zoukankan      html  css  js  c++  java
  • dubbo服务降级

    转:

    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
  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/libin6505/p/11270147.html
Copyright © 2011-2022 走看看