Edge
顾名思义,边缘,是外部流量的入口,因此在edge可以做一些通用流量治理和统一鉴权的事情。
ServiceComb自带的3个Edge Dispatcher,可以满足大部分需求,当然开发者也可以自定义Dispatcher,自带的Dispatcher如下:
org.apache.servicecomb.edge.core.DefaultEdgeDispatcher
org.apache.servicecomb.edge.core.URLMappedEdgeDispatcher
org.apache.servicecomb.edge.core.CommonHttpEdgeDispatcher
如何配置可以参考项目demo中的demo-edge
1.重要类的继承关系
2.consumer、producer、edge调用链,来自InvocationStageTrace类注释
以demo-edge为例
edge调用链:
EncryptEdgeDispatcher->edgeInvocation.edgeInvoke()->创建Invocation (InvocationFactory.forConsumer)->Hanlder列表:
AuthHandler
LoadbalanceHandler
TransportClientHandler
consumer调用链:
CseClientHttpRequest -> 创建Invocation (InvocationFactory.forConsumer)->Hanlder列表:
LoadbalanceHandler
TransportClientHandler
Producer调用链:
VertxRestDispatcher->VertxRestInvocation->创建Invocation (InvocationFactory.forProvider)->Handler链:
ProducerOperationHandler
运行态线程分析
edge处理过程,都是在eventloop线程进行,那么是如何实现的呢
1.以demo-edge为例,首先我们看到,有新的请求过来,进入EncryptEdgeDispatcher,此时是执行是在eventloop中
2.接着进入EncryptEdgeInvocation 的edgeInvoke方法,最终到operationMeta.getExecutor().execute()中执行,debug一看,还是在eventloop线程执行。那么operationMeta的Executor是如何设置为eventloop线程的呢?
如下是跟踪OperationMeta创建过程,
得知,OperationMeta的Executor来自:
this.executor = schemaMeta.getMicroserviceMeta().getScbEngine().getExecutorManager().findExecutor(this);
ExecutorManager找excutor,最终找到是ReactiveExecutor,这个Excutor是在eventloop线程就地执行。
// ExecutorManager找excutor
public Executor findExecutor(OperationMeta operationMeta, Executor defaultOperationExecutor) {
...
// 寻找config-key指定的default
executor = findByKey(KEY_EXECUTORS_DEFAULT);
if (executor != null) {
return executor;
}
...
}
// EdgeBootListener的KEY_EXECUTORS_DEFAULT配置
public void onBootEvent(BootEvent event) {
...
configuration.setProperty(ExecutorManager.KEY_EXECUTORS_DEFAULT, ExecutorManager.EXECUTOR_REACTIVE);
}
// ExecutorManager 的EXECUTOR_REACTIVE设置,是ReactiveExecutor
public ExecutorManager() {
registerExecutor(EXECUTOR_REACTIVE, new ReactiveExecutor());
}
// ExecutorManager从executors获取EXECUTOR_REACTIVE
public Executor findExecutorById(String id) {
Executor executor = executors.get(id);
}
Edge调用超时设置
由于edge都是在eventloop进行,不能耗时过长,因此设置了超时时间。isInQueueTimeout,默认30s
// AbstractRestInvocation
try {
operationMeta.getExecutor().execute(() -> {
synchronized (this.requestEx) {
try {
if (isInQueueTimeout()) {
throw new InvocationException(Status.INTERNAL_SERVER_ERROR, "Timeout when processing the request.");
}
// 超时配置nanoRestRequestWaitInPoolTimeout,在OperationConfig的setMsRestRequestWaitInPoolTimeout
public void setMsRestRequestWaitInPoolTimeout(long msRestRequestWaitInPoolTimeout) {
this.msRestRequestWaitInPoolTimeout = msRestRequestWaitInPoolTimeout;
this.nanoRestRequestWaitInPoolTimeout = TimeUnit.MILLISECONDS.toNanos(msRestRequestWaitInPoolTimeout);
registerRequestWaitInPoolTimeout(Const.RESTFUL, msRestRequestWaitInPoolTimeout);
}
// setMsRestRequestWaitInPoolTimeout的调用,经过InjectProperty注入,默认值是30000毫秒,30秒
@InjectProperty(keys = {
"Provider.requestWaitInPoolTimeout${op-priority}",
"rest.server.requestWaitInPoolTimeout"}, defaultValue = "30000")
private long msRestRequestWaitInPoolTimeout;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。