根据Directory我们已经获取到了所有注册到注册中心的Invoker,那如果我们需要做灰度发布,只容许用户访问某一些服务怎么办呢?
这里其实就是Router的功能了,根据路由规则,获取到有效的(可访问的Invoker)。
invokers = router.route(invokers, getConsumerUrl(), invocation)
我们看一下Router接口的实现以及方法
1.ScriptRouter(基本路由),比如:javascript, jruby, groovy 等,通过 type=javascript 参数设置脚本类型,缺省为 javascript。基本不使用
2.MockInvokersSelector(MOCK路由),默认走的是这种,我们在之前的调用中有提到,这里是判断是不是mock调用,如果不是mock调用,去除mockInvoke
public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers,
URL url, final Invocation invocation) throws RpcException {
if (invocation.getAttachments() == null) {
return getNormalInvokers(invokers);
} else {
String value = invocation.getAttachments().get(Constants.INVOCATION_NEED_MOCK);
if (value == null)
return getNormalInvokers(invokers);
else if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
return getMockedInvokers(invokers);
}
}
return invokers;
}
//获取正常Invoker,去除mockInvoker
private <T> List<Invoker<T>> getNormalInvokers(final List<Invoker<T>> invokers) {
if (!hasMockProviders(invokers)) {
return invokers;
} else {
List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(invokers.size());
for (Invoker<T> invoker : invokers) {
if (!invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
sInvokers.add(invoker);
}
}
return sInvokers;
}
}
//获取mockInvoker,去除正常Invoker
private <T> List<Invoker<T>> getMockedInvokers(final List<Invoker<T>> invokers) {
if (!hasMockProviders(invo