1.Hystrix
简介:Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败
问题起因:例如微服务I发生异常,请求阻塞,用户不会得到响应,则tomcat的这个线程不会释放,于是越来越多的用户请求到来,越来越多的线程会阻塞
解决手段:
- 1.1线程隔离
- 1.2服务熔断
1.1线程隔离
触发Hystix服务降级的情况:
- 线程池已满
- 请求超时
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
启动类的方式
@SpringCloudApplication
相当于
@SpringBootApplication
@EnableDiscoveryClient //客户端的(包括提供者和消费者)
@EnableCircuitBreaker//激活Hystix功能
给RestTemplate增加注解
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
编写降级逻辑:
1)针对每个方法的
@GetMapping
@ResponseBody
@HystrixCommand(fallbackMethod = "queryUserByIdFallBack")
public String queryUserById(@RequestParam("id") Long id) {
String user = this.restTemplate.getForObject("http://service-provider/user/" + id, String.class);
return user;
}
public String queryUserByIdFallBack(Long id){
return "请求繁忙,请稍后再试!";
}
2)针对每个类的
@Controller
@RequestMapping("consumer/user")
@DefaultProperties(defaultFallback = "fallBackMethod") // 指定一个类的全局熔断方法
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping
@ResponseBody
@HystrixCommand // 标记该方法需要熔断
public String queryUserById(@RequestParam("id") Long id) {
String user = this.restTemplate.getForObject("http://service-provider/user/" + id, String.class);
return user;
}
/**
* 熔断方法
* 返回值要和被熔断的方法的返回值一致
* 熔断方法不需要参数
* @return
*/
public String fallBackMethod(){
return "请求繁忙,请稍后再试!";
}
}
设置超时时长
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
1.2服务熔断
相当于电闸跳闸了
熔断状态机3个状态:
- Closed:关闭状态,所有请求都正常访问。
- Open:打开状态,所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
- Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会完全关闭断路器,否则继续保持打开,再次进行休眠计时
熔断的配置参数
circuitBreaker.requestVolumeThreshold=10 #触发熔断的最小请求次数,默认20
circuitBreaker.sleepWindowInMilliseconds=10000 #休眠时长,默认是5000毫秒
circuitBreaker.errorThresholdPercentage=50 #触发熔断的失败请求最小占比,默认50%
2.Feign
2.1 pom依赖
<artifactId>spring-cloud-starter-openfeign</artifactId>
2.2启动类增加注解
@EnableFeignClients
2.3添加http调用接口
@FeignClient(value = "service-provider") // 标注该类是一个feign接口
public interface UserClient {
@GetMapping("user/{id}")
User queryById(@PathVariable("id") Long id);
}
2.4功能
本身已经集成了Ribbon和Hystrix
如何打开hystrix
feign.hystrix.enabled=true
2.5在2.3的基础上增加降级处理逻辑
增加处理类
@Component
public class UserClientFallback implements UserClient {
@Override
public User queryById(Long id) {
User user = new User();
user.setUserName("服务器繁忙,请稍后再试!");
return user;
}
}
在接口指定降级处理逻辑类
@FeignClient(value = "service-provider", fallback = UserClientFallback.class) // 标注该类是一个feign接口
public interface UserClient {
@GetMapping("user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
5.6了解一下额外的配置属性(一般用默认值就好了)
feign.compression.request.enabled=true # 开启请求压缩
feign.compression.response.enabled=true # 开启响应压缩feign.compression.request.mime-types=text/html,application/xml,application/json # 设置压缩的数据类型
feign.compression.request.min-request-size=2048 # 设置触发压缩的大小下限
5.7了解一下定义日志级别
1)编写配置文件
@Configuration
public class FeignLogConfiguration {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
2)在FeignClient接口指定配置类
@FeignClient(value = "service-privider", fallback = UserFeignClientFallback.class, configuration = FeignConfig.class)
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
3.Zuul网关
1.pom文件
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
2启动类
@SpringCloudApplication
@EnableZuulProxy
3关于一些配置文件
zuul:
prefix: /api # 路由路径前缀
routes:
item-service: /item/**
search-service: /search/**
user-service: /user/**
auth-service: /auth/**
cart-service: /cart/**
order-service: /order/**
# 这下面的配置相当于把前缀给去掉了
upload-service:
path: /upload/**
serviceId: upload-service
strip-prefix: false
add-host-header: true
sensitive-headers: #覆盖默认敏感头信息"Cookie", "Set-Cookie", "Authorization"
4过滤器执行生命周期
4.1过滤器使用场景
- 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了
- 异常处理:一般会在error类型和post类型过滤器中结合来处理。
- 服务调用时长统计:pre和post结合使用。
5Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置