在Sentinel
的项目中,有一个拓展的module,里面提供了对dubbo,grpc,webServlet以及其他协议的支持。
而在duobbo协议的支持中,实质是实现了Dubbo的Filter接口对接口做扩展。
消费端:
resourceName为调用接口类名,方法名,和参数类型拼接起来的字符串
-
两个entry分为是接口名和resourceName,可以对对外提供的接口,或者方法做控制。
@Activate(group = "consumer")
public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements Filter {
public SentinelDubboConsumerFilter() {
RecordLog.info("Sentinel Dubbo consumer filter initialized");
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
Entry interfaceEntry = null;
Entry methodEntry = null;
try {
String resourceName = getResourceName(invoker, invocation);
interfaceEntry = SphU.entry(invoker.getInterface().getName(), EntryType.OUT);
methodEntry = SphU.entry(resourceName, EntryType.OUT);
Result result = invoker.invoke(invocation);
if (result.hasException()) {
// Record common exception.
Tracer.trace(result.getException());
}
return result;
} catch (BlockException e) {
return DubboFallbackRegistry.getConsumerFallback().handle(invoker, invocation, e);
} catch (RpcException e) {
Tracer.trace(e);
throw e;
} finally {
if (methodEntry != null) {
methodEntry.exit();
}
if (interfaceEntry != null) {
interfaceEntry.exit();
}
}
}
}
protected String getResourceName(Invoker<?> invoker, Invocation invocation) {
StringBuilder buf = new StringBuilder(64);
buf.append(invoker.getInterface().getName())
.append(":")
.append(invocation.getMethodName())
.append("(");
boolean isFirst = true;
for (Class<?> clazz : invocation.getParameterTypes()) {
if (!isFirst) {
buf.append(",");
}
buf.append(clazz.getName());
isFirst = false;
}
buf.append(")");
return buf.toString();
}
服务端其他都一样,只是在请求进入后,创建Context的时候,增加了origin。系统来源,来区分是来自哪个系统的流量。
//SentinelDubboProviderFilter.java
String application = DubboUtils.getApplication(invocation, "");
String resourceName = getResourceName(invoker, invocation);
String interfaceName = invoker.getInterface().getName();
ContextUtil.enter(resourceName, application);
interfaceEntry = SphU.entry(interfaceName, EntryType.IN);
methodEntry = SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments());
Result result = invoker.invoke(invocation);
orgin的系统来源来自于dubbo的隐式传参
@Activate(group = "consumer")
public class DubboAppContextFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY);
if (application != null) {
RpcContext.getContext().setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, application);
}
return invoker.invoke(invocation);
}
}
其他类似dubbo,web-servlet也是基于filter实现。