dubbo服务降级(1)
1. 在 dubbo 管理控制台配置服务降级

上图的配置含义是:consumer 调用 com.zhang.HelloService 的方法时,直接返回 null,不发起远程调用。
实际操作是:在 zk 的 /dubbo/com.zhang.HelloService/configurators 节点中添加了 override。
override://0.0.0.0/com.zhang.HelloService?category=configurators&dynamic=false&group=a&mock=force:return+null

2. 也可以通过代码,进行服务降级:(dubbo文档中给出了代码片段)
可以通过服务降级功能,临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
向注册中心写入动态配置覆盖规则:
RegistryFactory registryFactory =
ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=consumer_app&mock=force:return+null"));
mock=force:return+null
表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
mock=fail:return+null
表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
dubbo 服务降级的真实含义:并不是对 provider 进行操作,而是告诉 consumer,调用服务时要做哪些动作。
3. 现在分析consumer端静态配置mock, consumer中如何调用mock服务
用户可以在<dubbo:reference>中配置mock属性。如何配置自定义的mock,还没有搞懂。以mock="force:return+null"为例,我们先分析dubbo默认的MockInvoker。
MockClusterInvoker逻辑:

// MockClusterInvoker
public Result invoke(Invocation invocation) throws RpcException {
Result result = null; // 获取<dubbo:reference>的mock属性。
String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), Constants.MOCK_KEY, Boolean.FALSE.toString()).trim();
if (value.length() == 0 || value.equalsIgnoreCase("false")){
//mock="" 或者 mock="false"
result = this.invoker.invoke(invocation);
} else if (value.startsWith("force")) {
//强制使用mock,如mock="force:return+null"
if (logger.isWarnEnabled()) {
logger.info("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + directory.getUrl());
}
result = doMockInvoke(invocation, null);
} else {
//mock="fail:return+null" 或 mock="MyMock"
try {
result = this.invoker.invoke(invocation);
}catch (RpcException e) {
if (e.isBiz()) {
throw e;
} else {
if (logger.isWarnEnabled()) {
logger.info("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + directory.getUrl(), e);
}
//出现超时异常
result = doMockInvoke(invocation, e);
}
}
}
return result;
} private Result doMockInvoke(Invocation invocation, RpcException e) {
Result result = null;
Invoker<T> minvoker; List<Invoker<T>> mockInvokers = selectMockInvoker(invocation);
if (mockInvokers == null || mockInvokers.size() == 0){
//如果没有配置自定义Mock,则使用默认MockInvoker
minvoker = (Invoker<T>) new MockInvoker(directory.getUrl());
} else {
minvoker = mockInvokers.get(0);
}
try {
//调用
result = minvoker.invoke(invocation);
} catch (RpcException me) {
if (me.isBiz()) {
result = new RpcResult(me.getCause());
} else {
throw new RpcException(me.getCode(), getMockExceptionMessage(e, me), me.getCause());
}
} catch (Throwable me) {
throw new RpcException(getMockExceptionMessage(e, me), me.getCause());
}
return result;
}

默认的MockInvoker:

// MockInvoker
public Result invoke(Invocation invocation) throws RpcException {
//获取url中的sayHello.mock参数值
String mock = getUrl().getParameter(invocation.getMethodName() + "." + Constants.MOCK_KEY);
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(this);
}
if (StringUtils.isBlank(mock)){
//获取mock属性值
mock = getUrl().getParameter(Constants.MOCK_KEY);
} if (StringUtils.isBlank(mock)){
throw new RpcException(new IllegalAccessException("mock can not be null. url :" + url));
}
//假定mock="force:return+null",处理后mock="return+null"
mock = normallizeMock(URL.decode(mock));
if (Constants.RETURN_PREFIX.trim().equalsIgnoreCase(mock.trim())){
RpcResult result = new RpcResult();
result.setValue(null);
return result;
} else if (mock.startsWith(Constants.RETURN_PREFIX)) {
//构造返回值
mock = mock.substring(Constants.RETURN_PREFIX.length()).trim();
mock = mock.replace('`', '"');
try {
Type[] returnTypes = RpcUtils.getReturnTypes(invocation);
Object value = parseMockValue(mock, returnTypes);
return new RpcResult(value);
} catch (Exception ew) {
throw new RpcException("mock return invoke error. method:" + invocation.getMethodName() + ", mock:" + mock + ", url: "+ url , ew);
}
} else if (mock.startsWith(Constants.THROW_PREFIX)) {
mock = mock.substring(Constants.THROW_PREFIX.length()).trim();
mock = mock.replace('`', '"');
if (StringUtils.isBlank(mock)){
throw new RpcException(" mocked exception for Service degradation. ");
} else { //用户自定义类
Throwable t = getThrowable(mock);
throw new RpcException(RpcException.BIZ_EXCEPTION, t);
}
} else { //impl mock
try {
Invoker<T> invoker = getInvoker(mock);
return invoker.invoke(invocation);
} catch (Throwable t) {
throw new RpcException("Failed to create mock implemention class " + mock , t);
}
}
} //mock=fail:throw
//mock=fail:return
//mock=xx.Service
private String normallizeMock(String mock) {
if (mock == null || mock.trim().length() ==0){
return mock;
} else if (ConfigUtils.isDefault(mock) || "fail".equalsIgnoreCase(mock.trim()) || "force".equalsIgnoreCase(mock.trim())){
mock = url.getServiceInterface()+"Mock";
}
if (mock.startsWith(Constants.FAIL_PREFIX)) {
mock = mock.substring(Constants.FAIL_PREFIX.length()).trim();
} else if (mock.startsWith(Constants.FORCE_PREFIX)) {
mock = mock.substring(Constants.FORCE_PREFIX.length()).trim();
}
return mock;
}

dubbo服务降级(1)的更多相关文章
- Dubbo服务降级设置
dubbo降级服务 dubbo开发中,通常是微服务架构,那么在使用过程中可能会遇到多种问题: 1)多个服务之间可能由于服务没有启动或者网络不通,调用中会出现远程调用失败; 2) 服务请求过大, ...
- dubbo服务降级(2)
dubbo降级服务 使用dubbo在进行服务调用时,可能由于各种原因(服务器宕机/网络超时/并发数太高等),调用中就会出现RpcException,调用失败. 服务降级就是指在由于非业务异常导致的服务 ...
- Dubbo服务降级
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或简单处理,从而释放服务器资源以保证核心业务正常运作或高效运作. 可以通过服务降级功能临时屏蔽某个出错的非关键服务并定义 ...
- 13.1 dubbo服务降级源码解析
从 9.1 客户端发起请求源码 的客户端请求总体流程图中,截取部分如下: //代理发出请求 proxy0.sayHello(String paramString) -->InvokerInvoc ...
- Dubbo 服务降级,失败重试怎么做?
可以通过 dubbo:reference 中设置 mock="return null".mock 的值也可以修 改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名 ...
- (万字好文)Dubbo服务熔断与降级的深入讲解&代码实战
原文链接:(万字好文)Dubbo服务熔断与降级的深入讲解&代码实战 一.Dubbo服务降级实战 1 mock 机制 谈到服务降级,Dubbo 本身就提供了服务降级的机制:而 Dubbo 的服务 ...
- dubbo熔断,限流,服务降级
1 写在前面 1.1 名词解释 consumer表示服务调用方 provider标示服务提供方,dubbo里面一般就这么讲. 下面的A调用B服务,一般是泛指调用B服务里面的一个接口. 1.2 拓扑图 ...
- 5.如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?
作者:中华石杉 面试题 如何基于 dubbo 进行服务治理.服务降级.失败重试以及超时重试? 面试官心理分析 服务治理,这个问题如果问你,其实就是看看你有没有服务治理的思想,因为这个是做过复杂微服务的 ...
- 分布式的几件小事(六)dubbo如何做服务治理、服务降级以及重试
1.服务治理 服务治理主要作用是改变运行时服务的行为和选址逻辑,达到限流,权重配置等目的. ①调用链路自动生成 一个大型的分布式系统,会由大量的服务组成,那么这些服务之间的依赖关系和调用链路会很复杂, ...
随机推荐
- maven+eclpse+jmeter+jenkis
1.maven配置:http://www.cnblogs.com/AlanLee/p/6133189.html 2.在eclipse中创建maven项目:https://jingyan.baidu.c ...
- web攻击之零:WEB攻击及防御技术汇总
一.XSS攻击 [介绍] xss攻击是跨站脚本攻击,例如在表单中提交含有可执行的javascript的内容文本,如果服务器端没有过滤或转义这些脚本,而这些脚本由通过内容的形式发布到了页面上,这个时候如 ...
- Crypto Challenge Set 1解题报告
1.Convert hex to base64 题意:给出一个hex编码过的字符串,将它进行base64加密 解题关键:直接利用base64库函数实现 import base64 str1=" ...
- AngularJs(Part 3)--注册服务
有以下5中方法注册一个AngularJS可以识别的Service value和constant是两个极其简单的方法,只有少数情况下会使用. service已经开始复杂了起来.而factory是我认为既 ...
- css3中变形处理
transfrom功能 在css3 中可以使用transfrom功能实现文字或图像的旋转,缩放,倾斜,移动等变形处理 deg是css3中使用的一种角度单位. 旋转: 使用rotate方法,在参数中加入 ...
- Hive与表操作有关的语句
Hive与表操作有关的语句 1.创建表的语句: Create [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COM ...
- eclipse(java) 使用SQL …
java连接sqlserver2005数据库 首先得下载驱动程序到微软网站下载Microsoft JDBC Driver 4.0 for SQL Server 下载地址 :http://msdn. ...
- POJ 1127 Jack Straws (线段相交)
题意:给定一堆线段,然后有询问,问这两个线段是不是相交,并且如果间接相交也可以. 析:可以用并查集和线段相交来做,也可以用Floyd来做,相交就是一个模板题. 代码如下: #pragma commen ...
- ansible无网络安装openstack(Newton)
概要 apt使用本地源,pip使用本地源 网络环境 物理机环境 网络名 网络地址 VLAN br-ex 192.168.200.250/24 90 br-mgmt 92.0.0.100/24 92 a ...
- Linux之vim常用扩展操作
多窗口编辑 批量注释和自定义注释 显示行号 1.多窗口编辑 2.批量注释和自定义注释 3.显示行号(临时生效) 命令行模式下输入: set nu 显示行号 set nonu 不显示行号