[JavaEE] 搭建SpringCloud环境 进入微服务时代
最近玩了一下SpringCloud
经过一番周折之后终于找到捷径搭建出一套比较完整的项目 触类旁通的你肯定也有所耳闻 这是一套完整的微服务框架 通过它可以快速集成一整套企业所需的微服务环境 用上最先进的后台技术
在这里要特别感谢余胜军老师的视频 @蚂蚁课堂
SpringCloud视频教程地址:
http://www.mayikt.com/front/couinfo/91/0
一.什么是微服务
请自行百度
下面是我总结出来的
就是把一整个后台项目拆分成多个模块 每一个模块称作一个服务 每个服务都可以独立运行 这样的好处是其中有一个服务挂掉后 另外的服务并不受影响
二.环境搭建
首先需要准备一个好用的IDE如 IDEA
Eclipse
Netbeans
文章中使用IDEA
1.首先新建一个SpringBoot项目




然后next项目建好了 - -
好的 到这里我们的工程已经创建完成了 接下来我们来了解一个比较重要的东西pom.xml
这个东西 它就是maven
的配置文件, 而maven
是项目的包管理工具 我们在上文中勾选的一些模块 其实是直接配置到pom.xml
中去了 我们打开来看一下

我们刚刚勾选的模块都在这里面 在这个清单里面想要移除某个组件 只需要注释掉相应的代码块即可 这里就不多加赘述了.
之后我们在入口文件上添加注解

然后运行项目试试吧

发现运行项目之后是图上这个样子 那你可能会有疑问 这个东西是做什么用的呢
这里解释一下 首先我们做的是微服务 在上面已经说过了 就是把一个大应用 拆分成若干的功能模块 每一个模块独立运行互不依赖 那么这些模块之间如何相互调用呢? 注册中心存在的意义就是记录每一个功能模块
名称
和ip地址
让子模块可以方便的进行相互远程调用
好 我们已经知道注册中心的作用了 那我们要如何使用呢? 不要着急 在使用之前还需要进行一些配置
首先在工程中找到application.properties
文件

然后把下面的配置复制黏贴到上面
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8081/eureka
#是否需要将自己注册到注册中心(注册中心集群需要设置为true)
register-with-eureka: false
#是否需要搜索服务信息 因为自己是注册中心所以为false
fetch-registry: false
配置完之后重新运行项目 访问下面地址
http://localhost:8081
网页可以正常运行后 我们的注册中心就配置完毕了
光有注册中心是没有用的 连服务都没有 根本写不了接口 所以接下来我们就创建两个服务
工程文件夹右键new
-> Module



接下来勾选一些功能模块



新建完之后是这个样子 同理配置service-b

之后我们配置服务的入口文件

然后配置一下application.yml
首先是service-a
server:
#服务端口号
port: 8082
spring:
application:
#服务名称 - 服务之间使用名称进行通讯
name: service-objcat-a
eureka:
client:
service-url:
#填写注册中心服务器地址
defaultZone: http://localhost:8081/eureka
#是否需要将自己注册到注册中心
register-with-eureka: true
#是否需要搜索服务信息
fetch-registry: true
之后是service-b
server:
#服务端口号
port: 8083
spring:
application:
#服务名称 - 服务之间使用名称进行通讯
name: service-objcat-b
eureka:
client:
service-url:
#填写注册中心服务器地址
defaultZone: http://localhost:8081/eureka
#是否需要将自己注册到注册中心
register-with-eureka: true
#是否需要搜索服务信息
fetch-registry: true
之后我们来运行一下服务吧



打开注册管理页面看一下 两个服务都注册上去了 大功告成!
那我们接下来开始写个简单的接口

@RestController
public class TestController {
@RequestMapping("/hello")
public String hello() {
return "hello world";
}
}
然后重新运行服务a
访问下面地址

浏览器上出现hello world
说明成功了
有人会问了 到这里并没有使用到任何注册中心的功能啊?
不要着急 接下来我们就是用一用注册中心
我们现在有一个需求 使用服务b调用服务a的接口
这时我们就需要用到eurka(注册中心)
和feign
客户端了
首先我们在service-b中创建interface


@FeignClient("SERVICE-OBJCAT-A")
public interface ServiceAFeignClient {
@RequestMapping("/hello")
public String hello();
}
之后我们来写接口 在服务b中添加个控制器

@RestController
public class TestController {
@Autowired
private ServerAFeignClient serverAFeignClient;
@RequestMapping("/call")
public String call() {
String result = serverAFeignClient.hello();
return "b to a 访问结果 ----- " + result;
}
}
之后我们发现报错了 不要慌张设置一下即可

最后在应用入口加上注解 就能实现服务之间的调用了

重新运行服务b 在网站上访问试试吧

到这里服务之间的相互访问也可以完成了 到这里springcloud最基本的环境搭建就完成了 快写几个微服务玩玩吧
内容扩展
我们来看一个神奇的现象 我把service-a接口中写一个延时函数 我们看一下效果

之后我们重新运行service-a
我们会发现报如下错误

意思是读取超时了 这是为什么呢
原因就是feign的默认请求超时时间是1秒 而我们延时1.5秒后返回了数据 所以这个请求失败了 那么我们要如何解决这个问题呢?
很简单 我们在配置文件中配置feign的超时时间即可
server:
#服务端口号
port: 8083
spring:
application:
#服务名称 - 服务之间使用名称进行通讯
name: service-objcat-b
eureka:
client:
service-url:
#填写注册中心服务器地址
defaultZone: http://localhost:8081/eureka
#是否需要将自己注册到注册中心
register-with-eureka: true
#是否需要搜索服务信息
fetch-registry: true
ribbon:
#建立连接超时时间
ReadTimeout: 5000
#读取资源超时间
ConnectTimeout: 5000
关键是下面这三行
ribbon:
#建立连接超时时间
ReadTimeout: 5000
#读取资源超时间
ConnectTimeout: 5000
这里说一下 ribbon
如果你是搞IT的 那么你一定听说过一个叫负载均衡
的东西 而负载均衡呢 又分为两种
1.本地负载均衡 一般使用ribbon
2.服务器端负载均衡 一般使用nginx
顾名思义所谓负载均衡
就是让用户访问可以平均到集群服务上去 避免单个服务访问量过大而增加服务器负担
所谓集群 就是单个服务在不同服务器上运行(相同服务器也可 但同一个服务器端口一定不同) 实现同样服务的效果
说到这里 你可能还是不太懂 没关系 先看下面的例子 我们来重现一下ribbon
的负载均衡功能
我们现在就在本地开启两个service-a
首先修改一下代码 让服务打印出当前端口号

对服务a做了上图中的修改
1.获取服务器端口号
2.拼接端口号返回给客户端
3.注释掉了延时函数提高效率
好 那我们来启动两个service-a 这个要进行设置一下 因为idea默认情况下是单例运行的 我们先要给服务改成不是单例的状态 这样就能跑起来两个同样名称但端口不同的服务了


到了这一步 我们来跑起来两个service-a吧


运行之后我们会发现有两个a服务 一个是8082 一个是8092

这个就成为集群 同一个服务开启了两个端口 独立运行 我们打开eureka看一下 服务都顺利运行了
有两个a服务 一个b服务

接口下来我们用b服务来访问以下a服务 调用我们以前就写好的方法 call

访问的同一个地址 但是端口会在8082和8092之间来回切换 这就是所谓的本地负载均衡 那么这个机制是怎么实现的呢 其实很简单 就是轮询机制 计算公式就是 总请求次数 % 服务器总数
取模后就调用相对应索引的服务 就可以实现本地均衡负载了 这就是ribbon的基本原理
三.功能模块集成
在第二章我已经把基本环境搭建完成了 但是那只是最基本的环境还缺少诸多功能 如服务降级
服务熔断
服务隔离
网关
等
1.网关
[JavaEE] SpringCloud集成Zuul网关
https://www.jianshu.com/p/6ef9ca1efa4b
2.服务保护
[JavaEE] SpringCloud集成Hystrix服务保护
https://www.jianshu.com/p/cce702d44b7d
3.负载均衡
[JavaEE] 狒狒都能懂的Nginx教程 for Mac
https://www.jianshu.com/p/c21606bb4044
4.分布式配置中心
[JavaEE] SpringCloud集成Apollo分布式配置中心
https://www.jianshu.com/p/5606483c7fbf
四.打包
[JavaEE] SpringCloud项目打包
https://www.jianshu.com/p/935868c9141e
五.Demo
https://github.com/objcat/test-spring-cloud-demo
finall enjoy it.
by objcat 2018.11.14
更新日志:
2018年11月20日14:24:58
1.新增负载均衡原理
2.新增网关配置教程