Spring Cloud
Spring Cloud知识点
1、Spring Cloud
微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自的进程中运行,服务之间一般通过HTTP的RESTful API进行通信协作。
Spring Cloud是一系列框架的有序集合,它通过Spring Boot实现各个框架的自动配置,简化开发和维护。
Spring Cloud和Dubbo都是实现微服务的有效工具。Dubbo使用RPC通讯协议,Spring Cloud使用RESTful完成通信,Dubbo效率略高于Spring Cloud。
Spring中提供了RestTemplate模板类,可用于在java代码里访问RESTful服务。
2、Spring Cloud Netflix
2.1 Eureka服务治理
Eureka本质就是对各个微服务的ip和port进行统一维护,在进程服务调用的时候,可以根据ServiceId从注册中心获取对应的ip和port号。(当然了单看这个组件功能比较单一,但是很多组件集成在一起,它可以起一个桥梁的作用)
编写Eureka Server端:
1、导入spring-cloud-starter-netflix-eureka-server包;
2、在引导类上添加@EnableEurekaServer和@EnableDiscoveryClient注解;
3、配置application.yml
必须配置项:
spring:
application:
name: eureka-server
server:
port: 10086
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
fetch-registry: false
register-with-eureka: false
4、访问http://localhost:10086即可在UI界面中查看eureka注册中心状态
编写instance:
1、使用SpringBoot正常构建web项目即可;
2、在引导类上添加@EnableEurekaClient注解;
3、配置application.yml;
必须配置项:
spring:
application:
name: eureka-client1
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
fetch-registry: true
register-with-eureka: true
备注:
1)使用RestTemplate对象(需要配置Bean)进行服务调用,常用方法
<T> T getForObject(String url,Class<T> ResponseType)
2)使用DiscoveryClient对象(直接注入)从Eureka server端通过注册的服务名字获取 对应服务的Instances,是个List集合
List<ServiceInstance> getInstances(String serviceId)
通过ServiceInstance对象获取对应服务的IP和port
String getHost();
int getPort();
2.2 Ribbon负载均衡
Ribbon是Netflix提供的基于HTTP和TCP的客户端负载均衡。
负载均衡:指的是当为了实现服务的高可用,可以将相同的服务部署在不同的机器上,当客户端调用该服务的时候,通过负载均衡算法选择访问其中的一台机器。
客户端负载均衡:指的是在客户端实现负载均衡算法,然后选择访问那台机器。
服务端负载均衡:指的是在服务器端实现负载均衡方法,服务器接收到访问请求之后通过负载均衡算法决定访问那天一起。
Ribbo的负载均衡策略是:当一个服务1调用一个服务2的时候,服务1已经实现了负载均衡,请求发出时已经确定访问那台服务器。
Nigin的负载均衡策略是:当客户端访问服务端的时候,请求到达服务端之后,通过负载均衡算法再决定将请求转发到那台服务器。
Ribbon与Eureka结合,如果服务1部署在了多台服务器,然后都会注册到Eureka Server(ServiceId一般注册的名字相同),当服务2调用服务1的时候,通过服务1的ServiceId从Eureka Server中获取,会获得同一服务的多个Instance,此时采用Ribbon进行HTTP访问的时候,内部就封装了负载均衡的算法。
Spring Cloud对负载均衡进行了很好的封装,与2.1中一样,还是使用RestTempalte对象进行HTTP访问,只需要简单的配置之后,RestTempalte对象在进行HTTP访问的时候就会自动实现负载均衡。
步骤:
在2.1的基础上对Instance端进行改造:
1、spring-cloud-starter-netflix-eureka-ribbon包已经继承了ribbon不需要额外导包;
2、在配置RestTemplate的Bean时,加上@LoadBalanced注解;
3、RestTemplate进行服务调用的时候url格式
备注:url中的IP和port用需要调用的服务在Eureka Server中的注册ServiceId代替即可。
2.3 Feign声明式服务调用
Feign是对RestTempalte进行封装,基于接口生成动态代理对象,简化远程服务的调用。
备注:RestTemplate进行远程调用的时候,除了url不同外,调用方式完全相同,因此可以将url进行抽取出来,配置到接口中,通过接口动态生成代理对象,在使用的时候直接注入该对象,然后调用方法即可。
在2.1和2.2的基础上:
1)导入spring-cloud-starter-openfeign包;
2)在引导类上加上@EnableFeignClients;
3)编写一个接口;
备注:@FeignClient中的value值表示需要调用的服务在Eureka Server注册的ServiceId,
接口的方法除了没有方法体外,与被调用的服务相同即可。
@FeignClient(value = "eureka-client1")
public interface UserFeignClient {
@RequestMapping("/test/findById/{id}")
public User findById(@PathVariable(value = "id") int id);
}
2.4 Hystrix熔断器
Hystrix是Netflix开源的延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。
雪崩:在微服务架构中,一个服务失败导致整条链路的服务都失败的情况。
Hystrix的功能:
隔离:1)线程池隔离;2)信号量隔离;
降级:当服务1需要调用服务2的时候,存在两种情况:1)服务2不存在或网络不通,此时可以在服务1实现降级处理;2)可以访问到服务2,但服务2出错了,服务2可以进行降级处理。(备注:降级处理指的是,可以写一个方法,当原本的服务出现问题的时候,调用该方法)
熔断:当某个服务在某段时间内被访问导致多次出错的时候,该服务被禁用,然后再过一段事件后,该服务半开,可以被部分请求访问,如果继续出错,则再次被禁用(过一段时间又会半开),如果出现访问正常,则该服务全开,可供访问。
限流:指的是对访问进行限制;
在2.1、2.2、2.3、2.4的基础上:
1)导入spring-cloud-starter-netflix-hystrix包;
2)在引导类上加@EnableCircuitBreaker注解;
3)为Controller中的方法添加降级方法;
在需要配置降级方法的前面加上 @HystrixCommand注解,参数值指定降级之后调用的方法,该降级方法的编写与原方法方法名和方法体不同,其他相同。
@RestController
@RequestMapping("/client1")
public class UserController {
@Autowired
private UserFeignClient userFeignClient;
@RequestMapping("/findUserById/{id}")
@HystrixCommand(fallbackMethod = "findUserById_fallback")
public User findUserById(@PathVariable int id){
int i = 1/0;
User user = userFeignClient.findById(id);
return user;
}
public User findUserById_fallback(int id){
System.out.println("出错啦");
return new User();
}
}
3、Spring Cloud GateWay
Spring Cloud GateWay网关旨在为微服务架构提供一种简单而有效的同一API路由管理方式。类似于Spring MVC中的DispatcherServlet前端控制器,前端的请求全部经由网关,然后将请求路由到需要调用的服务,这样做的好处就是,前端只需要与网关交互,降低代码的耦合性,同时还可以在网关中实现一些与服务无关的统一性的操作,譬如认证、监控、缓存、负载均衡等。
实现步骤:
1)新建一个SpringBoot项目
导入spring-cloud-starter-gateway包;
2)配置application.yml
其中routes配置的是路由规则,如果访问的uri中资源路径(除访问协议、IP和poprt后的部分),符合predicates的规则,就会将请求转发到uri(配置中的uri)配置的路径+访问的uri(浏览器要访问的uri)中的资源路径。
譬如,如果浏览器访问http://localhost:80/client1/test/demo
该路径的资源理解符合Path=/client1/**的路由规则,然后路由到http://localhost:8001/client1/test/demo,将该url的资源再返回给前端。
server:
port: 80
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: gateway
uri: http://localhost:8001/
predicates:
- Path=/client1/**
上述的路由方式属于静态路由,直接将在application.yml中直接写的是路由uri固定地址,可以将spring cloud gateway与eureka结合起来,使网关根据服务在eureka server中的ServceId找到对应的服务。
步骤:
1)在上述的基本上进行改造即可;
2)导入eureka的包;
3)在引导类上加上@EnableEurekaClient,使网关作为一个服务注册到注册中心;
4)配置application.yml文件;
uri的配置改写为lb://ServiceId
server:
port: 80
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: gateway
uri: lb://eureka-client2
predicates:
- Path=/client1/**
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
fetch-registry: true
register-with-eureka: true
4、Spring Cloud Config
Spring Cloud Config解决了在分布式场景下多环境配置文件的管理和维护。
在分布式环境中,配置文件多且存在同一服务重复发布的情况,此时修改配置文件将会特别麻烦。Spring Cloud Config可以对配置文件进行统一管理,还可以在不重启服务的情况下,更新配置文件。
可以将配置文件放在git仓库,创建一个配置中心服务端并与该git仓库进行关联,可以通过该服务查看git仓库中的配置文件信息,然后需要使用配置文件的Spring Boot项目作为配置中心的客户端,在客户端中进行配置之后,客户端在启动程序的时候会从配置中心服务端获取相应的配置文件。
配置中心服务端的实现步骤:
1)在上述代码的基础上进行;
2)使用Spring Boot创建配置中心服务端;
3)导入spring-cloud-config-server包;
4)配置application.yml文件;
uri表示配置文件放置的git仓库路径;
lable表示仓库的分支;
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://gitee.com/wuyiping2020/config-server.git
label: master
server:
port: 8888
5)配置中心服务端测试
该配置中心可以作为一个服务访问其关联到的git库中的配置文件,路径如下:
其中master表示分支,config-server.yml表示该分之下的文件名
http://localhost:8888/master/config-server.yml
配置中心客户端的实现:
1)可以在3、Spring Cloud GateWay的基础上进行配置即可,也可重新创建一个Spring Boot项目;
2)导入spring-cloud-config包;
3)配置bootstrap.yml文件;
重启项目会出现如下的日志信息,表示从哪里取配置文件
在git仓库中存放了config-dev.yml文件
Fetching config from server at : http://localhost:8888
Located environment: name=config, profiles=[dev], label=master, version=2c030dd27d32dfd22122cada016fbecb8a4ab8aa, state=null
spring:
cloud:
config:
uri: http://localhost:8888
name: config
label: master
profile: dev
4)在Controller层中直接注入配置文件中写的键值对,然后再编写一个方法直接返回来测试;(config-dev.yml就写了一个键值对namefortest:zhangsan,访问之后直接在页面上显示zhangsan)
@RestController
@RequestMapping("/client1")
public class UserController {
@Value("${namefortest}")
private String name;
@RequestMapping("/name")
public String name(){
return name;
}
}
由上可知,使用Config配置中心,Spring Boot项目可以在启动的时候读取配置中心的配置文件,但是如果对配置中心的配置文件做了修改,如何将修改同步到项目中呢?
客户端配置文件的更新步骤:
1)git仓库中的配置文件修改之后,配置中心再访问的话就会是已更新的文件,但是该更新的配置文件并没有同步到配置中心客户端的项目中;
2)在配置中心的客户端引入spring-boot-actuator依赖;
3)在配置信息类上添加@RefreshScope
4)添加配置
management:
endpoints:
web:
exposure:
include: refresh
5) 使用curl工具发送POST请求即可更新配置中心客户端的配置文件
curl -X POST http://需要更新的服务的ip:port/actuator/refresh
6) 访问测试
Config配置中心与Eureka注册中心的结合:
1)同样的,如果配置中心服务器的地址发生变化,那么与该配置中心关联的所有客户端都需要更改ip地址,为了避免这种情况,可以将Config配置中心作为服务注册到Eureka Server;
2)在Config配置中心服务端,导入spring-cloud-starter-netflix-eureka-client包;
3)然后在引导类上加上@EnableEurekaClient;
4)改造配置中心bootstrap.yml文件
原本eureka的配置写在application.yml中,配置中心的配置写在bootstrap.yml中,(bootstrap.yml的优先级更高),如果还是分开写,只是把config.uri改成config.discovery进行配置的话,会出现找不到config-server的报错信息,如果将eureka的配置和config server的配置写在一起,就没有报错
server:
port: 8001
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
register-with-eureka: true
fetch-registry: true
spring:
application:
name: eureka-client2
cloud:
config:
name: config
label: master
profile: dev
discovery:
enabled: true
service-id: config-server
management:
endpoints:
web:
exposure:
include: refresh
5)更新git库中的配置文件,发送POST请求更新项目的配置信息,测试是否更新;
5、Spring Cloud Bus
Spring Cloud Bus消息总线是用轻量级的消息中间件,将分布式的节点连接起来,可以用于广播配置文件的更改或者服务的监控管理。关键的思想是,消息总线可以为微服务做监控,也可以实现应用程序之间相互通信。
Spring Cloud Bus可选的消息中间件可以是RabbitMQ和 Kafka。
Spring Cloud Bus是与Spring Cloud Config集成使用的,需要在配置中心引入actuator的坐标,其功能是对配置中心进行监控,actuator会检测到配置文件的相关变化并暴露出refresh的埋点,当发送POST到配置中心的RabbitMQ之后,它会广播道其他的节点。
实现步骤:
1)安装并启动RabbitMQ服务;
1)在4、Spring Cloud Config的基础上进行改造;
2)配置中心和各个微服务引入actuator和bus-amqp坐标;
3)配置application.yml文件
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
4)发送curl -X POST http://localhost:8888/actruator/bus-refresh
该url的ip和port是配置中心的ip和地址。
6、Spring Cloud Stream消息驱动
Spring Cloud Stream是一个构建消息驱动微服务应用的框架。
Stream解决了开发人员无感知的使用消息中间件的问题,因为Stream对消息中间件实现了进一步的封装,对外暴露了与消息中间件交互的统一API。如果在开发过程中,消息中间件发生了改变,只需要简单的配置即可,代码并不需要修改。(类似JAVA为操作数据库提供了JDBC的统一接口,各个数据库公司提供具体实现,在编程过程中只需要面向接口即可)。
Spring Cloud Stream目前支持两种消息中间件RabbitMQ和Kafka。
Spring Cloud Stream构建的应用程序与消息中间件之间是通过绑定器Binder相关联的。绑定器对于应用程序而言可以起到隔离作用,屏蔽应用程序直接与消息中间件的直接交互,只需要面向中间件即可。
binding指的是将应用程序和Spring Cloud Stream的Binder绑定在一起。
output指的是发送消息的Channel,内置Source接口;
input指的是接收消息的Channel,内置Sink接口;
消费生产者:
1)安装并启动RabbitMQ服务;
2)创建Spring Boot项目,引入spring-cloud-starter-stream-rabbit;
3)为消息生产者编写配置文件,定义binder和bindings;
spring:
cloud:
stream:
bindings:
binders:
wyp_binder: #定义绑定器
type: rabbit #定义绑定器的类型
environment: #定义绑定器的环境信息
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
bindings:
output: #channel名称
binder: wyp_binder #指定使用哪一个绑定器
destination: wyp_exchange #消息目的地
server:
port: 8000
4)定义消息发送业务类,添加@EnableBinding(Source.class),注入MessageChannel output对象,完成下消息发送;
可以在Controller层直接注入该对象调用相关方法实现在前端访问发送消息的目的。
@Component
@EnableBinding(Source.class)
public class MessageProducer {
@Autowired
private MessageChannel output;
public void sendMsg(){
String message = "hello stream";
output.send(MessageBuilder.withPayload(message).build());
System.out.println("消息发送成功了。");
}
}
消息消费者:
1)创建Spring Boot项目,引入spring-cloud-starter-stream-rabbit;
2)编写配置,定义binder和bindings;
spring:
cloud:
stream:
bindings:
binders:
wyp_binder: #定义绑定器
type: rabbit #定义绑定器的类型
environment: #定义绑定器的环境信息
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
bindings:
input: #channel名称
binder: wyp_binder #指定使用哪一个绑定器
destination: wyp_exchange #消息目的地
server:
port: 9000
3)定义消息接收业务类,添加@EnableBinding(Sink.class),使用 @StreamListener(Sink.INPUT)完成消息接收。
@Component
@EnableBinding(Sink.class)
public class MessageListener {
@StreamListener(Sink.INPUT)
public void receiveMsg(Message message){
System.out.println(message.getPayload());
}
}
7、Spring Cloud Sleuth和Zipkin
Spring Cloud Sleuth可以在整个分布式系统中跟踪一个用户请求的过程,捕获这些跟踪数据,就能构建微服务的整个调用链的视图,是调试和监控微服务的关键工具。
功能:耗时分析;可视化错误;链路优化;
Zipkin是Twitter的一个开源项目,致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展示。
使用步骤:(Seuth收集数据,Zipkin展示数据)
1)安装启动zipkin,java -jar zipkin.jar;
2)访问zipkin web界面,http://localhost:9411;
3)在各个微服务中分别引入slueth和zipkin(其实zipkin包含slueth)依赖;
4)配置;
spring:
zipkin:
base-url: http://localhost:9411/
sleuth:
sampler:
probability: 1 #数据采集率 默认0.1 百分之十(采集越多,对性能损耗越大)

浙公网安备 33010602011771号