Skip to content

Instantly share code, notes, and snippets.

@yangl
Created April 19, 2018 10:34
Show Gist options
  • Save yangl/e4d0d2a8e613e09e385e0297e9d37686 to your computer and use it in GitHub Desktop.
Save yangl/e4d0d2a8e613e09e385e0297e9d37686 to your computer and use it in GitHub Desktop.
Hystrix dubbo 插件 备忘
hystrix=com.alibaba.dubbo.rpc.protocol.dubbo.filter.HystrixFilter

欢迎使用 Hystrix Dubbo扩展功能


基于Dubbo SPI引入Hystrix。提供如下功能:

  • rest服务接口生成监控数据
  • 服务消费方业务代码零改动具有熔断、限流功能

rest服务接口生成监控数据

1. 更新Dubbo依赖至公司内部最新版本

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>dubbo</artifactId>
	<version>${dubbo-sf.version}</version>
</dependency>

3. 下载hystrix-dashboard并解压至tomcat容器ROOT目录下启动

4. 打开本地tomcat并添加Hystrix地址http://127.0.0.1:8888/hystrix.stream

5.最后就可以查看监控数据了,压测调整hystrix参数至合理值

服务消费方业务代码零改动具有熔断、限流功能

1. 更新Dubbo依赖至公司内部最新版本

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>dubbo</artifactId>
	<version>${dubbo-sf.version}</version>
</dependency>

2. 修改服务消费方Dubbo配置 添加<dubbo:parameter key="hystrix" value="true"/>配置

  <dubbo:reference check="false" id="demoUserRestService"
    interface="com.sf.test.service.DemoUserRestService" registry="regZK2">

    <dubbo:parameter key="hystrix" value="true"/> <!-- (1) -->

    <dubbo:method name="selectByPrimaryKey">
      <dubbo:parameter key="hystrix" value="false"/> <!-- (2) -->
    </dubbo:method>
  </dubbo:reference>

注: 上边的(1)为demoUserRestService接口所有方法启用hystrix熔断、限流功能; 上边的(2)为关闭demoUserRestService接口selectByPrimaryKey方法的hystrix熔断、限流功能; 合理配置dubbo:parameter即可,true为打开,其它为关闭。


结合 disconf 动态配置 Hystrix 参数

监听disconf配置变化回调更新 Hystrix 参数

package com.sf.test.service.conf;

import com.baidu.disconf.client.common.annotations.DisconfFile;
import com.baidu.disconf.client.common.annotations.DisconfUpdateService;
import com.baidu.disconf.client.common.update.IDisconfUpdate;
import com.netflix.config.ConfigurationManager;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

/**
 * hystrix配置
 *
 * 在disconf统一配置中心后台改动会自动重新加载最新配置
 *
 * @author YANGLiiN 2017-06-27 10:41
 */

@Component
@DisconfFile(filename = HystrixConfig.HYSTRIX_CONFIG_NAME)
@DisconfUpdateService(classes = {HystrixConfig.class})
public class HystrixConfig implements InitializingBean, IDisconfUpdate {

  private static final Logger log = LoggerFactory.getLogger(HystrixConfig.class);

  public static final String HYSTRIX_CONFIG_NAME = "hystrix.properties";

  @Override
  public void afterPropertiesSet() throws Exception {
    loadProperties();
  }

  @Override
  public void reload() throws Exception {
    loadProperties();
  }

  private void loadProperties() {
    try {
      ConfigurationManager.getConfigInstance().clear();
      ConfigurationManager.loadPropertiesFromResources(HYSTRIX_CONFIG_NAME);
    } catch (IOException e) {
      log.error("加载hystrix.properties配置发错", e);
    }

  }


}

disconf配置中心后台添加hystrix.properties配置文件

##################默认配置项##################
### 线程池大小
hystrix.threadpool.default.coreSize=200

### 是否强制打开熔断器,默认关闭
hystrix.command.default.circuitBreaker.forceOpen=false
### 触发熔断后,拒绝请求后多长时间开始尝试再次执行,默认5000毫秒
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=10000
### 触发熔断的错误比例。默认50,即50%
hystrix.command.default.circuitBreaker.errorThresholdPercentage=10
### 超时时间,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
### 是否开启超时,默认true
hystrix.command.default.execution.timeout.enabled=false
### 是否开启熔断,默认true
hystrix.command.default.circuitBreaker.enabled=true
### 是否开启fallback,默认true
hystrix.command.default.fallback.enabled=true

##################非default配置项##################
hystrix.command.demoUserRestService_selectAll.circuitBreaker.forceOpen=false
hystrix.command.demoUserRestService_selectByPrimaryKey.circuitBreaker.forceOpen=false
package com.alibaba.dubbo.rpc.protocol.dubbo.filter;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.common.utils.StringUtils;
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.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
/**
* Hystrix熔断过滤器
*
* @author YANGLiiN 2017-07-04 16:15
*/
@Activate(group = {
Constants.CONSUMER/*, Constants.PROVIDER*/}, value = DubboHystrixCommand.HYSTRIX_KEY)
public class HystrixFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
URL url = invoker.getUrl();
if (url != null) {
String is = url.getParameter(DubboHystrixCommand.HYSTRIX_KEY, "false");
String ms = url
.getMethodParameter(invocation.getMethodName(), DubboHystrixCommand.HYSTRIX_KEY);
// hystrix功能开启
if (StringUtils.isEquals("true", ms) || (
StringUtils.isEquals("true", is) && StringUtils.isBlank(ms))) {
DubboHystrixCommand command = new DubboHystrixCommand(invoker, invocation);
return command.execute();
}
}
// hystrixa功能未开启
return invoker.invoke(invocation);
}
}
class DubboHystrixCommand extends HystrixCommand<Result> {
public static final String HYSTRIX_KEY = "hystrix";
private Invoker<?> invoker;
private Invocation invocation;
public DubboHystrixCommand(Invoker<?> invoker, Invocation invocation) {
super(
Setter.withGroupKey(HystrixCommandGroupKey.Factory
.asKey(org.apache.commons.lang3.StringUtils
.substringAfterLast(invoker.getInterface().getName(), ".")))
.andCommandKey(
HystrixCommandKey.Factory.asKey(String.format("%s_%s",
org.apache.commons.lang3.StringUtils
.substringAfterLast(invoker.getInterface().getName(), "."),
invocation.getMethodName()
)))
.andCommandPropertiesDefaults(
//使用dubbo的超时,禁用Hystrix的超时功能
HystrixCommandProperties.Setter().withExecutionTimeoutEnabled(false)
// 禁用fallback功能
.withFallbackEnabled(false)));
// 其它参数可直接使用disconf统一配置管理,与服务提供方例子一样 @see com.sf.test.service.conf.HystrixConfig
this.invoker = invoker;
this.invocation = invocation;
}
@Override
protected Result run() throws Exception {
return invoker.invoke(invocation);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment