1. 新建父项目
- 在idea新建父项目 springcloud
- 导入相应的spring cloud 依赖
具体可参考 https://gitee.com/fangping94/springcloud/blob/master/springcloud/pom.xml
2.新建springcloud-api 项目
该项目主要存储一些对外访问的实体类
- 新建数据库db01,建数据库表dept
- 新建实体类
表数据
insert into dept (dname, db_source) values ('开发部',DATABASE());
insert into dept (dname, db_source) values ('人事部',DATABASE());
insert into dept (dname, db_source) values ('财务部',DATABASE());
insert into dept (dname, db_source) values ('市场部',DATABASE());
insert into dept (dname, db_source) values ('运维部',DATABASE());
3.新建服务端
新建服务提供者
- 导入依赖
- 配置application.yml
- 配置主启动类
3.1 这边依赖可以参考配置
3.2 配置 application.yml
主要是配置数据库连接,mybatis等
3.3 配置主启动类,配置mapper.xml,dao,controller
对应的文件参考springcloud-provider-dept-8001 里面的mapper.xml,dao和controller等,controller里面提供了对数据库数据的查找和添加操作。
3.4 测试,拿根据id来查找举例
4.新建消费者
新建maven 项目,项目名称为 springcloud-consumer-dept-80
- 导入相关依赖
- 配置application.yml 配置个端口就好,端口为80
- 消费者端调用服务端提供的服务
- 配置主启动类 参考gitee
4.1) 导入相关依赖参考 springcloud-consumer-dept-80 的项目里面
4.2) 配置 application.yml
配置端口号
server:
port: 80
4.3 )消费端需要通过http去调用远程的服务。通过 org.springframework.web.client.RestTemplate 这个类去调用
启动服务端,启动消费端, 测试。
5.新建eureka
eureka 是提供了和zookeeper类似的功能,也就是服务注册和发现的功能。
新建一个eureka服务端,名称为springcloud-eureka-7001 。
- 导入相关依赖
- 配置application.yml
- 配置主启动类
5.1 )导入依赖,只需要导入
5.2) 配置application.yml
5.3) 配置主启动类
5.4) 启动eureka 服务
5.5) 将服务注册进来
1)在8001服务注册到eureka 中,需要在8001的服务里配置相关依赖,这边导入的依赖时spring-cloud-starter-eureka,eureka服务中导入的是spring-cloud-starter-eureka-server
2)同时需要在application.yml 配置
3)在主配置类里配置
4)测试
先开启7001 eureka服务,然后开启8001 服务,会将8001这个服务注册到7001中
6.配置eureka集群
同样建立和7001端口号一样的eureka服务,配置和springcloud-eureka-7001服务一样,建立springcloud-eureka-7004和springcloud-eureka-7005这两个服务。
值得注意的是,mac/linux上需要通过sudo vim /etc/hosts 添加配置
- 注意在配置集群的时候,以springcloud-eureka-7001为例,需要将application.yml中的配置改为
- register-with-eureka改为true, fetch-register也为true,单实例的eureka为false
- hostname 改为 eureka7001.com
- defaultZone 值为 http://eureka7004.com:7004/eureka/,http://eureka7005.com:7005/eureka/
测试得到如下结果
7.Ribbon 负载均衡
负载均衡的作用是将用户请求平均分配到多个服务器上,从而达到高可用。
负载均衡(LoadBalance 简称LB) 分为集中式LB,进程LB。
Ribbon是进程LB,在消费端启用,此处以 springcloud-consumer-dept-80 端口为例,Ngnix是集中式LB
配置负载均衡
- 引入依赖
- 配置文件修改
- controller中根据服务名访问
- resttemplate 加@LoadBalance
7.1) 引入依赖
7.2) 配置文件修改
7.3) controller 中修改根据服务名访问
7.4) restTemplate加LoadBalance注解
服务提供者集群模式
新建2个和springcloud-provider-dept-8001一样的服务,只是端口号不一样,并且每个服务访问的数据库不一样,服务名分别为springcloud-provider-dept-8002,springcloud-provider-dept-8003,数据库分别为db02,db03
db02数据如下:
db03数据如下:
以springcloud-provider-dept-8002为例,需要修改的地方
- 引入和springcloud-provider-dept-8001一样的pom依赖
- application.xml 修改,需要修改的地方是port和和连接数据库的名字
- 主启动类名字修改下
- 其他的结构和8001服务一样
具体如下所示:
测试:启动springcloud-provider-dept-8001,springcloud-provider-dept-8002,springcloud-provider-dept-8003
提供服务,并让其注册到springcloud-eureka-7001,springcloud-eureka-7004,springcloud-eureka-7005集群,启动
springcloud-consumer-dept-80来消费服务。
如下图所示:
可以看到在SPRINGCLOUD-PROVIDER-DEPT 这个集群下有3个服务提供者。
启动80端口来消费服务。第一次访问
第二次访问:
第三次访问:
可以看到是会从不同的服务提供者哪里获取服务。
8. Ribbon负载均衡算法
负载均衡算法是可以自定义的,自己实现的负载均衡算法都要实现Irule这个接口,如下所示:
默认用的是RoundRobin负载算法,如果想用随机的如下图配置即可
如果想自定义负载均衡算法,可以参考RandomRule,继承AbstractLoadBalancerRule,重写cho0se方法,如下所示:
同时,如果想将Ribbon负载均衡自定义,可以在和主程序类的上一层级springcloud新建一个同级的package liam_rule
LiamRule为:
主程序配置
9.Feign远程过程调用
Ribbon和Feign 的主要区别是,ribbon一般和resttemplate一起使用,显示的通过http进行调用,而Feign一般是写好一个接口,有点类似dubbo里面的@Reference注解,引用一个api就可以实现远程过程调用。
copy一个springcloud-consumer-dept-80服务,服务名称为springcloud-consumer-dept-feign,该服务中需要修改的地方有
- 在pom.xml引入feign的依赖
- 主程序类
- 修改请求接口类(主要是这里)
- 在springcloud-api中添加一个feignclient
9.1) springcloud-consumer-dept-feign引入feign依赖
9.2) springcloud-consumer-dept-feign 主程序类名称的修改
9.3) 请求接口类修改
9.4) 加入一个DeptServiceClient 这个类,这个类在springcloud-api里面编写
在用ribbon+restTemplate时,会明显看到http请求的标识,而Feign更比较符合面向接口编程。
10.Hystrix:服务熔断和降级
服务熔断:对雪崩效应的一种微服务链路保护机制,例如A---->B----->C----->D这种服务调用,如果C发生不可用或者响应时间太长,可以熔断该节点微服务的调用,快速返回错误的响应。默认5秒内20次调用失败触发熔断机制
熔断一般是在服务提供端,新建一个和 springcloud-provider-dept-8001 一样的项目,名称为 springcloud-provider-dept-8001-hystrix,要修改的地方有
- 引入hystrix的依赖
- 修改主程序的名字,开启hystrix
- 测试
10.1) 引入依赖
10.2) 修改主程序
10.3) 修改controller
10.4) 测试
访问 http://localhost:8001/dept/get/1, 得到的结果为
访问 http://localhost:8001/dept/get/10,得到的结果为
11. 服务降级
假设有A,B,C 3个服务,如果A,B服务的访问很高,而C在同一时刻访问流量很低,我们可以考虑将C下线掉,让出更多的资源,给A,B服务,当然C下线掉之后,如果有请求到C那就会返回错误,服务降级可以使得C返回一个无意义的结果,不会报错。
- 首先在 springcloud-api 中新建 DeptServiceClientFallbackFactory 类
- 同级目录下修改DeptServiceClient 加入fallbackFactory
- 在springcloud-consumer-dept-feign 的application.xml开启hystrix
11.1) 新建 DeptServiceClientFallbackFactory 类
11.2) 修改 DeptServiceClient 加入fallbackFactory
11.3) application.xml 开启 hystrix
熔断和降级有什么区别?
熔断是在服务端处理的,加入@HystrixCommand命令,而降级是在客户端加入的,为的是将访问少的服务停掉用于支持访问多的服务。
12.hystrix dashboard 监控器
新建一个新的module 叫做 springcloud-consumer-dept-hystrix-9001,这个服务专门用来监控数据信息,配置步骤如下:
- 引入依赖
- 配置主启动类
- 访问测试
- 在 springcloud-provider-dept-8001-hystrix 注册 ServletRegistrationBean
12.1) 依赖和 springcloud-consumer-dept-80 的pom依赖一样,但会另加 hystrix 的支持,依赖支持如下:
12.2 ) 配置主启动类
12.3 ) 访问http://localhost:9001/hystrix
12.4) 在 springcloud-provider-dept-8001-hystrix 注册 ServletRegistrationBean
访问 http://localhost:8001/actuator/hystrix.stream 可以看到数据
在 http://localhost:9001/hystrix 页面添加对 http://localhost:8001/actuator/hystrix.stream 的监控
出现如下界面
可以访问http://localhost:8001 这个服务下的接口:例如http://localhost:8001/dept/get/1,可以看到监控变化
图中各个指标如下:
13. zuul路由网关
Zuul提供了动态路由、监控、弹性负载和安全功能,也就是说对于我们要访问某个服务的接口,例如http://localhost:8001/dept/get/1这个接口,我们是可以看的出来真实的服务地址和端口号的,zuul可以替换真实的地址,用另一个地址来访问即可,例如http://www.liam.com:9527/springcloud-provider-dept/dept/get/1 来访问,springcloud-provider-dept是微服务的名字。
要准备的工作:
- 修改hosts
- 新建一个module springcloud-zuul, 引入依赖
- application.yml配置
- 编写主程序, 开启zuul代理
13.1) hosts修改 添加127.0.0.1 www.liam.com
13.2) 新建module,引入依赖,依赖和 springcloud-consumer-dept-hystrix-9001一样,另外新增依赖
13.3) application.yml
mydept.serviceId 这个值mydept代表key,serviceId值是 springcloud-provider-dept是服务的名字
mydept.path 这个值mydept代表key,path值是 /mydept/** 用来代替 springcloud-provider-dept 这个名字来访问 举个例子本来要访问:http://www.liam.com:9527/springcloud-provider-dept/dept/get/1,这样微服务的名字会被暴露,因此可以通过http://www.liam.com:9527/mydept/dept/get/1 来代替。
ignored-services这个值表示忽略服务,也就是说只能通过http://www.liam.com:9527/mydept/dept/get/1来访问 不能通过http://www.liam.com:9527/springcloud-provider-dept/dept/get/1访问。如图:
如果想对所有的原来的微服务 名禁用的话,其值为"*"即可。
13.4)编写主程序
13.5) 测试
http://www.liam.com:9527/springcloud-provider-dept/dept/get/1 访问失败
http://www.liam.com:9527/mydept/dept/get/1 访问成功。
14. spring cloud config
在gitee上新建一个仓库,仓库包含一个application.yml的配置,拉取到本地如图所示:
14.1 )新建一个项目,该项目属于服务端,名称为springcloud-config-server-3344,该服务负责向gitee拉取相关配置信息。
- 引入依赖
- 新建配置类
- 编写主程序,开启配置服务
1)引入依赖
2)新建配置类
3)编写主程序,开启配置服务
4) 测试,查看服务端是否能正确拉取到gitee上的配置信息
在springcloud-config项目中存在一个application.yml 文件,如下所示:
该配置文件存在在gitee上,可以通过刚新建的3344这个服务去访问里面的application.yml文件,请求接口和结果如下:
请求接口的规范如下:
链接地址:https://www.springcloud.cc/spring-cloud-config.html
14.2) 建立客户端,客户端负责向服务端发送请求,然后服务端负责向gitee拉取相关配置信息
流程步骤
- 我们需要在springcloud-config里面新建一个客户端自身的配置类
- 新建客户端,引入依赖
- yml文件编写
- 主程序编写
- controller 编写,查看客户端是否能通过服务端找到gitee上的配置
- 测试
1)在gitee上新建的一个仓库spingcloud-config文件结构如下所示:
其中config-client.yml 参考以下链接https://gitee.com/fangping94/springcloud-config/blob/master/config-client.yml
2)新建一个module,名称叫做 springcloud-config-client-3355,注意端口号不是3355,我们可以从gitee上获取,同时可以引入依赖
3 ) yml 文件编写
注意这里的yml文件只是配置从gitee上哪个文件读取,注意这里是bootstrap.yml配置,和 application.yml 的区别是 bootstrap.yml是系统级别的配置,而 application.yml 是用户级别的配置。
以下配置是说明客户端要从服务端3344这个服务去获取配置信息,而3344这个服务去gitee上获取
之前在在服务端测试是否能访问成功时可以通过如下方式进行访问
例如访问gitee上的application.yml的配置信息时,我们启动3344的服务器时,可以通过http://localhost:3344/master/application-dev.yml来访问,上面的配置信息也是差不多的意思。
4)主程序编写,无需开启@Enable***
5)controller 中负责对gitee上配置的数据进行展示
6)测试
启动7001 eureka,3344的springcloud-config-server服务器,启动3355的项目,注意3355这个项目中的端口号是从gitee上获取的。访问http://localhost:8202/config结果如下
14.3) spring config 用来配置eureka和dept-8001
spring config 用来配置eureka-7001和 dept-8001,也就是将eureka和dept-8001的配置信息放入到gitee上。
在springcloud-config 项目里配置eureka-7001一样的配置,配置名称叫做config-eureka.yml 配置参考链接https://gitee.com/fangping94/springcloud-config/blob/master/config-eureka.yml config-dept.yml 配置参考链接https://gitee.com/fangping94/springcloud-config/blob/master/config-dept.yml
- 新建 springcloud-config-eureka-7001 module
-
新建springcloud-config-dept-8001 module
1) 新建springcloud-config-eureka-7001
- 引入依赖,和springcloud-eureka-7001的依赖一样,只是需要引入
- 配置bootstrap.yml
- 配置启动类
- 测试
测试先启动3344的springcloud-config服务,后启动eureka服务,看到7001服务启动了说明从gitee上得到了配置信息
2)新建springcloud-config-dept-8001 这个服务
- 导入依赖,基本上和springcloud-provider-dept-8001 依赖一致,需额外导入spring-cloud-starter-config 依赖
- 配置bootstrap.yml
- 配置主启动类
主启动类不用改。因为springcloud config client 无需开启@Enable***
测试访问:
可以看到查到的数据是从数据源db02得到的,因为在bootstrap.yml中的profile为test。更改profile 值为dev, 测试得到的值为:
15. springcloud 总结
这篇文章在最开始先新建了个服务提供端,然后新建了个消费端,消费者可以通过http的方式来调用远程的服务,用到的就是RestTemplate,这样远程调用就是得指定相应的远程服务器的地址,如下所示:
如果以后服务多了,那么对于服务提供者是不好管理的,因此需要一个和zookeeper类似的注册中心,那就是Eureka,Eureka是去中心话的,也就是提供了AP ( 可用性和分区容错性 ),因此我们新建了Eureka-7001的注册中心,这样的话可以通过http://localhost/serviceName 去访问服务,通过ribbon + resttemplate去实现该功能,与此同时可以开启负载均衡,也就是在获得RestTemplate 的bean 时使用@LoadBalance来开启负载均衡,当然也可以自定义负载均衡算法,可以通过注入一个Irule的实例即可实现,为了实现Eureka的高可用,配置了Eureka的集群模式。
由于Ribbon+resttemplate 不符合面向接口编程的规范,Feign出现了,该组件提供了很好的面向接口编程的实现方式,只需编写一个api,在api上开启@FeignClient,然后其他的服务就可以将其注入进来,去调用远程的服务。
服务在运行的时候不可避免的会出现崩溃,特别是在存在多个服务链路的情况下,因此出现了服务熔断和服务降级,服务熔断是在服务端开启的,在方法发生异常或者调用失败时,可以通过@HystrixCommand方法来回调写好的方法来返回一个结果;服务降级是在消费端,也就是在api层开启的,在application.yml 配置hystrix开启,写一个类来实现FallbackFactory 这个接口,后在FeignClient配置一下这个实现了FallbackFactory这个接口的类。Hystrix还实现对流量的监控,新建一个流量监控的服务,然后配置其对流量的监控,会有一个直观的展示。
在很多时候,需要对服务的真实访问地址做一个屏蔽或者说替换,因此,需要用到zuul这个组件,就是用来干这个事的,例如对于http://localhost/微服务名/方法,可以通过 http://zuul地址/微服务名称/方法 来代替,这里的微服务名称可以通过配置来让其他的值代替。
spring cloud config 是可以将配置进行统一管理的,也就是application.yml这种可以放到gitee上,spring cloud config 可以通过一个服务器统一对gitee进行访问,然后客户端只需要从服务端取配置信息即可。
文章评论