Producer如何接受请求
有以下重要问题
- 怎么将HTTP请求映射到Controller方法调用的;
- CSE提供的各种扩展,如HttpServerFilter,Handler是如何嵌入到处理流程的;
HttpServer创建
CSE使用Vertx创建HttpServer,入口类为VertxRestTransport。
1、org.apache.servicecomb.transport.rest.vertx.VertxRestTransport.init()方法如下:
@Override
public boolean init() throws Exception {
restClient = RestTransportClientManager.INSTANCE.getRestClient();
// 部署transport server
DeploymentOptions options = new DeploymentOptions().setInstances(TransportConfig.getThreadCount()); // 新建rest请求的client
SimpleJsonObject json = new SimpleJsonObject();
json.put(ENDPOINT_KEY, getEndpoint());
json.put(RestTransportClient.class.getName(), restClient);
options.setConfig(json);
return VertxUtils.blockDeploy(transportVertx, TransportConfig.getRestServerVerticle(), options);
}
2、所有的请求走到VertxRestDispatcher.onRequest方法进行处理:
protected void onRequest(RoutingContext context) {
if (transport == null) {
transport = CseContext.getInstance().getTransportManager().findTransport(Const.RESTFUL);
}
HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context); // 新建请求对象
HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response()); // 新建响应对象
VertxRestInvocation vertxRestInvocation = new VertxRestInvocation();
context.put(RestConst.REST_PRODUCER_INVOCATION, vertxRestInvocation);
vertxRestInvocation.invoke(transport, requestEx, responseEx, httpServerFilters); // 请求的处理
}
context的信息如下:

requestEx的信息如下:

responseEx的信息如下:

3、org.apache.servicecomb.common.rest.RestProducerInvocation.invoke()方法如下:
public void invoke(Transport transport, HttpServletRequestEx requestEx, HttpServletResponseEx responseEx, List<HttpServerFilter> httpServerFilters) {
this.transport = transport;
this.requestEx = requestEx;
this.responseEx = responseEx;
this.httpServerFilters = httpServerFilters;
requestEx.setAttribute("servicecomb-rest-request", requestEx); // 其中放入requestEx的引用
try {
this.findRestOperation();
} catch (InvocationException var6) {
this.sendFailResponse(var6);
return;
}
this.scheduleInvocation();
}
进入RestProducerInvocation.findRestOperation()方法:
protected void findRestOperation() {
MicroserviceMeta selfMicroserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();
this.findRestOperation(selfMicroserviceMeta);
}
selfMicroserviceMeta的内容如下:

4、org.apache.servicecomb.common.rest.AbstractRestInvocation.findRestOperation()方法如下:
protected void findRestOperation(MicroserviceMeta microserviceMeta) {
ServicePathManager servicePathManager = ServicePathManager.getServicePathManager(microserviceMeta); // 获取所有的schema的信息
if (servicePathManager == null) {
LOGGER.error("No schema defined for {}:{}.", microserviceMeta.getAppId(), microserviceMeta.getName());
throw new InvocationException(Status.NOT_FOUND, Status.NOT_FOUND.getReasonPhrase());
} else {
OperationLocator locator = this.locateOperation(servicePathManager); // 定位到具体的处理rest
this.requestEx.setAttribute("servicecomb-paths", locator.getPathVarMap());
this.restOperationMeta = locator.getOperation();
}
}
servicePathManager的参数如下:

locator的参数如下:

此时找到对应的处理rest,下面将请求转发过去。
此时,回到org.apache.servicecomb.common.rest.RestProducerInvocation.invoke()方法:
public void invoke(Transport transport, HttpServletRequestEx requestEx, HttpServletResponseEx responseEx, List<HttpServerFilter> httpServerFilters) {
this.transport = transport;
this.requestEx = requestEx;
this.responseEx = responseEx;
this.httpServerFilters = httpServerFilters;
requestEx.setAttribute("servicecomb-rest-request", requestEx);
try {
this.findRestOperation();
} catch (InvocationException var6) {
this.sendFailResponse(var6);
return;
}
this.scheduleInvocation(); // 下一步,进行请求的处理
}
5、进入org.apache.servicecomb.common.rest.AbstractRestInvocation.scheduleInvocation()方法:
protected void scheduleInvocation() {
try {
this.createInvocation(); // 创建invovation对象属性
} catch (Throwable var6) {
this.sendFailResponse(var6);
return;
}
this.invocation.onStart(this.requestEx, this.start);
this.invocation.getInvocationStageTrace().startSchedule(); // 初始化InvocationStageTrace.startSchedule变量为当前时间
OperationMeta operationMeta = this.restOperationMeta.getOperationMeta();
try {
this.setContext();
} catch (Exception var5) {
LOGGER.error("failed to set invocation context", var5);
this.sendFailResponse(var5);
return;
}
Holder<Boolean> qpsFlowControlReject = this.checkQpsFlowControl(operationMeta);
if (!(Boolean)qpsFlowControlReject.value) {
try {
operationMeta.getExecutor().execute(() -> {
synchronized(this.requestEx) {
try {
if (this.isInQueueTimeout()) { // 判断是否已经超时
throw new InvocationException(Status.INTERNAL_SERVER_ERROR, "Timeout when processing the request.");
}
if (this.requestEx.getAttribute("servicecomb-rest-request") != this.requestEx) {
LOGGER.error("Rest request already timeout, abandon execute, method {}, operation {}.", operationMeta.getHttpMethod(), operationMeta.getMicroserviceQualifiedName());
return;
}
this.runOnExecutor();
} catch (Throwable var5) {
LOGGER.error("rest server onRequest error", var5);
this.sendFailResponse(var5);
}
}
});
} catch (Throwable var4) {
LOGGER.error("failed to schedule invocation, message={}, executor={}.", var4.getMessage(), var4.getClass().getName());
this.sendFailResponse(var4);
}
}
}
6、创建invocation的方法如下:
protected void createInvocation() {
super.createInvocation();
((VertxServerRequestToHttpServletRequest)this.requestEx).getContext().put("servicecomb-rest-invocation-context", this.invocation);
}
invocation的参数内容如下:

7、调用org.apache.servicecomb.core.Invocation.onStart()方法
public void onStart(HttpServletRequestEx requestEx, long start) {
this.requestEx = requestEx;
this.onStart(start);
}
public void onStart(long start) {
this.invocationStageTrace.start(start); // InvocationStageTrace为处理过程的追踪类
this.initTraceId(); // 生成traceid
EventManager.post(new InvocationStartEvent(this)); // 发送InvocationStartEvent事件
}
8、AbstractRestInvocation.setContext()方法如下:
protected void setContext() throws Exception {
String strCseContext = this.requestEx.getHeader("x-cse-context");
if (!StringUtils.isEmpty(strCseContext)) {
Map<String, String> cseContext = (Map)JsonUtils.readValue(strCseContext.getBytes(StandardCharsets.UTF_8), Map.class);
this.invocation.mergeContext(cseContext); // 将header中的x-cse-context的信息合并入InvocationContext的context对象中
}
}
9、AbstractRestInvocation.checkQpsFlowControl进行流控:
private Holder<Boolean> checkQpsFlowControl(OperationMeta operationMeta) {
Holder<Boolean> qpsFlowControlReject = new Holder(false);
Handler providerQpsFlowControlHandler = operationMeta.getProviderQpsFlowControlHandler();
if (null != providerQpsFlowControlHandler) {
try {
providerQpsFlowControlHandler.handle(this.invocation, (response) -> {
qpsFlowControlReject.value = true;
this.produceProcessor = ProduceProcessorManager.JSON_PROCESSOR;
this.sendResponse(response);
});
} catch (Throwable var5) {
LOGGER.error("failed to execute ProviderQpsFlowControlHandler", var5);
qpsFlowControlReject.value = true;
this.sendFailResponse(var5);
}
}
return qpsFlowControlReject;
}
operationMeta的信息如下:

如果设置对应的Qps的限制的handler,会在此处生效,返回结果为是否拒绝对应的请求。
10、operationMeta.getExecutor().execute获取对应的处理线程进行请求的异步处理
对应的线程池信息如下:

首先判断请求是否已经超时:
private boolean isInQueueTimeout() {
return System.nanoTime() - this.invocation.getInvocationStageTrace().getStart() > this.invocation.getOperationMeta().getConfig().getNanoRestRequestWaitInPoolTimeout();
}
this.requestEx.getAttribute("servicecomb-rest-request") != this.requestEx判断当前的请求的请求信息是否还在,请求信息是否已经被抛弃。
11、进入请求的处理方法AbstractRestInvocation.runOnExecutor()
protected void runOnExecutor() {
this.invocation.onExecuteStart(); // 重置InvocationStageTrace.startExecution变量的值为当前时间戳
this.invoke();
}
public void invoke() {
try {
Response response = this.prepareInvoke();
if (response != null) { // 如果返回的结果不为null,直接进行返回,不做后续的处理
this.sendResponseQuietly(response);
return;
}
this.doInvoke(); // 处理到对应的方法
} catch (Throwable var2) {
LOGGER.error("unknown rest exception.", var2);
this.sendFailResponse(var2);
}
}
protected Response prepareInvoke() throws Throwable {
this.initProduceProcessor();
this.invocation.getHandlerContext().put("servicecomb-rest-request", this.requestEx);
this.invocation.getInvocationStageTrace().startServerFiltersRequest();
Iterator var1 = this.httpServerFilters.iterator(); // 获取到所有的HttpServerFilters的实现类
while(var1.hasNext()) {
HttpServerFilter filter = (HttpServerFilter)var1.next();
if (filter.enabled()) {
Response response = filter.afterReceiveRequest(this.invocation, this.requestEx); // 依次调用HttpServerFilter的afterReceiveRequest方法
if (response != null) {
return response; // 如果response不为null,返回
}
}
}
return null;
}
12、进入AbstractRestInvocation.doInvoke方法
protected void doInvoke() throws Throwable {
this.invocation.getInvocationStageTrace().startHandlersRequest(); // 将InvovationStageTrace.startHandlersRequest初始化为当前时间戳 this.invocation.next((resp) -> { this.sendResponseQuietly(resp); }); }protected void sendResponseQuietly(Response response) {
if (this.invocation != null) {
this.invocation.getInvocationStageTrace().finishHandlersResponse();
}
try {
this.sendResponse(response);
} catch (Throwable var3) {
LOGGER.error("Failed to send rest response, operation:{}, request uri:{}", new Object[]{this.getMicroserviceQualifiedName(), this.requestEx.getRequestURI(), var3});
}
}
protected void sendResponseQuietly(Response response) {
if (this.invocation != null) {
this.invocation.getInvocationStageTrace().finishHandlersResponse();
}
try {
this.sendResponse(response);
} catch (Throwable var3) {
LOGGER.error("Failed to send rest response, operation:{}, request uri:{}", new Object[]{this.getMicroserviceQualifiedName(), this.requestEx.getRequestURI(), var3});
}
}
13、进入org.apache.servicecomb.core.Invocation.next()方法
public void next(AsyncResponse asyncResp) throws Exception {
int runIndex = this.handlerIndex++;
((Handler)this.handlerList.get(runIndex)).handle(this, asyncResp);
}
this.handlerList为Handler的实现类,当前存在InterceptorHandler,ValidateHandler,ProducerOperationHandler实现,优先级从高到低。
14、进入org.apache.servicecomb.core.handler.impl.ProducerOperationHandler.handle()方法中
public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
SwaggerProducerOperation producerOperation = (SwaggerProducerOperation)invocation.getOperationMeta().getExtData("producer-operation");
if (producerOperation == null) {
asyncResp.producerFail(ExceptionUtils.producerOperationNotExist(invocation.getSchemaId(), invocation.getOperationName()));
} else {
producerOperation.invoke(invocation, asyncResp);
}
}
15、进入org.apache.servicecomb.swagger.engine.SwaggerProducerOperation.invoke()方法
public void invoke(SwaggerInvocation invocation, AsyncResponse asyncResp) {
if (CompletableFuture.class.equals(this.producerMethod.getReturnType())) {
this.completableFutureInvoke(invocation, asyncResp);
} else {
this.syncInvoke(invocation, asyncResp);
}
}
public void syncInvoke(SwaggerInvocation invocation, AsyncResponse asyncResp) {
ContextUtils.setInvocationContext(invocation);
Response response = this.doInvoke(invocation);
ContextUtils.removeInvocationContext();
asyncResp.handle(response);
}
public Response doInvoke(SwaggerInvocation invocation) {
Response response = null;
try {
invocation.onBusinessMethodStart();
Object[] args = this.argumentsMapper.toProducerArgs(invocation);
Iterator var4 = this.producerInvokeExtenstionList.iterator();
while(var4.hasNext()) {
ProducerInvokeExtension producerInvokeExtension = (ProducerInvokeExtension)var4.next();
producerInvokeExtension.beforeMethodInvoke(invocation, this, args);
}
Object result = this.producerMethod.invoke(this.producerInstance, args);
response = this.responseMapper.mapResponse(invocation.getStatus(), result);
invocation.onBusinessMethodFinish();
invocation.onBusinessFinish();
} catch (Throwable var6) {
if (this.shouldPrintErrorLog(var6)) {
LOGGER.error("unexpected error operation={}, message={}", invocation.getInvocationQualifiedName(), ExceptionUtils.getExceptionMessageWithoutTrace(var6));
}
invocation.onBusinessMethodFinish();
invocation.onBusinessFinish();
response = this.processException(invocation, var6);
}
return response;
}
this.producerMethod的参数为

this.producerInstance的参数如下:

args的参数为

this.producerMethod就是目标处理方法的代理对象
private List producerInvokeExtenstionList = SPIServiceUtils.getSortedService(ProducerInvokeExtension.class);实现了处理前的扩展点。