【sentinel】深入浅出之原理篇协议拓展dubbo,grpc,web-servlet

Sentinel的项目中,有一个拓展的module,里面提供了对dubbo,grpc,webServlet以及其他协议的支持。

协议支持

而在duobbo协议的支持中,实质是实现了Dubbo的Filter接口对接口做扩展。
消费端:

  • resourceName为调用接口类名,方法名,和参数类型拼接起来的字符串
  • 两个entry分为是接口名和resourceName,可以对对外提供的接口,或者方法做控制。
    dubbo
@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实现。

你可能感兴趣的:(【sentinel】深入浅出之原理篇协议拓展dubbo,grpc,web-servlet)