Dubbo中服务降级服务限流限流措施
Posted Leo Han
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo中服务降级服务限流限流措施相关的知识,希望对你有一定的参考价值。
作为一个RPC框架,Dubbo同时提供了兼具微服务的一些服务管理功能:
服务降级、限流
服务降级
Dubbo中服务降级可以通过mock
实现,在消费端,通过配置mock选项,来支持服务降级
如:
@DubboReference(mock = "force:return null")
@DubboReference(mock = "return null")
@DubboReference(mock = "throw") // 抛出 RpcException
@DubboReference(mock = "throw com.xxx.XXXException") // 抛出RpcException,并传入自定义异常
@DubboReference(mock = "com.xxx.XXXServiceImpl") // 实现调用接口,mock时调用该实现对应的接口方法
可以通过如上几种方式,其中force
是强制mock,不管调用的服务是否正常,都走mock流程,其他的都是在调用失败之后走mock。
mock代码实现在MockClusterInvoker
中:
public Result invoke(Invocation invocation) throws RpcException
Result result = null;
String value = getUrl().getMethodParameter(invocation.getMethodName(), MOCK_KEY, Boolean.FALSE.toString()).trim();
if (value.length() == 0 || "false".equalsIgnoreCase(value))
result = this.invoker.invoke(invocation);
else if (value.startsWith("force"))
if (logger.isWarnEnabled())
logger.warn("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + getUrl());
result = doMockInvoke(invocation, null);
else
//fail-mock
try
result = this.invoker.invoke(invocation);
if(result.getException() != null && result.getException() instanceof RpcException)
RpcException rpcException= (RpcException)result.getException();
if(rpcException.isBiz())
throw rpcException;
else
result = doMockInvoke(invocation, rpcException);
catch (RpcException e)
if (e.isBiz())
throw e;
result = doMockInvoke(invocation, e);
return result;
可以看到,对于force
这种mock,不管服务提供方是否正常都走mock,而具体执行mock在MockInvoker
中:
public Result invoke(Invocation invocation) throws RpcException
if (invocation instanceof RpcInvocation)
((RpcInvocation) invocation).setInvoker(this);
String mock = null;
if (getUrl().hasMethodParameter(invocation.getMethodName()))
mock = getUrl().getParameter(invocation.getMethodName() + "." + MOCK_KEY);
if (StringUtils.isBlank(mock))
mock = getUrl().getParameter(MOCK_KEY);
if (StringUtils.isBlank(mock))
throw new RpcException(new IllegalAccessException("mock can not be null. url :" + url));
mock = normalizeMock(URL.decode(mock));
if (mock.startsWith(RETURN_PREFIX))
mock = mock.substring(RETURN_PREFIX.length()).trim();
try
Type[] returnTypes = RpcUtils.getReturnTypes(invocation);
Object value = parseMockValue(mock, returnTypes);
return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
catch (Exception ew)
throw new RpcException("mock return invoke error. method :" + invocation.getMethodName()
+ ", mock:" + mock + ", url: " + url, ew);
else if (mock.startsWith(THROW_PREFIX))
mock = mock.substring(THROW_PREFIX.length()).trim();
if (StringUtils.isBlank(mock))
throw new RpcException("mocked exception for service degradation.");
else // user customized class
Throwable t = getThrowable(mock);
throw new RpcException(RpcException.BIZ_EXCEPTION, t);
else
try
Invoker<T> invoker = getInvoker(mock);
return invoker.invoke(invocation);
catch (Throwable t)
throw new RpcException("Failed to create mock implementation class " + mock, t);
服务限流
服务限流,为了防止服务的QPS突然飙升或者太大导致服务频繁失败甚至崩溃重启,对一些重要服务进行限流,虽然会导致一些请求失败,但是能够保证服务平稳运行
Dubbo中的限流有如下几个措施:
accepts:
限制服务器端接受的连接数
,对于服务提供方,Dubbo默认基于Netty协议的底层网络可以限制客户端连接数量进行限制dubbo.protocol.accepts=10
或者dubbo.provider.accepts=10
只能在服务提供端
connections:
限制客户端服务使用连接数
,使用@DubboReference(connections = 10)
或者
@DubboService(connections = 10)
作用在接口或方法级别上,如果两个都有,@DubboReference(connections = 10)
优先
executes
:服务提供者并发限制,作用在服务提供者接口或者方法上
,@DubboService(connections = 10,executes = 10)
或@Method(executes = 10)
,Dubbo中会根据接口或者方法上的该配置,然后在每次执行方法前,会判断当前接口或者方法并行的数量是否大于该值,如果大于抛出异常,否则当前接口和方法active+1.在ExecuteLimitFilter
实现了该过滤处理
actives
:与executes
类似,但是可以作用在服务提供者和消费者的接口或方法上,但是不同于executes
不同的是,这里是表示同事能够活跃的处理数,如果超过该值,则需要等待timeout
ms,超时则抛出异常,在ActiveLimitFilter
实现了active处理
以上是关于Dubbo中服务降级服务限流限流措施的主要内容,如果未能解决你的问题,请参考以下文章