天天看點

Spring Cloud之(十三)以線程池的形式實作服務隔離

十三、以線程池的形式實作服務隔離

13.1 系統負載過高存在的問題

在微服務架構中,我們将業務拆分成一個個的服務,服務與服務之間可以互相調用,由于網絡原因或者自身的原因,服務并不能保證服務的100%可用,如果單個服務出現問題,調用這個服務就會出現網絡延遲,此時若有大量的網絡湧入,會形成任務累計,導緻服務癱瘓。

在SpringBoot程式中,預設使用内置tomcat作為web伺服器。單tomcat支援最大的并發請求是有限的,如果某一接口阻塞,待執行的任務積壓越來越多,那麼勢必會影響其他接口的調用。

13.2 以線程池的形式實作服務隔離

  • 引入依賴

    引入以線程池方式實作的隔離的相關依賴。

    <!-- 以線程池的形式完成資源隔離的相關依賴 -->
    <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>
               
  • 配置線程池

    配置 HystrixCommand的實作類,在實作類中可以對線程池進行配置。

    package cn.ebuy.order.command;
    import cn.ebuy.order.pojo.EasybuyProduct;
    import com.netflix.hystrix.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.client.RestTemplate;
    
    public class OrderCommand extends HystrixCommand<EasybuyProduct> {
    
        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(500)
                    .withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);
    
            // 指令屬性配置Hystrix 開啟逾時
            HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
                    // 采用線程池方式實作服務隔離
                    .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                    // 禁止
                    .withExecutionTimeoutEnabled(false);
            return Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey)
                    .andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);
    
        }
    
    	/**
         * 當服務調用時,預設執行run()方法
         * @return
         * @throws Exception
         */
        @Override
        protected EasybuyProduct run() throws Exception {
            System.out.println(Thread.currentThread().getName());
            return restTemplate.getForObject("http://ebuy-product/product/"+id, EasybuyProduct.class);
        }
    
    	/**
         * 當服務阻塞時,執行fallback方法
         * @return
         */
        @Override
        protected EasybuyProduct getFallback(){
            EasybuyProduct easybuyProduct=new EasybuyProduct();
            easybuyProduct.setEpDescription("不好意思,出錯了");
            return easybuyProduct;
        }
    }
               
  • 配置調用

    修改OrderController,使用自定義的OrderCommand完成調用。

    package cn.ebuy.order.controller;
    import cn.ebuy.order.command.OrderCommand;
    import cn.ebuy.order.feign.OrderFeignClient;
    import cn.ebuy.order.pojo.EasybuyProduct;
    import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/order")
    @SuppressWarnings("all")
    //配置全局熔斷,類中預設實作fallback方法
    //@DefaultProperties(defaultFallback = "orderFallBack")
    public class OrderController {
        @Autowired
        RestTemplate restTemplate;
    
        /**
         * 測試--以線程池的形式完成資源隔離
         * @param id
         * @return
         */
        @GetMapping("/test/{id}")
        public EasybuyProduct Order(@PathVariable Long id){
            OrderCommand orderCommand = new OrderCommand(restTemplate,id);
            return orderCommand.execute();
        }
               
Spring Cloud之(十三)以線程池的形式實作服務隔離
Spring Cloud之(十三)以線程池的形式實作服務隔離

繼續閱讀