Hystrix(3):Hystrix降级/线程池隔离

本文介绍了Hystrix如何通过线程池隔离实现服务的超时和降级功能,避免服务雪崩。当添加@HystrixCommand注解后,方法会被放入线程池执行,若线程池被占满,新请求会被阻塞。为了解决这个问题,采用了线程池隔离策略,每个方法独立设置线程池,确保服务之间的资源隔离,防止一个服务的性能问题影响其他服务。此外,还展示了Hystrix的工作流程,强调了在服务出现问题时,通过降级策略保护系统稳定。
摘要由CSDN通过智能技术生成

目录

1、添加@HystrixCommand后,Hystrix是如何实现超时和降级功能?

2、线程池隔离

3、Hystrix工作流程


思考:当活动服务出现性能问题以后,我们只能眼睁睁看着活动服务被压垮吗?

1、添加@HystrixCommand后,Hystrix是如何实现超时和降级功能?

1、在某个方法上添加了@HystrixCommand后,该方法会被包裹在Hystrix里,并将该方法放到线程池中。类似切面。

分析:用户的请求会到达一个带有@HystrixCommand注解的方法,则该方法被放到线程池中进行执行【Hystrix的线程池中默认有10个线程】,该线程池会调用活动服务。

           此时如果用户的其他请求到达该另一个被@HystrixCommand修饰的方法时,方法1已经有10个请求占据了10个线程,则方法2的请求会等待。

以上模式的问题:所有带有@HystrixCommand注解的方法都用的同一个线程池,而这个线程池的线程数量是有限的,所以,当线程池被方法1占满以后,方法2就无法请求到X服务。

2、启动服务直观查看线程数量

1⃣️、启动

2⃣️、打印启动的进程。jps:当前用户下的java进程

3⃣️、进行多次请求fallback接口

4⃣️、查看线程数。jstack:查看指定进程(pid)的堆栈信息

5⃣️、多次请求timeout接口

6⃣️、查看仍只有10个线程

结论:用户请求的两个方法公用一个线程池。此时有性能问题的服务,当请求过多时,会导致正常的服务无法访问。

如何解决这个问题?

1、增加线程数:不可行,因为如果将线程数从10增加到100,而请求方法1的请求有10000个,此时仍然影响方法2的调用。

2、方法间的线程池隔离:以下隔离方式Hystrix称为 舱壁模式即(bulkhead)

2、线程池隔离

1、通过使用@HystrixCommand使每个方法单独设置线程池

@HystrixCommand(
            threadPoolKey = "firstLoginFallback",
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize",value = "1"),
                    @HystrixProperty(name="maxQueueSize",value = "20")
            },
            fallbackMethod = "firstLoginFallback0")
@Service
public class ActivityServiceBulkhead {
    @Autowired
    private RestTemplate restTemplate;

    /**
     *  调用活动服务,完成初次登陆,奖励发放
     **/
    public String firstLogin(Long userId){
        //使用服务名,实际上Spring会将服务名转为对应ip
        return restTemplate.postForObject("http://activity/firstLoginActivity", userId, String.class);
    }

    /**
     *  调用活动服务,完成初次登陆,奖励发放
     *  定义超时时间,让用户服务不再等待活动服务的响应
     *  这样的话,可以及时释放资源。
     *  使用hystrix,设置超时时间超过2s时则不继续等待调用,直接返回
     *  HystrixThreadPoolProperties类中Setter中(可以进去找配置)
     *  threadPoolKey:该属性为方法单独定义线程池,当key存在时直接使用定义过的线程池,不存在时新创建线程池
     *  threadPoolProperties:为线程池定义属性
     *  coreSize:允许有多少个线程
     *  maxQueueSize:当线程占满,允许排队的请求数量
     **/
    @HystrixCommand(
            threadPoolKey = "firstLoginTimeout",
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize",value = "2"),
                    @HystrixProperty(name="maxQueueSize",value = "20")
            },
            commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")
    })
    public String firstLoginTimeout(Long userId){
        //使用服务名,实际上Spring会将服务名转为对应ip
        return restTemplate.postForObject("http://activity/firstLoginActivityTimeout", userId, String.class);
    }

    /**
     *  需要提供一个备用方案,当活动服务不可用时,执行备用方案,即降级
     **/
    @HystrixCommand(
            threadPoolKey = "firstLoginFallback",
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize",value = "1"),
                    @HystrixProperty(name="maxQueueSize",value = "20")
            },
            fallbackMethod = "firstLoginFallback0")
    public String firstLoginFallback(Long userId){
        //使用服务名,实际上Spring会将服务名转为对应ip
        return restTemplate.postForObject("http://activity/firstLoginActivityError", userId, String.class);
    }

    public String firstLoginFallback0(Long userId){
        return "活动备用方案--降级";
    }
}

2、启动成功

3、发请求

4、实际线程数:此时只有3个。

3、Hystrix工作流程

思考:当活动服务出现性能问题以后,我们只能眼睁睁看着活动服务被压垮吗?

我们希望是什么样子呢?

如果活动服务出现性能问题,如果用户服务不继续请求,那么活动服务肯定不会被压垮;如果用户服务继续请求,很可能会压垮,而且是无意义的压垮。

1、当调用出现错误时,

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值