-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dubbo-admin同时对多个ip进行黑名单访问控制无效 #181
Comments
路由的时候遇到相同的问题,后面换用IP段来路由。 |
确实,com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouter.MatchPair#isMatch 这个方法判断是否匹配有问题 |
通过自定RouterFactory拓展点可以解决此问题,如下是本人的解决方案:
public class MyConditionRouterFactory implements RouterFactory {
public static final String NAME = "myCondition";
public Router getRouter(URL url) {
return new MyConditionRouter(url);
}
}
...
private static final class MatchPair {
final Set<String> matches = new HashSet<String>();
final Set<String> mismatches = new HashSet<String>();
public boolean isMatch(String value, URL param) {
for (String mismatch : mismatches) {
if (UrlUtils.isMatchGlobPattern(mismatch, value, param)) {
return false;
}
}
if (matches.isEmpty()) return true;
//这里只要任意个匹配,直接返回,形如 application=myConsumer => host = 127.0.0.1,127.0.0.2
for (String match : matches) {
if (UrlUtils.isMatchGlobPattern(match, value, param)) {
return true;
}
}
return false;
}
}
...
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://xxx:2181"));
//注意这里改为myCondition(协议?^_^)
final URL url = URL.valueOf("myCondition://0.0.0.0/xxx.DemoService?category=routers&force=true&enabled=true&dynamic=false&rule=" +
URL.encode("application = myConsumer => host = 127.0.0.1,127.0.0.2"));
registry.register(url); 以上 |
方案二:基于script的路由,思路与myCondition路由大同小异,这是在不改任何源代码的方式来实现(dubbo的script路由很灵活),定义如下: RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://xxx:2181"));
String script = "(function route(invokers,invocation){var routeApp='myConsumer';var routeHosts='127.0.0.1,127.0.0.2'.split(',');var result=new java.util.ArrayList();for(var i=0;i<invokers.size();i++){var url=invokers.get(i).getUrl();if(url.getParameter('application')!==routeApp){result.add(invokers.get(i))}else if(routeHosts.indexOf(url.getHost())>=0){result.add(invokers.get(i))}}return result}(invokers,invocation));";
URL url = URL.valueOf("script://0.0.0.0/xxx.DemoService?category=routers&force=true&enabled=true&dynamic=false&type=javascript&rule=" + URL.encode(script));
registry.register(url); ps (function route(invokers, invocation) {
var routeApp = 'myConsumer';
var routeHosts = '127.0.0.1,127.0.0.2'.split(',');
var result = new java.util.ArrayList();
for (var i = 0; i < invokers.size(); i++) {
var url = invokers.get(i).getUrl();
if (url.getParameter('application') !== routeApp) {
result.add(invokers.get(i));
} else if (routeHosts.indexOf(url.getHost()) >= 0) {
result.add(invokers.get(i));
}
}
return result;
}(invokers, invocation)); |
相当于是推了个js脚本到zookeeper中下发,从ip规则转为脚本规则。 感觉还是升级大法好,哈哈 |
在dubbo-admin中对一个服务可以按ip进行访问控制,测试中发现只禁用一个ip才有效果,但是同时禁用多个ip则会整个禁用控制失效,经跟踪代码发现com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouter.java里的
private static final class MatchPair { final Set<String> matches = new HashSet<String>(); final Set<String> mismatches = new HashSet<String>(); public boolean isMatch(String value, URL param) { for (String match : matches) { if (! UrlUtils.isMatchGlobPattern(match, value, param)) { return false; } } for (String mismatch : mismatches) { if (UrlUtils.isMatchGlobPattern(mismatch, value, param)) { return false; } } return true; } }
ismacth方法,当有多个不同的ip禁用时,如上代码所示,只要有一个match值与value不一致,就会返回false,从而使需要禁用的ip也能匹配失败。
The text was updated successfully, but these errors were encountered: