Loading

线程池实现服务隔离

问题分析

在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用,由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪。
在SpringBoot程序中,默认使用内置tomcat作为web服务器。单tomcat支持最大的并发请求是有限的,如果某一接口阻塞,待执行的任务积压越来越多,那么势必会影响其他接口的调用。

线程池的形式实现服务隔离

(1) 配置坐标

为了方便实现线以线程池的形式完成资源隔离,需要引入如下依赖
<dependency>
  <groupId>com.netflix.hystrix</groupId>
  <artifactId>hystrix-metrics-event-stream</artifactId>
  <version>1.5.12</version>
</dependency>
<dependency>
  <groupId>com.netflix.hystrix</groupId>
  <artifactId>hystrix-javanica</artifactId>
  <version>1.5.12</version>
</dependency>

(2) 配置线程池

配置HystrixCommand接口的实现类,再实现类中可以对线程池进行配置
public class OrderCommand extends HystrixCommand<String> {

  private RestTemplate restTemplate;
  private Long id;

  public OrderCommand(RestTemplate restTemplate, Long id) {
      super(setter());
      this.restTemplate = restTemplate;
      this.id = id;
  }

  private static Setter setter() {


      // 服务分组
      HystrixCommandGroupKey groupKey =
HystrixCommandGroupKey.Factory.asKey("order_product");
      // 服务标识
      HystrixCommandKey commandKey =
HystrixCommandKey.Factory.asKey("product");
      // 线程池名称
      HystrixThreadPoolKey threadPoolKey =
HystrixThreadPoolKey.Factory.asKey("order_product_pool");
      /**
       * 线程池配置
       *     withCoreSize :  线程池大小为10
       *     withKeepAliveTimeMinutes:  线程存活时间15秒
       *     withQueueSizeRejectionThreshold  :队列等待的阈值为100,超过100执行拒绝
策略
       */
      HystrixThreadPoolProperties.Setter threadPoolProperties =
HystrixThreadPoolProperties.Setter().withCoreSize(50)

.withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);

      // 命令属性配置Hystrix 开启超时
      HystrixCommandProperties.Setter commandProperties =
HystrixCommandProperties.Setter()
              // 采用线程池方式实现服务隔离
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrat
egy.THREAD)
              // 禁止
              .withExecutionTimeoutEnabled(false);
      return
HystrixCommand.Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThread
PoolKey(threadPoolKey)

.andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefau
lts(commandProperties);

  }


  @Override
  protected String run() throws Exception {
      return restTemplate.getForObject("http://shop-service-
product/product/"+id, String.class);
  }


  @Override
  protected String getFallback(){
      return "熔断降级";
  }
}

(3) 配置调用

修改 OrderController ,使用自定义的OrderCommand完成调用
@Autowired
private RestTemplate restTemplate;

@GetMapping("/buy/{id}")
public String order(@PathVariable Long id) throws ExecutionException,
InterruptedException, TimeoutException {
  return new OrderCommand(restTemplate,id).execute();
}

 

posted @ 2021-07-27 16:25  1640808365  阅读(632)  评论(0编辑  收藏  举报