一.简介
微服务架构中如果服务提供者不可用将会导致服务消费者也不可用,这种基础服务故障导致级联故障称为雪崩效应
。通常微服务架构系统都有多个服务层,雪崩效应更显著。
容错处理机制:
1.网络请求设置超时:通常一次远程调用对应一个线程,长时间得不到响应将导致系统资源长时间得不到释放
2.使用断路器模式:正常情况下断路器处于关闭状态,可以正常请求服务;当失败率到一定阈值时断路器会打开,不会代理请求需要的服务;断路器打开一段时间后会进入”半开“状态,允许一个请求访问服务,如果请求成功则关闭断路器,否则继续保存打开状态。
Hystrix:
Hystrix是netflix开源的防止服务级联失败的容错库。Hystrix会实时监控服务调用情况(失败、超时等),当服务调用失败到达一定阈值时断路器会自动打开。请求失败、超时、或断路器打开时会执行回退逻辑。
二.Hystrix容错方式
(一).@HystrixCommand容错
1.consumer-user引入Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.启动类增加@EnableCircuitBreaker注解开启熔断处理机制
@SpringBootApplication
@EnableFeignClients({"com.vincent.consumer.feign"})
@EnableCircuitBreaker
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
3.@HystrixCommand修饰方法,使其具备容错能力
package com.vincent.consumer.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.vincent.consumer.feign.IUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class TestController {
@Autowired
private IUserFeign userFeign;
@GetMapping("/getUserById")
@HystrixCommand(fallbackMethod = "getUserByIdFallback")
public Object getUserById(Integer id){
return this.userFeign.getById(id);
}
public Object getUserByIdFallback(Integer id,Throwable throwable){
Map<String,Object> data = new HashMap<>();
data.put("cause",throwable.getMessage());
data.put("msg","方法调用失败");
return data;
}
}
@HystrixCommand的fallbackMethod属性用于指定回退方法,回退方法需要与修饰的方法在同一个类中且方法签名参数需要一样,但是回退方法可以增加额外的回退参数Throwable;defaultFallback属性可以不需要同方法签名一样,可以直接增加Throwable参数处理多个回退处理逻辑。
4.启动service-eureka、service-user、consumer-user,并访问http://localhost:8030/getUserById?id=9
停止service-user并访问http://localhost:8030/getUserById?id=9:
Hystrix 默认1s超时设置,修改超时设置使用如下方式:
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
读取对端数据的Ribbon超时时间默认1s,修改配置如下:
ribbon:
ReadTimeout: 3000
(二).Feign使用Hystrix
@HystrixCommand注解在方法体上,FeignClient以接口方式将不适用。@FeignClient注解提供了fallback、fallbackFactory 属性实现FeignClient的失败回退。
由相关说明可知,可以实现@FeignClient标注接口的类或实现FallbackFactory工厂类提供回退类。
1.SpringCloud为Feign已经整合了Hystrix,设置feign.hystrix.enabled=true
feign:
hystrix:
enabled: true
2.@FeignClient设置fallback
package com.vincent.consumer.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "service-user",fallback = UserFeignFallback.class)
public interface IUserFeign {
@GetMapping("/user/{id}")
Object getById(@PathVariable("id") Integer id);
}
3.实现IUserFeign作为回退处理类
package com.vincent.consumer.feign;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class UserFeignFallback implements IUserFeign{
@Override
public Object getById(Integer id) {
Map<String,Object> rst = new HashMap<>();
rst.put("msg","UserFeign 失败回退");
return rst;
}
}
4.TestController.java
package com.vincent.consumer.controller;
import com.vincent.consumer.feign.IUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
private IUserFeign userFeign;
@GetMapping("/getUserById")
public Object getUserById(Integer id){
return this.userFeign.getById(id);
}
}
5.停止service-user 并访问http://localhost:8030/getUserById?id=9
fallbackFactory 属性与fallback基本类似,只是实现类create 方法有回退失败Throwable参数,create方法返回值也是一个实现了@FeignClient标注的类。
Feign使用Hystrix作为断路器,使用Feign远程映射接口时超时设置如下,通常还需要设置Hystrix 超时才能生效(hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds)
feign:
client:
config:
default:
readTimeout: 3000
connectTimeout: 3000
三.Hystrix 监控
Hystrix会实时监控服务调用情况,为项目开启熔断处理机制(@EnableCircuitBreaker开启熔断处理)后就可以获取服务监控信息。
1.consumer-user 增加如下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.启动类开启熔断机制
package com.vincent.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients({"com.vincent.consumer.feign"})
@EnableCircuitBreaker
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
3.访问http://localhost:8030/hystrix.stream,将看到浏览器通过SSE(Server-Send-Event)不断获取监控数据,在没有访问微服务时系统监控信息输出是ping,再次访问http://localhost:8030/getUserById?id=9后,监控信息输出如下:
四.Hystrix Dashboard可视化监控
直接访问/hystrix.stream端点获取的数据是文本信息,Hystrix Dashboard 可以让监控的数据图形化。
1.新建hystrix-dashboard子模块,添加Hystrix Dashboard依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
2.application.yml 配置
server:
port: 8040
3.@EnableHystrixDashboard 修饰启动类
package com.vincent.datamonitor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardApp {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardApp.class,args);
}
}
4.浏览器访问http://localhost:8040/hystrix
dashboard 中加入监控端点:http://localhost:8030/hystrix.stream,并点击Monitor Stream。不断访问http://localhost:8030/getUserById?id=9,将看到监控数据
五.Turbine聚合可视化监控
新建turbine聚合项目:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
application.yaml 配置文件:
server:
port: 8130
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://localhost:8090/eureka
register-with-eureka: false
turbine:
# 配置聚合监控的服务名即eureka注册中心中注册的服务名,多个服务以逗号分割
app-config: hotel-consumer
cluster-name-expression: new String("default")
把turbine聚合接口 http://localhost:8130/turbine.stream 放入HystrixDashboard 监控