微服务SpringCloud新手入门(三)
前言
在上次的文章中我们认识了SpringCloud的Feign组件,它的作用是使用Rest API实现服务的远程调用。我们知道消费者Consumer是通过调用注册在Eureka上的提供者Provider来实现功能的,那么当Provider由于网络故障或者其他原因与Eureka失去联系后,Consumer应该如何应对呢?
Hystrix
作用:断路器,保护系统,控制故障范围。
简介:为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
What is Hystrix ?
在分布式系统中,服务与服务之间依赖错综复杂,一种不可避免的情况就是某些服务将会出现失败。Hystrix是一个库,它提供了服务与服务之间的容错功能,主要体现在延迟容错和容错,从而做到控制分布式系统中的联动故障。Hystrix通过隔离服务的访问点,阻止联动故障,并提供故障的解决方案,从而提高了这个分布式系统的弹性。
Why Hystrix ?
复杂分布式体系结构中的应用程序具有许多依赖关系,每个依赖关系在某些时候都将不可避免地失败。即使所有依赖项都表现良好,如果您没有为整个系统设计弹性,那么即使0.01%停机时间对数十种服务中的每项服务的总体影响也相当于每月停机时间可能达到数小时。这个时长对于分布式微服务架构体系来说无疑是非常可怕的。而Hystrix就是用来解决这类问题的。
Hystrix功能:
1.通过第三方客户端库访问(通常通过网络)依赖关系,以防止和控制延迟和故障。
2.在复杂的分布式系统中停止级联故障。
3.快速失败并迅速恢复。
4.在可能的情况下,后退并优雅地降级。
5.实现实时监控,警报和操作控制。
How to use Hystrix ?
示例springcloud版本为Hoxton.SR3,springboot版本为2.2.5
容错机制:
在上次示例的基础上:
1.修改consumer-demo
由于feign组件的依赖已经集成hystrix容错,所以此处无需额外添加依赖
修改consumer-demo的applicaltion.yml文件如下:
server:
port: 8089
spring:
application:
name:consumer-demo
eureka:
client:
service-url:
defaultZone: http://admin:123456@localhost:8761/eureka/
feign:
hystrix:
enabled: true
增加UserFeignClientFallback容错类:
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public boolean login(User user) {
return false;
}
}
修改UserFeignClient接口:
@FeignClient(name="provider-demo",fallback=UserFeignClientFallback.class)
public interface UserFeignClient {
@RequestMapping(value="/login",method = RequestMethod.POST)
public boolean login(@RequestBody User user);
}
依次启动eureka-server,provider-demo,consumer-demo,使用Restlet Client测试http://localhost:8089/userlogin:
服务调用成功。
此时关闭provider-demo项目(模拟因网络故障与eureka失去联系),再次使用Restlet Client测试http://localhost:8089/userlogin:
此时可以看到虽然provider-demo已经与eureka-server失去联系,但是此时的响应状态依然为正常的200。这就是因为hystrix的容错机制,由于UserFeignClient接口无法实现功能,转而执行UserFeignClientFallback类里的方法返回false,所以此处响应为“fail,admin”。这样就避免了异常与级联故障的发生。
服务监控
除了服务容错之外,hystrix还提供了近乎实时的监控,他会会实时的,累加的记录所有关于HystrixCommand的执行信息,包括执行了每秒执行了多少请求,多少成功,多少失败等等。
1.修改consumer-demo
添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
添加以下配置类:
@Configuration
public class HystrixConfiguration {
@Bean
public ServletRegistrationBean<HystrixMetricsStreamServlet> getServlet(){
HystrixMetricsStreamServlet hystrixMetricsStreamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean<HystrixMetricsStreamServlet> servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(hystrixMetricsStreamServlet);
servletRegistrationBean.addUrlMappings("/hystrix.stream");
servletRegistrationBean.setName("HystrixMetricsStreamServlet");
return servletRegistrationBean;
}
}
在启动类上添加@EnableCircuitBreaker注解
2.创建hystrix-dashboard项目
创建时可勾选Hystrix Dashboard
添加以下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
application.yml配置如下:
server:
port: 8083
在启动类上加上@EnableHystrixDashboard注解
依次启动eureka-server,provider-demo,consumer-demo,hystrix-dashboard。
先使用Restlet Client正确调用一次consumer-demo产生监控数据,然后访问http://localhost:8083/hystrix:
在url框中输入http://localhost:8089/hystrix.stream:
说明:
实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,它的健康程度从 绿色 > 黄色 > 橙色 > 红色 递减;该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大实心圆就越大,所以通过该实心圆的展示,就可以在大量实例中快速的发现故障实例和高压力实例。
使用turbine监控多个微服务:
1.修改provider-demo
增加login2方法:
@RestController
public class UserService {
private Logger logger = LoggerFactory.getLogger(UserService.class);
@RequestMapping(value="/login",method = RequestMethod.POST)
public boolean login(@RequestBody User user) throws Exception{
return "admin".equals(user.getUsername())&&"123456".equals(user.getPassword());
}
@RequestMapping(value="/login2",method = RequestMethod.POST)
public boolean login2(@RequestBody User user) throws Exception{
return "admin".equals(user.getUsername())&&"123456".equals(user.getPassword());
}
}
2.复制consumer-demo项目
复制一份consumer-demo项目命名为consumer-demo2
修改consumer-demo2的application.yml为:
server:
port: 8085
spring:
application:
name:consumer-demo2
eureka:
client:
service-url:
defaultZone: http://admin:123456@localhost:8761/eureka/
feign:
hystrix:
enabled: true
修改consumer-demo2中的UserFeignClient接口:
@FeignClient(name="provider-demo",fallback=UserFeignClientFallback.class)
public interface UserFeignClient {
@RequestMapping(value="/login2",method = RequestMethod.POST)
public boolean login2(@RequestBody User user);
}
同时还需要修改UserFeignClientFallback与LoginController中的方法名为login2。
3.创建turbine-server项目
创建时可勾选一下工具:
添加依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
application.yml配置如下:
server:
port: 8084
spring:
application:
name: turbine-server
eureka:
client:
service-url:
defaultZone: http://admin:123456@localhost:8761/eureka/
turbine:
instanceUrlSuffix: /hystrix.stream
app-config: consumer-demo,consumer-demo2
cluster-name-expression: "'default'"
combine-host-port: true
在启动类上加上@EnableTurbine注解
依次启动eureka-server,provider-demo,consumer-demo,consumer-demo2,turbine-server,hystrix-dashboard。
使用Restlet Client分别调用consumer-demo与consumer-demo2产生监控数据。
访问http://localhost:8083/hystrix,在url框中输入:http://localhost/8084/turbine.stream。效果如下:
(SpringCloud其他组件将在下次更新 (ง •̀_•́)ง,如有错误,希望大家多多指正(•‾̑⌣‾̑•)✧˖°)