文档章节

Hystrix Semaphore timeout

OrangeJoke
 OrangeJoke
发布于 2018/10/03 22:17
字数 964
阅读 443
收藏 0

When to use semaphore

For Thread isolation. there is a thread context switch cost. but this is almost can be ignored in most application. see Thread pool

For circuits that wrap very low-latency requests (such as those that primarily hit in-memory caches) the overhead can be too high and in those cases you can use another method such as tryable semaphores which, while they do not allow for timeouts, provide most of the resilience benefits without the overhead. The overhead in general, however, is small enough that Netflix in practice usually prefers the isolation benefits of a separate thread over such techniques.

Drawbacks

It does not allow for timing out and walking away.

why? show me the code.

    /**
     * Semaphore that only supports tryAcquire and never blocks and that supports a dynamic permit count.
     * <p>
     * Using AtomicInteger increment/decrement instead of java.util.concurrent.Semaphore since we don't need blocking and need a custom implementation to get the dynamic permit count and since
     * AtomicInteger achieves the same behavior and performance without the more complex implementation of the actual Semaphore class using AbstractQueueSynchronizer.
     */
    /* package */static class TryableSemaphoreActual implements TryableSemaphore {
        protected final HystrixProperty<Integer> numberOfPermits;
        private final AtomicInteger count = new AtomicInteger(0);

        public TryableSemaphoreActual(HystrixProperty<Integer> numberOfPermits) {
            this.numberOfPermits = numberOfPermits;
        }

        @Override
        public boolean tryAcquire() {
            int currentCount = count.incrementAndGet();
            if (currentCount > numberOfPermits.get()) {
                count.decrementAndGet();
                return false;
            } else {
                return true;
            }
        }

        @Override
        public void release() {
            count.decrementAndGet();
        }

        @Override
        public int getNumberOfPermitsUsed() {
            return count.get();
        }

    }


通过计数的形式实现信号量机制。 Since1.4.4 Hystrix 提供了信号量的timeOut 机制,但是timeout 不会中断原来的线程,但是在timeout 发生的时候,把这个信息反馈到熔断器上,这样能做到更加实时的熔断机制。timeout 也是通过Timer 来实现的。


       Observable<R> execution;
        if (properties.executionTimeoutEnabled().get()) {
            execution = executeCommandWithSpecifiedIsolation(_cmd)
                    .lift(new HystrixObservableTimeoutOperator<R>(_cmd));
        } else {
            execution = executeCommandWithSpecifiedIsolation(_cmd);
        }
		
		
		TimerListener listener = new TimerListener() {

                @Override
                public void tick() {
                    // if we can go from NOT_EXECUTED to TIMED_OUT then we do the timeout codepath
                    // otherwise it means we lost a race and the run() execution completed or did not start
                    if (originalCommand.isCommandTimedOut.compareAndSet(TimedOutStatus.NOT_EXECUTED, TimedOutStatus.TIMED_OUT)) {
                        // report timeout failure
                        originalCommand.eventNotifier.markEvent(HystrixEventType.TIMEOUT, originalCommand.commandKey);

                        // shut down the original request
                        s.unsubscribe();

                        final HystrixContextRunnable timeoutRunnable = new HystrixContextRunnable(originalCommand.concurrencyStrategy, hystrixRequestContext, new Runnable() {

                            @Override
                            public void run() {
                                child.onError(new HystrixTimeoutException());
                            }
                        });


                        timeoutRunnable.run();
                        //if it did not start, then we need to mark a command start for concurrency metrics, and then issue the timeout
                    }
                }

                @Override
                public int getIntervalTimeInMilliseconds() {
                    return originalCommand.properties.executionTimeoutInMilliseconds().get();
                }
            };
		

Note: if a dependency is isolated with a semaphore and then becomes latent, the parent threads will remain blocked until the underlying network calls timeout. Semaphore rejection will start once the limit is hit but the threads filling the semaphore can not walk away.

信号量机制不允许超时设定,所以会阻塞服务端的线程,这样如果当command里面的执行变得很慢的时候,就会block当前请求的线程。这个时候如果信号量设置得很大,比如100,那么这100个线程都会被阻塞。如果有多个调用如此,那客户端能处理的请求就会变少。

这里是ab测试:默认请求是3秒完成,客户端无超时时间,信号量100:

ab -n 200 -c 200 http://localhost:8990/coke/block
Percentage of the requests served within a certain time (ms)
  50%   3057
  66%   3238
  75%   3274
  80%   3321
  90%   3510
  95%   3516
  98%   3523
  99%   3524
 100%   3526 (longest request)

期望:100个请求通过,100个被拒绝

Zuul and Hystrix timeout

As we know Zuul default use HystrixCommand with in ribbon http client.Default Hystrix isolation pattern (ExecutionIsolationStrategy) for all routes is SEMAPHORE.

Zuul 默认使用信号量做隔离(因为Zuul主要做请求转发已经是线程隔离的了,所以没有必要再使用一次线程隔离),超时由HttpClient的timeout 设置,当请求timeout之后抛出异常,然后才会触发对应的熔断降级。 如果使用线程池做隔离,则超时实践如下:

(ribbon.ConnectTimeout + ribbon.ReadTimeout) * (ribbon.MaxAutoRetries + 1) * (ribbon.MaxAutoRetriesNextServer + 1)

Zuul default use serviceId as commandKey, default semophore is 100.

Sentinel

If you trust the client and you only want load shedding, you could use this approach.(Semaphore)

当我们的调用方有可能出现延迟,并且qps很高的时候(如果这个时候使用线程池,你可能需要创建很大数量的线程池比如,qps2000,响应时间1秒,这个时候就需要 2000大小的线程,会额外带来大量的线程切换开销),这个时候我们可以使用alibaba/Sentinel 来做熔断降级。

具体可以参考这里熔断

Sentinel 与 Hystrix 的对比

© 著作权归作者所有

OrangeJoke
粉丝 40
博文 57
码字总数 39192
作品 0
江北
高级程序员
私信 提问
加载中

评论(1)

trust-freedom
trust-freedom
“因为Zuul主要做请求转发已经是线程隔离的了,所以没有必要再使用一次线程隔离”??
Zuul如果使用semaphore隔离,zuul server接收请求和执行转发调用的都是同一个线程吧? 我感觉zuul之所以默认用信号量隔离,是因为网关是多扇出的,后端可能有几十个微服务,每个都有一个线程池的话,线程会很多
Hystrix 配置信息

在Hystrix中我们一般是用的默认配置,有些时候需要调整一些参数来获取更好的处理性能 配置官方文档:https://github.com/Netflix/Hystrix/wiki/Configuration Execution相关的属性的配置: ...

尹吉欢
2017/12/17
0
0
聊聊hystrix的fallback

序 本文主要研究下hystrix的fallback AbstractCommand.executeCommandAndObserve hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/AbstractCommand.java 使用Observable的onErrorResu......

go4it
2018/07/08
394
0
Hystrix概述(二)

一、hystrix在生产中的建议 1、保持timeout的默认值(1000ms),除非需要修改(其实通常会修改) 2、保持threadpool的的线程数为10个,除非需要更多 3、依赖标准的报警和监控系统来捕获问题 ...

李景枫
2016/07/19
2.1K
0
HytrixCommand实践总结

一. 使用HystrixCommand编码方式 //构造setter HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(group); HystrixThreadPoolKey threadPoolKey = HystrixThreadPoo......

独孤环宇
2018/01/11
0
0
Hystrix semaphore和thread隔离策略的区别及配置参考

Hystrix semaphore和thread隔离策略的区别及配置参考 通用设置说明 Hystrix所有的配置都是开头,其中是可变的,默认是,即;另外Hystrix内置了默认参数,如果没有配置Hystrix属性,默认参数就会...

xiaomin0322
2019/04/08
83
0

没有更多内容

加载失败,请刷新页面

加载更多

六、Spring Cloud之配置中心config

前言 前面我们讲了微服务的注册中心、负载均衡、熔断处理、网管服务。接下来我们讲配置中心,为什么要用配置中心呢? 其实我们接触一段时间就可以发现,我们的项目还是非常多的,每个项目都有...

quellanan2
11分钟前
21
0
在Android的EditText视图中允许多行?

如何在Android的EditText视图中允许多行? #1楼 这对我有用 ,实际上这两个属性很重要: inputType和lines 。 此外,您可能需要一个滚动条,下面的代码显示了如何制作一个: <EditText ...

技术盛宴
15分钟前
13
0
分享自己写的JS版日期格式化和解析工具类,绝对好用!

前言 本来想模仿Java里面的SimpleDateFormat()对象的,但是感觉这样用起来不方便,所以还是直接写成单独的方法算了。 原文链接 日期格式化 2.1. 使用说明 formatDate(date, fmt),其中fmt支持...

SuShine
25分钟前
27
0
快递鸟api物流查询接口实现订阅物流轨迹单号查询功能对接调用

背景: 分享一篇关于在电商系统中同步物流轨迹到本地服务器的文章,当前方案使用了快递鸟集成api做为数据来源接口,这个接口是免费使用的,不过提供的功能还是非常强大的,有专门的售后维护团...

程序的小猿
30分钟前
34
0
Day08多态,abstract,接口

1.A:多态的概述:事物存在的多种形态。 B:多态前提:要有继承关系,方法重写和父类引用子类对象。 父类引用子类对象:Animal a = new Cat(); a.eat(); //效果等同于c.eat(); 2.多态中的...

Lao鹰
35分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部