Search in sources :

Example 1 with ServerReceiveEvent

use of com.alipay.sofa.rpc.event.ServerReceiveEvent in project sofa-rpc by sofastack.

the class BoltServerProcessor method handleRequest.

@Override
public void handleRequest(BizContext bizCtx, AsyncContext asyncCtx, SofaRequest request) {
    // RPC内置上下文
    RpcInternalContext context = RpcInternalContext.getContext();
    context.setProviderSide(true);
    String appName = request.getTargetAppName();
    if (appName == null) {
        // 默认全局appName
        appName = (String) RpcRuntimeContext.get(RpcRuntimeContext.KEY_APPNAME);
    }
    // 是否链路异步化中
    boolean isAsyncChain = false;
    try {
        // 这个 try-finally 为了保证Context一定被清理
        // 统计值加1
        processingCount.incrementAndGet();
        // 远程地址
        context.setRemoteAddress(bizCtx.getRemoteHost(), bizCtx.getRemotePort());
        // 远程返回的通道
        context.setAttachment(RpcConstants.HIDDEN_KEY_ASYNC_CONTEXT, asyncCtx);
        InvokeContext boltInvokeCtx = bizCtx.getInvokeContext();
        if (RpcInternalContext.isAttachmentEnable()) {
            if (boltInvokeCtx != null) {
                // rpc线程池等待时间 Long
                putToContextIfNotNull(boltInvokeCtx, InvokeContext.BOLT_PROCESS_WAIT_TIME, context, RpcConstants.INTERNAL_KEY_PROCESS_WAIT_TIME);
            }
        }
        putToContext(boltInvokeCtx);
        if (EventBus.isEnable(ServerReceiveEvent.class)) {
            EventBus.post(new ServerReceiveEvent(request));
        }
        // 开始处理
        // 响应,用于返回
        SofaResponse response = null;
        // 异常,用于记录
        Throwable throwable = null;
        ProviderConfig providerConfig = null;
        String serviceName = request.getTargetServiceUniqueName();
        try {
            // 这个try-catch 保证一定有Response
            invoke: {
                if (!boltServer.isStarted()) {
                    // 服务端已关闭
                    throwable = new SofaRpcException(RpcErrorType.SERVER_CLOSED, LogCodes.getLog(LogCodes.WARN_PROVIDER_STOPPED, SystemInfo.getLocalHost() + ":" + boltServer.serverConfig.getPort()));
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    break invoke;
                }
                if (bizCtx.isRequestTimeout()) {
                    // 加上丢弃超时的请求的逻辑
                    throwable = clientTimeoutWhenReceiveRequest(appName, serviceName, bizCtx.getRemoteAddress());
                    break invoke;
                }
                // 查找服务
                Invoker invoker = boltServer.findInvoker(serviceName);
                if (invoker == null) {
                    throwable = cannotFoundService(appName, serviceName);
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    break invoke;
                }
                if (invoker instanceof ProviderProxyInvoker) {
                    providerConfig = ((ProviderProxyInvoker) invoker).getProviderConfig();
                    // 找到服务后,打印服务的appName
                    appName = providerConfig != null ? providerConfig.getAppName() : null;
                }
                // 查找方法
                String methodName = request.getMethodName();
                Method serviceMethod = ReflectCache.getOverloadMethodCache(serviceName, methodName, request.getMethodArgSigs());
                if (serviceMethod == null) {
                    throwable = cannotFoundServiceMethod(appName, methodName, serviceName);
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    break invoke;
                } else {
                    request.setMethod(serviceMethod);
                }
                // 真正调用
                response = doInvoke(serviceName, invoker, request);
                if (bizCtx.isRequestTimeout()) {
                    // 加上丢弃超时的响应的逻辑
                    throwable = clientTimeoutWhenSendResponse(appName, serviceName, bizCtx.getRemoteAddress());
                    break invoke;
                }
            }
        } catch (Exception e) {
            // 服务端异常,不管是啥异常
            LOGGER.errorWithApp(appName, "Server Processor Error!", e);
            throwable = e;
            response = MessageBuilder.buildSofaErrorResponse(e.getMessage());
        }
        // Response不为空,代表需要返回给客户端
        if (response != null) {
            RpcInvokeContext invokeContext = RpcInvokeContext.peekContext();
            isAsyncChain = CommonUtils.isTrue(invokeContext != null ? (Boolean) invokeContext.remove(RemotingConstants.INVOKE_CTX_IS_ASYNC_CHAIN) : null);
            // 如果是服务端异步代理模式,特殊处理,因为该模式是在业务代码自主异步返回的
            if (!isAsyncChain) {
                // 其它正常请求
                try {
                    // 这个try-catch 保证一定要记录tracer
                    asyncCtx.sendResponse(response);
                } finally {
                    if (EventBus.isEnable(ServerSendEvent.class)) {
                        EventBus.post(new ServerSendEvent(request, response, throwable));
                    }
                }
            }
        }
    } catch (Throwable e) {
        // 可能有返回时的异常
        if (LOGGER.isErrorEnabled(appName)) {
            LOGGER.errorWithApp(appName, e.getMessage(), e);
        }
    } finally {
        processingCount.decrementAndGet();
        if (!isAsyncChain) {
            if (EventBus.isEnable(ServerEndHandleEvent.class)) {
                EventBus.post(new ServerEndHandleEvent());
            }
        }
        RpcInvokeContext.removeContext();
        RpcInternalContext.removeAllContext();
    }
}
Also used : InvokeContext(com.alipay.remoting.InvokeContext) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) ServerSendEvent(com.alipay.sofa.rpc.event.ServerSendEvent) ProviderConfig(com.alipay.sofa.rpc.config.ProviderConfig) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext) ServerEndHandleEvent(com.alipay.sofa.rpc.event.ServerEndHandleEvent) Method(java.lang.reflect.Method) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) ProviderProxyInvoker(com.alipay.sofa.rpc.server.ProviderProxyInvoker) Invoker(com.alipay.sofa.rpc.invoke.Invoker) ProviderProxyInvoker(com.alipay.sofa.rpc.server.ProviderProxyInvoker) ServerReceiveEvent(com.alipay.sofa.rpc.event.ServerReceiveEvent) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse)

Example 2 with ServerReceiveEvent

use of com.alipay.sofa.rpc.event.ServerReceiveEvent in project sofa-rpc by sofastack.

the class TripleTracerAdapter method serverReceived.

/**
 * 适配服务端serverReceived
 */
public static void serverReceived(SofaRequest sofaRequest, ServerServiceDefinition serverServiceDefinition, final ServerCall call, Metadata requestHeaders) {
    try {
        if (sofaRequest == null) {
            sofaRequest = new SofaRequest();
        }
        Map<String, String> traceMap = new HashMap<String, String>();
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_TARGET_SERVICE)) {
            sofaRequest.setTargetServiceUniqueName(requestHeaders.get(TripleHeadKeys.HEAD_KEY_TARGET_SERVICE));
            sofaRequest.setInterfaceName(requestHeaders.get(TripleHeadKeys.HEAD_KEY_TARGET_SERVICE));
        } else {
            String serviceName = serverServiceDefinition.getServiceDescriptor().getName();
            sofaRequest.setTargetServiceUniqueName(serviceName);
            sofaRequest.setInterfaceName(serviceName);
        }
        final String serviceName = call.getMethodDescriptor().getServiceName();
        sofaRequest.setTargetServiceUniqueName(serviceName);
        sofaRequest.setInterfaceName(serviceName);
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_TARGET_APP)) {
            sofaRequest.setTargetAppName(requestHeaders.get(TripleHeadKeys.HEAD_KEY_TARGET_APP));
        }
        // 先取兼容的
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_OLD_TRACE_ID)) {
            traceMap.put(TracerCompatibleConstants.TRACE_ID_KEY, requestHeaders.get(TripleHeadKeys.HEAD_KEY_OLD_TRACE_ID));
        } else if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_TRACE_ID)) {
            traceMap.put(TracerCompatibleConstants.TRACE_ID_KEY, requestHeaders.get(TripleHeadKeys.HEAD_KEY_TRACE_ID));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_OLD_RPC_ID)) {
            traceMap.put(TracerCompatibleConstants.RPC_ID_KEY, requestHeaders.get(TripleHeadKeys.HEAD_KEY_OLD_RPC_ID));
        } else if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_RPC_ID)) {
            traceMap.put(TracerCompatibleConstants.RPC_ID_KEY, requestHeaders.get(TripleHeadKeys.HEAD_KEY_RPC_ID));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_SERVICE_VERSION)) {
            RpcInvokeContext.getContext().put(TripleContants.SOFA_UNIQUE_ID, requestHeaders.get(TripleHeadKeys.HEAD_KEY_SERVICE_VERSION));
        } else {
            RpcInvokeContext.getContext().put(TripleContants.SOFA_UNIQUE_ID, "");
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_SAMP_TYPE)) {
            traceMap.put(TracerCompatibleConstants.SAMPLING_MARK, requestHeaders.get(TripleHeadKeys.HEAD_KEY_SAMP_TYPE));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_CURRENT_APP)) {
            sofaRequest.addRequestProp(HEAD_APP_NAME, requestHeaders.get(TripleHeadKeys.HEAD_KEY_CURRENT_APP));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_PROTOCOL_TYPE)) {
            sofaRequest.addRequestProp(RemotingConstants.HEAD_PROTOCOL, requestHeaders.get(TripleHeadKeys.HEAD_KEY_PROTOCOL_TYPE));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_INVOKE_TYPE)) {
            sofaRequest.addRequestProp(RemotingConstants.HEAD_INVOKE_TYPE, requestHeaders.get(TripleHeadKeys.HEAD_KEY_INVOKE_TYPE));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_BIZ_BAGGAGE_TYPE)) {
            traceMap.put(TracerCompatibleConstants.PEN_ATTRS_KEY, requestHeaders.get(TripleHeadKeys.HEAD_KEY_BIZ_BAGGAGE_TYPE));
        }
        if (requestHeaders.containsKey(TripleHeadKeys.HEAD_KEY_SYS_BAGGAGE_TYPE)) {
            traceMap.put(TracerCompatibleConstants.PEN_SYS_ATTRS_KEY, requestHeaders.get(TripleHeadKeys.HEAD_KEY_SYS_BAGGAGE_TYPE));
        }
        if (!traceMap.isEmpty()) {
            sofaRequest.addRequestProp(RemotingConstants.RPC_TRACE_NAME, traceMap);
        }
        if (EventBus.isEnable(ServerReceiveEvent.class)) {
            EventBus.post(new ServerReceiveEvent(sofaRequest));
        }
        String remoteIp = "";
        SocketAddress socketAddress = call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
        if (socketAddress instanceof InetSocketAddress) {
            remoteIp = ((InetSocketAddress) socketAddress).getHostName();
        }
        String methodName;
        String fullMethodName = call.getMethodDescriptor().getFullMethodName();
        methodName = StringUtils.substringAfter(fullMethodName, serviceName + "/");
        sofaRequest.setMethodName(methodName);
        SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
        SofaTracerSpan serverSpan = sofaTraceContext.getCurrentSpan();
        if (serverSpan != null) {
            // FIXME modify the dep relation
            serverSpan.setTag("service", sofaRequest.getTargetServiceUniqueName());
            serverSpan.setTag("method", methodName);
            // 从请求里获取ConsumerTracerFilter额外传递的信息
            serverSpan.setTag("remote.app", (String) sofaRequest.getRequestProp(HEAD_APP_NAME));
            serverSpan.setTag("protocol", RpcConstants.PROTOCOL_TYPE_TRIPLE);
            serverSpan.setTag("remote.ip", remoteIp);
        }
    } catch (Throwable e) {
        LOGGER.warn("triple serverReceived tracer error", e);
    }
}
Also used : SofaTracerSpan(com.alipay.common.tracer.core.span.SofaTracerSpan) SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) HashMap(java.util.HashMap) SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext) InetSocketAddress(java.net.InetSocketAddress) ServerReceiveEvent(com.alipay.sofa.rpc.event.ServerReceiveEvent) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress)

Example 3 with ServerReceiveEvent

use of com.alipay.sofa.rpc.event.ServerReceiveEvent in project sofa-rpc by sofastack.

the class AbstractHttpServerTask method run.

@Override
public void run() {
    // RPC内置上下文
    RpcInternalContext context = RpcInternalContext.getContext();
    context.setProviderSide(true);
    String appName = request.getTargetAppName();
    if (appName == null) {
        // 默认全局appName
        appName = (String) RpcRuntimeContext.get(RpcRuntimeContext.KEY_APPNAME);
    }
    try {
        // 这个 try-finally 为了保证Context一定被清理
        Channel channel = ctx.channel();
        // 远程地址
        context.setRemoteAddress((InetSocketAddress) channel.remoteAddress());
        // 远程返回的通道
        context.setAttachment(RpcConstants.HIDDEN_KEY_ASYNC_CONTEXT, channel);
        if (EventBus.isEnable(ServerReceiveEvent.class)) {
            EventBus.post(new ServerReceiveEvent(request));
        }
        // 开始处理
        // 响应,用于返回
        SofaResponse response = null;
        // 异常,用于记录
        Throwable throwable = null;
        HttpResponseStatus status = null;
        ProviderConfig providerConfig = null;
        String serviceName = request.getTargetServiceUniqueName();
        Serializer serializer = null;
        if (request.getSerializeType() > 0) {
            serializer = SerializerFactory.getSerializer(request.getSerializeType());
        }
        try {
            // 这个try-catch 保证一定有Response
            invoke: {
                // 查找服务
                Invoker invoker = serverHandler.getInvokerMap().get(serviceName);
                if (invoker == null) {
                    throwable = cannotFoundService(appName, serviceName);
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    status = HttpResponseStatus.NOT_FOUND;
                    break invoke;
                }
                if (invoker instanceof ProviderProxyInvoker) {
                    providerConfig = ((ProviderProxyInvoker) invoker).getProviderConfig();
                    // 找到服务后,打印服务的appName
                    appName = providerConfig != null ? providerConfig.getAppName() : null;
                }
                // 查找方法
                String methodName = request.getMethodName();
                Method serviceMethod = serverHandler.getMethod(serviceName, methodName);
                if (serviceMethod == null) {
                    throwable = cannotFoundServiceMethod(appName, methodName, serviceName);
                    response = MessageBuilder.buildSofaErrorResponse(throwable.getMessage());
                    status = HttpResponseStatus.NOT_FOUND;
                    break invoke;
                } else {
                    request.setMethod(serviceMethod);
                }
                AbstractByteBuf reqData = request.getData();
                if (reqData != null) {
                    try {
                        Map<String, String> map = new HashMap<String, String>(4);
                        map.put(RemotingConstants.HEAD_TARGET_SERVICE, request.getTargetServiceUniqueName());
                        map.put(RemotingConstants.HEAD_METHOD_NAME, request.getMethodName());
                        map.put(RemotingConstants.HEAD_TARGET_APP, request.getTargetAppName());
                        serializer.decode(reqData, request, map);
                    } catch (Exception e) {
                        LOGGER.errorWithApp(appName, "Server deserialize error, request from " + channel.remoteAddress(), e);
                        response = MessageBuilder.buildSofaErrorResponse("Server deserialize error, " + e.getMessage());
                        break invoke;
                    }
                } else if (request.getMethodArgs() == null) {
                    request.setMethodArgs(CodecUtils.EMPTY_OBJECT_ARRAY);
                }
                // 真正调用
                response = doInvoke(serviceName, invoker, request);
            }
        } catch (Exception e) {
            // 服务端异常,不管是啥异常
            LOGGER.errorWithApp(appName, "Server Processor Error!", e);
            throwable = e;
            response = MessageBuilder.buildSofaErrorResponse(e.getMessage());
            status = HttpResponseStatus.INTERNAL_SERVER_ERROR;
        }
        // Response不为空,代表需要返回给客户端
        if (response != null) {
            response.setSerializeType(request.getSerializeType());
            // 其它正常请求
            try {
                // 这个try-catch 保证一定要记录tracer
                if (response.isError()) {
                    ByteBuf content = ctx.alloc().buffer();
                    content.writeBytes(StringSerializer.encode(response.getErrorMsg()));
                    sendRpcError(status == null ? HttpResponseStatus.INTERNAL_SERVER_ERROR : status, content);
                } else {
                    if (response.getAppResponse() instanceof Throwable) {
                        ByteBuf content = ctx.alloc().buffer();
                        String errorMsg = ExceptionUtils.toString((Throwable) response.getAppResponse());
                        content.writeBytes(StringSerializer.encode(errorMsg));
                        sendAppError(HttpResponseStatus.OK, content);
                    } else {
                        ByteBuf content = ctx.alloc().buffer();
                        if (request.getSerializeType() > 0) {
                            AbstractByteBuf bs = serializer.encode(response, null);
                            content.writeBytes(bs.array());
                        } else {
                            content.writeBytes(StringSerializer.encode(response.getAppResponse().toString()));
                        }
                        sendAppResponse(HttpResponseStatus.OK, content);
                    }
                }
            } finally {
                if (EventBus.isEnable(ServerSendEvent.class)) {
                    EventBus.post(new ServerSendEvent(request, response, throwable));
                }
            }
        }
    } catch (Throwable e) {
        // 可能有返回时的异常
        if (LOGGER.isErrorEnabled(appName)) {
            LOGGER.errorWithApp(appName, e.getMessage(), e);
        }
    } finally {
        serverHandler.getProcessingCount().decrementAndGet();
        if (EventBus.isEnable(ServerEndHandleEvent.class)) {
            EventBus.post(new ServerEndHandleEvent());
        }
        RpcInvokeContext.removeContext();
        RpcInternalContext.removeAllContext();
    }
}
Also used : AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) HashMap(java.util.HashMap) ServerSendEvent(com.alipay.sofa.rpc.event.ServerSendEvent) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) ProviderConfig(com.alipay.sofa.rpc.config.ProviderConfig) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext) Channel(io.netty.channel.Channel) ServerEndHandleEvent(com.alipay.sofa.rpc.event.ServerEndHandleEvent) Method(java.lang.reflect.Method) ByteBuf(io.netty.buffer.ByteBuf) AbstractByteBuf(com.alipay.sofa.rpc.transport.AbstractByteBuf) SofaRpcException(com.alipay.sofa.rpc.core.exception.SofaRpcException) ProviderProxyInvoker(com.alipay.sofa.rpc.server.ProviderProxyInvoker) Invoker(com.alipay.sofa.rpc.invoke.Invoker) ProviderProxyInvoker(com.alipay.sofa.rpc.server.ProviderProxyInvoker) ServerReceiveEvent(com.alipay.sofa.rpc.event.ServerReceiveEvent) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse) StringSerializer(com.alipay.sofa.rpc.codec.common.StringSerializer) Serializer(com.alipay.sofa.rpc.codec.Serializer)

Aggregations

ServerReceiveEvent (com.alipay.sofa.rpc.event.ServerReceiveEvent)3 ProviderConfig (com.alipay.sofa.rpc.config.ProviderConfig)2 RpcInternalContext (com.alipay.sofa.rpc.context.RpcInternalContext)2 SofaRpcException (com.alipay.sofa.rpc.core.exception.SofaRpcException)2 SofaResponse (com.alipay.sofa.rpc.core.response.SofaResponse)2 ServerEndHandleEvent (com.alipay.sofa.rpc.event.ServerEndHandleEvent)2 ServerSendEvent (com.alipay.sofa.rpc.event.ServerSendEvent)2 Invoker (com.alipay.sofa.rpc.invoke.Invoker)2 ProviderProxyInvoker (com.alipay.sofa.rpc.server.ProviderProxyInvoker)2 Method (java.lang.reflect.Method)2 HashMap (java.util.HashMap)2 SofaTraceContext (com.alipay.common.tracer.core.context.trace.SofaTraceContext)1 SofaTracerSpan (com.alipay.common.tracer.core.span.SofaTracerSpan)1 InvokeContext (com.alipay.remoting.InvokeContext)1 Serializer (com.alipay.sofa.rpc.codec.Serializer)1 StringSerializer (com.alipay.sofa.rpc.codec.common.StringSerializer)1 RpcInvokeContext (com.alipay.sofa.rpc.context.RpcInvokeContext)1 SofaRequest (com.alipay.sofa.rpc.core.request.SofaRequest)1 AbstractByteBuf (com.alipay.sofa.rpc.transport.AbstractByteBuf)1 ByteBuf (io.netty.buffer.ByteBuf)1