服务治理-线程隔离

原创 2018年04月16日 16:46:41

隔离

隔离是指将系统或资源分隔开,为了在系统发生故障时,减小影响范围,防止雪崩。常见的隔离有,环境隔离,资源隔离,线程隔离,进程隔离,集群隔离,机房隔离,读写隔离,动静隔离,爬虫隔离等等。。本篇主要讲线程隔离。

举个例子,在下单场景下,需要获取商家信息和商品信息,如果商家服务查询数据库发生缓慢情况,也会影响到商品服务,导致整个下单流程不能走完。像这种情况,我们可以采用降级策略,在服务发生故障的时候,进行熔断,返回一些托底数据,阻止雪崩。

我采用的是spring cloud这个框架集合,它提供了spring cloud-hystrix组件。hystrix是Netflix开源的一款容错系统,用来隔离分布式服务故障。

直入话题,下面是Hystrix的实战。

Hystrix提供了俩种隔离方式,信号量隔离和线程池隔离。

线程池隔离

//需引入的依赖包
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>1.5.12</version>
</dependency>
/**
 * @author jespon
 * @date 2018/4/16 14:44
 * @desc 代码方式配置。注意:一个command只能调用一次,不可以写单例,调用只能实例化
 */
public class GetStockCommand extends HystrixCommand<String> {

    private StockService stockService;

    public GetStockCommand(StockService stockService) {
        super(setter());
        this.stockService = stockService;
    }

    private static Setter setter(){

        //服务分组名称,相同分局服务聚合
        HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("stock");
        //服务唯一标识
        HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("getStock");
        //线程池名称
        HystrixThreadPoolKey poolKey = HystrixThreadPoolKey.Factory.asKey("stock-pool");

        HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter()
                .withCoreSize(10)    //核心线程池大小,核心线程一直存活
                .withKeepAliveTimeMinutes(5)     //线程池空闲线程的生存时间,超过则销毁
                .withMaxQueueSize(10000)     //线程池队列大小
                .withQueueSizeRejectionThreshold(100);      //动态队列大小调整,因为MaxQueueSize不会改变,通过这个属性来限制,当MaxQueueSize=-1(默认值)时,不生效

        //线程池隔离方式
        HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);

        return HystrixCommand.Setter
                .withGroupKey(groupKey)
                .andCommandKey(commandKey)
                .andThreadPoolKey(poolKey)
                .andThreadPoolPropertiesDefaults(threadPoolProperties)
                .andCommandPropertiesDefaults(commandProperties);
    }

    //业务处理,开启一个新线程执行
    @Override
    protected String run() throws Exception {
        return stockService.getStock();
    }

    //降级处理
    @Override
    protected String getFallback() {
        return "降级处理";
    }
}
    //调用方代码
    public String getStock(){
        GetStockCommand getStockCommand = new GetStockCommand(stockService);
        String result = getStockCommand.execute();//同步调用
        //Future<String> future = getStockCommand.queue();String result = future.get();//异步非堵塞方式调用
        //Observable<String> observe = getStockCommand.observe(); observe.asObservable().subscribe((result) -> {System.out.println(result)});//响应式编程
        return result;
    }

以上是java代码方式配置线程池隔离,这个代码量确实让人有点不敢恭维,于是就有了javanica项目,提供了hystrix的注解配置方式。代码如下

//依赖包
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.12</version>
</dependency>
    @HystrixCommand(groupKey = "stock", commandKey = "getStock", threadPoolKey = "stock-pool",
                    threadPoolProperties = {
                        @HystrixProperty(name = "coreSize",value = "10"),
                        @HystrixProperty(name = "maxQueueSize",value = "10000"),
                        @HystrixProperty(name = "keepAliveTimeMinutes",value = "5"),
                        @HystrixProperty(name = "queueSizeRejectionThreshold",value = "100"),
                    },
                    fallbackMethod = "fallbackForGetStock")  //降级方法名
    public String getStockOne() {
        System.out.println("getone");
        return stockService.getStock();
    }

    public String fallbackForGetStock(){
        System.out.println("注解配置降级");
        return "注解配置fallback";
    }

信号量隔离

这里就只写注解配置方式了

 //信号量隔离方式,
    @HystrixCommand(
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
                    @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),   //并发数量
                    @HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "50")  // 信号量配置,如果请求超过了并发信号量,则不走fallback,快速响应失败,抛出fallback execution rejected.这个异常
            },
            fallbackMethod = "fallbackForGetStock")
    public String getStockOneForSemaphore() {
        return stockFeign.getStock();
    }

线程池是控制线程的数量,信号量是用来控制并发数量的。信号量只是限制了总的并发数,服务使用主线程进行同步调用,因此,如果只是限制某个服务的并发数或者不涉及远程调用的情况,可以使用轻量级的信号量隔离。

Java多线程数据隔离(ThreadLocal)

变量值的共享可以使用public static变量的形式,所有的线程都使用同一个public static变量。如果想实现每一个线程都有自己的共享变量需要用到类ThreadLocal。 这里的线程A...
  • IsResultXaL
  • IsResultXaL
  • 2016年11月24日 14:33
  • 640

多线程 : ThreadLocal 实现线程间共享变量隔离例子

package thread; import java.util.Random; public class ThreadLocalShareDataDemo { /** * ThreadL...
  • hackeraaa
  • hackeraaa
  • 2016年03月13日 11:46
  • 423

Java多线程总结(4)— 线程范围内数据操作的隔离及ThreadLocal类

1. Java内存模型  在java中,所有实例域、静态域和数组元素存储在堆内存中,堆内存在线程之间共享(本文使用“共享变量”这个术语代指实例域,静态域和数组元素)。局部变量(Local variab...
  • Mark_LQ
  • Mark_LQ
  • 2015年12月16日 16:39
  • 1982

Hystrix系列-5-Hystrix的资源隔离策略

Hystrix的资源隔离策略有两种,分别为:线程池和信号量。说到资源隔离,那我们就要明白,我们为什么需要资源隔离。 在一个分布式系统中,服务之间都是相互调用的,如下图所示: 例如,我们容器...
  • liuchuanhong1
  • liuchuanhong1
  • 2017年06月25日 18:57
  • 4095

十三、断路器-Hystrix 的隔离策略

断路器-Hystrix 的隔离策略
  • dengqiang123456
  • dengqiang123456
  • 2017年07月23日 17:11
  • 1276

聊聊高并发之隔离术

转载:http://geek.csdn.net/news/detail/100944 隔离是指将系统或资源分割开,系统隔离是为了在系统发生故障时能限定传播范围和影响范围,即发生故障后...
  • zhangxinrun
  • zhangxinrun
  • 2016年09月13日 14:04
  • 976

Hystrix线程隔离技术

认识HystrixHystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离、信号量隔离、降级策略、熔断技术。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多...
  • qq_27935091
  • qq_27935091
  • 2018年02月27日 09:40
  • 77

Hystrix学习(3)隔离

隔离模式 一个形象的解释是:对系统请求按类型划分成若干个的小岛,当某个小岛被火少光了,不会影响到其他的小岛。 Hystrix依赖的隔离架构,如下图:Hystrix在用户请求和服务之间加入了线程池。Hy...
  • qq_17751605
  • qq_17751605
  • 2016年04月23日 12:57
  • 1170

Spring Cloud中使用Hystrix 线程隔离导致ThreadLocal数据丢失

在Spring Cloud中我们用Hystrix来实现断路器,默认是用信号量来进行隔离的,我们可以通过配置使用线程方式隔离。在使用线程隔离的时候,有个问题是必须要解决的,那就是在某些业务场景下通过Th...
  • u010889990
  • u010889990
  • 2018年01月02日 09:30
  • 300

业务线程与IO线程的隔离

线程模型 隔离的好处: 职责明确化。IO线程只负责IO的读写、编解码和心跳等简单功能,以便及时高效处理IO事件;业务线程负责复杂的业务处理; 降低客户端间的相互影响。对于同一IO线程,避免了由于执行...
  • yangguosb
  • yangguosb
  • 2018年01月23日 21:05
  • 71
收藏助手
不良信息举报
您举报文章:服务治理-线程隔离
举报原因:
原因补充:

(最多只允许输入30个字)