dubbo hystrix

来源:互联网 发布:常州seo徐建伟 编辑:程序博客网 时间:2024/05/22 15:17

大中型分布式系统中,通常我们需要依赖很多dubbo服务,在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖有很多不可控问题:如网络连接缓慢、资源繁忙、暂时不可用、服务脱机等。当依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。


Hystrix

(1)Hystrix使用命令模式HystrixCommand包装依赖调用逻辑,每个命令在单独线程中、信号授权下执行。
(2)可配置依赖调用超时时间,当调用超时时,直接返回或执行降级逻辑。
(3)为每个依赖提供一个小的线程池或信号,如果线程份已满调用将被立即拒绝,默认不采用排队,加速失败判定时间。
(4)请求失败时执行降级逻辑。
(5)提供熔断器组件,可以自动运行或手动调用,停止当前依赖一段时间(10s),熔断器默认错误阈值为50%,超过将自动运行。
(6)提供实时依赖的统计和监控。

Dubbo消费者引入Hystrix

package com.netease.hystrix.dubbo.rpc.filter;import com.alibaba.dubbo.common.Constants;import com.alibaba.dubbo.common.extension.Activate;import com.alibaba.dubbo.rpc.Filter;import com.alibaba.dubbo.rpc.Invocation;import com.alibaba.dubbo.rpc.Invoker;import com.alibaba.dubbo.rpc.Result;import com.alibaba.dubbo.rpc.RpcException;@Activate(group = Constants.CONSUMER)public class HystrixFilter implements Filter {    @Override    public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {        DubboHystrixCommand command = new DubboHystrixCommand(invoker, invocation);        return command.execute();    }}

DubboHystrixCommand代码
package com.netease.hystrix.dubbo.rpc.filter;import org.apache.log4j.Logger;import com.alibaba.dubbo.common.URL;import com.alibaba.dubbo.rpc.Invocation;import com.alibaba.dubbo.rpc.Invoker;import com.alibaba.dubbo.rpc.Result;import com.netflix.hystrix.HystrixCommand;import com.netflix.hystrix.HystrixCommandGroupKey;import com.netflix.hystrix.HystrixCommandKey;import com.netflix.hystrix.HystrixCommandProperties;import com.netflix.hystrix.HystrixThreadPoolProperties;public class DubboHystrixCommand extends HystrixCommand {    private static Logger    logger                       = Logger.getLogger(DubboHystrixCommand.class);    private static final int DEFAULT_THREADPOOL_CORE_SIZE = 30;    private Invoker       invoker;    private Invocation       invocation;        public DubboHystrixCommand(Invoker invoker,Invocation invocation){        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(invoker.getInterface().getName()))                    .andCommandKey(HystrixCommandKey.Factory.asKey(String.format("%s_%d", invocation.getMethodName(),                                                                                 invocation.getArguments() == null ? 0 : invocation.getArguments().length)))              .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()                                            .withCircuitBreakerRequestVolumeThreshold(20)//10秒钟内至少19此请求失败,熔断器才发挥起作用                                            .withCircuitBreakerSleepWindowInMilliseconds(30000)//熔断器中断请求30秒后会进入半打开状态,放部分流量过去重试                                            .withCircuitBreakerErrorThresholdPercentage(50)//错误率达到50开启熔断保护                                            .withExecutionTimeoutEnabled(false))//使用dubbo的超时,禁用这里的超时              .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(getThreadPoolCoreSize(invoker.getUrl()))));//线程池为30                       this.invoker=invoker;        this.invocation=invocation;    }        /**     * 获取线程池大小     *      * @param url     * @return     */    private static int getThreadPoolCoreSize(URL url) {        if (url != null) {            int size = url.getParameter("ThreadPoolCoreSize", DEFAULT_THREADPOOL_CORE_SIZE);            if (logger.isDebugEnabled()) {                logger.debug("ThreadPoolCoreSize:" + size);            }            return size;        }        return DEFAULT_THREADPOOL_CORE_SIZE;    }    @Override    protected Result run() throws Exception {        return invoker.invoke(invocation);    }}


线程池大小可以通过Dubbo参数进行控制,当前其他的参数也可以通过类似的方式进行配置
<dubbo:parameter key="ThreadPoolCoreSize" value="20" />

|-resources        |-META-INF            |-dubbo                |-com.alibaba.dubbo.rpc.Filter (纯文本文件,内容为:hystrix=com.netease.hystrix.dubbo.rpc.filter.HystrixFilter

由于Filter定义为自动激活,所以启动代码所有消费者都被隔离起来啦。

原创粉丝点击