zoukankan      html  css  js  c++  java
  • 解决dubbo问题:forbid consumer(2)

    线下环境经常出现类似这种异常:

    com.alibaba.dubbo.rpc.RpcException: Forbid consumer 10.0.53.69 access service com.kuaidadi.op.api.pay.service.PayChannelConfigRemoteService from registry 10.0.50.150:2181 use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist).

    大致意思是当前调用者被禁止访问某个服务,请检查下注册中心访问列表,还有黑名单和白名单。

    其实线下环境根本没有对服务做白名单和黑名单机制,因为线下环境给开发人员的账号是guest,没有权限做黑白名单。今天有好几个人问我这个问题,我仔细看了源码,找出了根源所在。

    根据异常栈,抛出这个异常的代码在RegistryDirectory的第579行,如下:

    如果forbidden变量为true,则抛出该异常。forbidden变量默认为false,那么什么时候变成true了呢?看RegistryDirectory的这段代码:

    意思是如果invokerUrls的size为1,并且url的协议头是Constants.EMPTY_PROTOCOL时,则设置forbidden为false,Constants.EMPTY_PROTOCOL的值是empty。

    refreshInvoker方法什么时候被调用呢?当某个服务的provider有变化时就会被调用,例如zookeeper上某个服务的provider目录里的内容发生变化,则zk监听器会被触发,由于provider的数量会发生变化,例如有一个新的provider启动了,有一个provider下线了,所以必须刷新本地的对provider的连接,具体逻辑就在refreshInvoker方法里,这个方法的调用栈如下:

    可以确定的是,zookeeper推送的URL的protocol部分不可能无缘无故变成了empty,肯定是由某个地方更改了,于是看一下Constants.EMPTY_PROTOCOL到底有哪些地方调用了,如下:

    见图中红色圈圈部分,当zookeeper初次订阅或者订阅的信息有变更时,都会触发toUrlsChanged方法,看看这个方法内部都做了什么,完整代码如下:

    可见如果toUrlsWithoutEmpty的结果是空或者size为0,则强制返回一个protocol为empty的url,看来源头就在这里了。传入的List<String> providers实际上就是最新的服务提供者信息,当某个服务没有任何provider时,providers就变为一个size为o的List了,导致返回一个协议头为empty的url,进而导致forbidden为true,屏蔽了consumer调用。

  • 相关阅读:
    🍖流程控制之if判断
    🍖Python开发入门之变量
    🍖Python入门之基本数据类型
    sql事务和存储过程 【转】
    《设计模式基于C#的工程化实现及扩展》 Security Design Pattern 系列 4 角色模式(Role Pattern) 【转】
    C#中ToString格式大全 【转】
    事务日志 (SQL Server)【转】
    批处理启动、停止SQL服务 【转】
    关于HttpContext.Current.Request获取值 【转】
    C#中HashTable的用法 【转】
  • 原文地址:https://www.cnblogs.com/austinspark-jessylu/p/7389540.html
Copyright © 2011-2022 走看看