Hystrix 介绍
在分布式系统中如何保证各个服务的健康机制,当某个服务出现故障时客户端页面不会一直等待,某个服务宕机不会影响整个的分布式服务,要解决这些问题就用到了高可用分布式系统的很多技术包括:资源隔离,限流与过载保护,熔断,优雅降级,容错,超时控制等。
服务雪崩效应
服务雪崩效应的产生是因为所有的服务堆积在同一个线程池中,所有的服务都是同一个线程池去处理,如果在高并发的情况下,所有的请求全部访问同一个接口,这时会导致所有的线程只处理一个服务,其它服务没有线程进行处理,会在等待状态,这就是服务雪崩效应
服务降级
所谓服务降级,就是在高并发情况下,为防止客户等待,当用户调用服务时不进行业务处理,直接返回某种友好提示,比如当前服务器忙,请稍后再试等,这样可以减少服务器压力,使服务器权力处理核心业务。
服务熔断
熔断机制目的为了保护服务,在高并发的情况下,如果请求达到一定极限(可以自己设置阔值)如果流量超出了设置阈值,让后直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用
服务隔离
因为默认情况下,只有一个线程池会维护所有的服务接口,如果大量的请求访问同一个接口,达到tomcat 线程池默认极限,可能会导致其他服务无法访问。
解决服务雪崩效应:使用服务隔离机制(线程池方式和信号量),使用线程池方式实現隔离的原理: 相当于每个接口(服务)都有自己独立的线程池,因为每个线程池互不影响,这样的话就可以解决服务雪崩效应。
线程池隔离:
每个服务接口,都有自己独立的线程池,每个线程池互不影响。
信号量隔离:
使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,当请求进来时先判断计数器的数值,若超过设置的最大线程个数则拒绝该请求,若不超过则通行,这时候计数器+1,请求返 回成功后计数器-1。
服务限流
服务限流就是对接口访问进行限制,常用服务限流算法令牌桶、漏桶。计数器也可以进行粗暴限流实现。
Hystrix
在微服务架构中,我们把每个业务都拆成了单个服务模块,然后当有业务需求时,服务间可互相调用,但是,由于网络原因或者其他一些因素,有可能出现服务不可用的情况,当某个服务出现问题时,其他服务如果继续调用这个服务,就有可能出现线程阻塞,但如果同时有大量的请求,就会造成线程资源被用完,这样就可能会导致服务瘫痪,由于服务间会相互调用,很容易造成蝴蝶效应导致整个系统宕掉。因此,就有人提出来断路器来解决这一问题。
hystrix具备的功能:
资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。
熔断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。
缓存:提供了请求缓存、请求合并实现。
springCloud 使用Hystrix
在cloud系列的第一篇博文中,我们介绍了eureka,现在对第一篇博文中的order服务进行改造,用于支持Hysrtix
- 修改pom.xml,用于增加对hystrix的依赖
<!-- hystrix断路器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 修改application.yml,开启hystrix
###服务启动端口号
server:
port: 8001
###服务名称(服务注册到eureka名称)
spring:
application:
name: app-itmayiedu-order
###服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
###因为该应用为注册中心,不会注册自己
register-with-eureka: true
###是否需要从eureka上获取注册信息
fetch-registry: true
## 开启hystrix路由器 新增
feign:
hystrix:
enabled: true
3.实现hystrix有两种方式,一种是通过注解@HystrixCommand,一种是配置@FeignClient
@HystrixCommand
@RequestMapping("/orderToMemberHystrix")
@HystrixCommand(fallbackMethod = "orderToMemberFallBack") ,fallbakMethod 配置服务降级后调用的方法
/**
* HystrixCommand 具有开启服务降级,服务熔断,服务隔离的功能
* 服务隔离默认是线程池隔离
* 熔断阈值默认应该是10 ,没记错的话
*
*/
public ResponseBase orderToMemberHystrix(){
System.out.println("当前线程池名称"+Thread.currentThread().getName());
memberFeign.getUserinfo(); // 调用这个接口会失败,之后会跳转到服务降级方法
return setResultSuccess();
}
// 服务降级的方法
public ResponseBase orderToMemberFallBack(){
return setResultError("服务降级,服务繁忙请稍后再试");
}
@FeignClient
首先实现IMemberFeign 接口类,在实现类里定义服务降级的方法
@Component //一定要注册到spring中
public class MemberFeignFallback implements IMemberFeign {
@Override
public UserEntity getMember(String name) {
return null;
}
@Override
public String getUserinfo() {
return "服务降级,统一的服务处理方法";
}
}
修改@FeignClient
@FeignClient(name = "app-member",fallback = MemberFeignFallback.class) // 这里的fllback就是上面的实现类
public interface IMemberFeign extends IMemberService {
}
4 开启@EnableHystrix注解
**/
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
@EnableHystrix // 开启hystrix
public class AppOrder {
public static void main(String[] args) {
SpringApplication.run(AppOrder.class,args);
}
}
分别启动eureka order member服务,访问 订单接口,即可实现服务降级