Dubbo—Hystrix接入

概述

本文将介绍以下内容:

  • Hystrix简介
  • Dubbo接入Hystrix

Hystrix简介

Hystrix是Netflix开源的一款容错系统,主要用于解决服务提供者不可用带来的服务雪崩效应。Hystrix容错方案主要有以下几种:

  • 熔断:只作用在服务调用者,即consumer端,熔断器开关由关闭到打开的状态转换是通过当前服务健康状况(请求失败数 / 请求总数)和设定阈值比较决定的。
  • 降级:当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。
  • 限流(隔离):采用线程/信号的方式,通过隔离限制依赖的并发量和阻塞扩散
  • 异步RPC:将同步RPC调用转为异步调用。

Dubbo接入Hystrix

Dubbo是通过Filter接入Hystrix的。

新建DubboHystrixCommand

设置Hystrix相关参数

package com.beidao.dubbo.hystrix.command;

import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
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;
 
/**
 * Hystrix命令
 * @author 0200759
 *
 */
public class DubboHystrixCommand extends HystrixCommand<Result> {
 
    private static Logger    logger                       = LoggerFactory.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 {
    	try {
			return invoker.invoke(invocation);
		} catch(Exception e){
			e.printStackTrace();
			throw new HystrixBadRequestException(e.getMessage(),e);
		}
    }
    /*@Override
    protected Result getFallback(){
		return new RpcResult(new Exception("wrong invoke"));
    }*/
    
}


注意: 这里在run方法内捕获了Exception并抛出了HystrixBadRequestException异常,故不会执行getFallback方法。

新建Filter

这里配置了一个CONSUMER端全局自动触发的Filter

package com.beidao.dubbo.hystrix.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;
import com.beidao.dubbo.hystrix.command.DubboHystrixCommand;

/**
 *  Hystrix拦截器
 * @author 0200759
 *
 */
@Activate(group = Constants.CONSUMER)
public class HystrixFilter implements Filter {

	public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
		DubboHystrixCommand command = new DubboHystrixCommand(invoker, invocation);
        return (Result) command.execute();
	}

}

目录resources\META-INF\dubbo下新建文件com.alibaba.dubbo.rpc.Filter内容如下

HystrixFilter = com.beidao.dubbo.hystrix.filter.HystrixFilter

Done!当服务调用者调用时参数不满足前面Hystrix设置的参数阈值时,调用者不再调用服务提供者,即发生熔断。

猜你喜欢

转载自blog.csdn.net/qq_30051265/article/details/82791735
今日推荐