Search in sources :

Example 1 with AsyncResponse

use of io.servicecomb.core.AsyncResponse in project java-chassis by ServiceComb.

the class LoadbalanceHandler method sendWithRetry.

private void sendWithRetry(Invocation invocation, AsyncResponse asyncResp, final LoadBalancer choosenLB) throws Exception {
    long time = System.currentTimeMillis();
    // retry in loadbalance, 2.0 feature
    final int currentHandler = invocation.getHandlerIndex();
    final SyncResponseExecutor orginExecutor;
    final Executor newExecutor;
    if (invocation.getResponseExecutor() instanceof SyncResponseExecutor) {
        orginExecutor = (SyncResponseExecutor) invocation.getResponseExecutor();
        newExecutor = new Executor() {

            @Override
            public void execute(Runnable command) {
                // retry的场景,对于同步调用, 需要在网络线程中进行。同步调用的主线程已经被挂起,无法再主线程中进行重试。
                command.run();
            }
        };
        invocation.setResponseExecutor(newExecutor);
    } else {
        orginExecutor = null;
        newExecutor = null;
    }
    ExecutionListener<Invocation, Response> listener = new ExecutionListener<Invocation, Response>() {

        @Override
        public void onExecutionStart(ExecutionContext<Invocation> context) throws AbortExecutionException {
        }

        @Override
        public void onStartWithServer(ExecutionContext<Invocation> context, ExecutionInfo info) throws AbortExecutionException {
        }

        @Override
        public void onExceptionWithServer(ExecutionContext<Invocation> context, Throwable exception, ExecutionInfo info) {
            LOGGER.error("onExceptionWithServer msg {}; server {}", exception.getMessage(), context.getRequest().getEndpoint());
        }

        @Override
        public void onExecutionSuccess(ExecutionContext<Invocation> context, Response response, ExecutionInfo info) {
            if (orginExecutor != null) {
                orginExecutor.execute(() -> {
                    asyncResp.complete(response);
                });
            } else {
                asyncResp.complete(response);
            }
        }

        @Override
        public void onExecutionFailed(ExecutionContext<Invocation> context, Throwable finalException, ExecutionInfo info) {
            if (orginExecutor != null) {
                orginExecutor.execute(() -> {
                    asyncResp.consumerFail(finalException);
                });
            } else {
                asyncResp.consumerFail(finalException);
            }
        }
    };
    List<ExecutionListener<Invocation, Response>> listeners = new ArrayList<>(0);
    listeners.add(listener);
    ExecutionContext<Invocation> context = new ExecutionContext<>(invocation, null, null, null);
    LoadBalancerCommand<Response> command = LoadBalancerCommand.<Response>builder().withLoadBalancer(choosenLB).withServerLocator(invocation).withRetryHandler(new DefaultLoadBalancerRetryHandler(Configuration.INSTANCE.getRetryOnSame(invocation.getMicroserviceName()), Configuration.INSTANCE.getRetryOnNext(invocation.getMicroserviceName()), true)).withListeners(listeners).withExecutionContext(context).build();
    Observable<Response> observable = command.submit(new ServerOperation<Response>() {

        public Observable<Response> call(Server s) {
            return Observable.create(f -> {
                try {
                    ((CseServer) s).setLastVisitTime(time);
                    choosenLB.getLoadBalancerStats().incrementNumRequests(s);
                    invocation.setHandlerIndex(currentHandler);
                    invocation.setEndpoint(((CseServer) s).getEndpoint());
                    invocation.next(resp -> {
                        if (resp.isFailed()) {
                            LOGGER.error("service call error, msg is {}, server is {} ", ((Throwable) resp.getResult()).getMessage(), s);
                            choosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
                            f.onError(resp.getResult());
                        } else {
                            choosenLB.getLoadBalancerStats().incrementActiveRequestsCount(s);
                            choosenLB.getLoadBalancerStats().noteResponseTime(s, (System.currentTimeMillis() - time));
                            f.onNext(resp);
                            f.onCompleted();
                        }
                    });
                } catch (Exception e) {
                    LOGGER.error("execution error, msg is " + e.getMessage());
                    f.onError(e);
                }
            });
        }
    });
    observable.subscribe(response -> {
    }, error -> {
    }, () -> {
    });
}
Also used : DefaultLoadBalancerRetryHandler(com.netflix.client.DefaultLoadBalancerRetryHandler) RoundRobinRule(com.netflix.loadbalancer.RoundRobinRule) LoggerFactory(org.slf4j.LoggerFactory) ExceptionUtils(io.servicecomb.core.exception.ExceptionUtils) SyncResponseExecutor(io.servicecomb.core.provider.consumer.SyncResponseExecutor) ArrayList(java.util.ArrayList) Observable(rx.Observable) IsolationServerListFilter(io.servicecomb.loadbalance.filter.IsolationServerListFilter) Map(java.util.Map) AbstractHandler(io.servicecomb.core.handler.impl.AbstractHandler) LoadBalancerCommand(com.netflix.loadbalancer.reactive.LoadBalancerCommand) Logger(org.slf4j.Logger) ExecutionListener(com.netflix.loadbalancer.reactive.ExecutionListener) Executor(java.util.concurrent.Executor) Server(com.netflix.loadbalancer.Server) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AsyncResponse(io.servicecomb.core.AsyncResponse) TransactionControlFilter(io.servicecomb.loadbalance.filter.TransactionControlFilter) ExecutionContext(com.netflix.loadbalancer.reactive.ExecutionContext) List(java.util.List) IRule(com.netflix.loadbalancer.IRule) ExecutionInfo(com.netflix.loadbalancer.reactive.ExecutionInfo) Response(io.servicecomb.core.Response) ServerOperation(com.netflix.loadbalancer.reactive.ServerOperation) Invocation(io.servicecomb.core.Invocation) Invocation(io.servicecomb.core.Invocation) Server(com.netflix.loadbalancer.Server) SyncResponseExecutor(io.servicecomb.core.provider.consumer.SyncResponseExecutor) ArrayList(java.util.ArrayList) ExecutionInfo(com.netflix.loadbalancer.reactive.ExecutionInfo) ExecutionListener(com.netflix.loadbalancer.reactive.ExecutionListener) SyncResponseExecutor(io.servicecomb.core.provider.consumer.SyncResponseExecutor) Executor(java.util.concurrent.Executor) DefaultLoadBalancerRetryHandler(com.netflix.client.DefaultLoadBalancerRetryHandler) Observable(rx.Observable) AsyncResponse(io.servicecomb.core.AsyncResponse) Response(io.servicecomb.core.Response) ExecutionContext(com.netflix.loadbalancer.reactive.ExecutionContext)

Example 2 with AsyncResponse

use of io.servicecomb.core.AsyncResponse in project java-chassis by ServiceComb.

the class TestLoadbalanceHandler method testLoadbalanceHandlerHandleWithSendWithRetry.

@Test
public void testLoadbalanceHandlerHandleWithSendWithRetry() throws Exception {
    boolean status = true;
    LoadbalanceHandler lh = new LoadbalanceHandler();
    Invocation invocation = Mockito.mock(Invocation.class);
    AsyncResponse asyncResp = Mockito.mock(AsyncResponse.class);
    Mockito.when(invocation.getConfigTransportName()).thenReturn("baadshah");
    Map<String, LoadBalancer> loadBalancerMap = new ConcurrentHashMap<String, LoadBalancer>();
    loadBalancerMap.put("baadshah", lb);
    try {
        Deencapsulation.setField(lh, "loadBalancerMap", loadBalancerMap);
        Deencapsulation.invoke(lh, "sendWithRetry", invocation, asyncResp, lb);
        lh.handle(invocation, asyncResp);
    } catch (Exception e) {
        status = false;
    }
    Assert.assertTrue(status);
}
Also used : Invocation(io.servicecomb.core.Invocation) AsyncResponse(io.servicecomb.core.AsyncResponse) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.junit.Test)

Example 3 with AsyncResponse

use of io.servicecomb.core.AsyncResponse in project java-chassis by ServiceComb.

the class TestLoadbalanceHandler method testLoadbalanceHandlerHandleWithLoadBalancerHandler.

@Test
public void testLoadbalanceHandlerHandleWithLoadBalancerHandler() throws Exception {
    boolean status = true;
    new MockUp<LoadbalanceHandler>() {

        @Mock
        private LoadBalancer createLoadBalancer(String appId, String microserviceName, String microserviceVersionRule, String transportName) {
            return lb;
        }
    };
    LoadbalanceHandler lh = new LoadbalanceHandler();
    Invocation invocation = Mockito.mock(Invocation.class);
    Mockito.when(invocation.getConfigTransportName()).thenReturn("baadshah");
    Mockito.when(invocation.getMicroserviceVersionRule()).thenReturn("VERSION_RULE_LATEST");
    AsyncResponse asyncResp = Mockito.mock(AsyncResponse.class);
    Mockito.when(invocation.getMicroserviceName()).thenReturn("test");
    new MockUp<Configuration>() {

        @Mock
        public boolean isRetryEnabled(String microservice) {
            return true;
        }
    };
    SyncResponseExecutor orginExecutor = new SyncResponseExecutor();
    Mockito.when(invocation.getResponseExecutor()).thenReturn(orginExecutor);
    List<ExecutionListener<Invocation, Response>> listeners = new ArrayList<>(0);
    @SuppressWarnings("unchecked") ExecutionListener<Invocation, Response> listener = Mockito.mock(ExecutionListener.class);
    ExecutionListener<Invocation, Response> e = null;
    listeners.add(e);
    listeners.add(listener);
    try {
        lh.handle(invocation, asyncResp);
    } catch (Exception ex) {
        status = false;
    }
    Assert.assertTrue(status);
}
Also used : Invocation(io.servicecomb.core.Invocation) SyncResponseExecutor(io.servicecomb.core.provider.consumer.SyncResponseExecutor) ArrayList(java.util.ArrayList) MockUp(mockit.MockUp) ExecutionListener(com.netflix.loadbalancer.reactive.ExecutionListener) AsyncResponse(io.servicecomb.core.AsyncResponse) Response(io.servicecomb.core.Response) AsyncResponse(io.servicecomb.core.AsyncResponse) Test(org.junit.Test)

Example 4 with AsyncResponse

use of io.servicecomb.core.AsyncResponse in project java-chassis by ServiceComb.

the class GrpcTransport method send.

@Override
public void send(Invocation invocation, AsyncResponse asyncResp) throws Exception {
    HttpClientWithContext httpClientWithContext = clientMgr.findThreadBindClientPool();
    OperationMeta operationMeta = invocation.getOperationMeta();
    OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(operationMeta);
    String cseContext = JsonUtils.writeValueAsString(invocation.getContext());
    // 在verticle之外的线程调用
    IpPort ipPort = (IpPort) invocation.getEndpoint().getAddress();
    Buffer requestBuf = GrpcCodec.encodeRequest(invocation, operationProtobuf);
    String url = "/" + invocation.getSchemaId() + "/" + operationMeta.getOperationId();
    Handler<HttpClientResponse> responseHandler = httpResponse -> {
        httpResponse.bodyHandler(responseBuf -> {
            invocation.getResponseExecutor().execute(() -> {
                try {
                    Response response = GrpcCodec.decodeResponse(invocation, operationProtobuf, httpResponse, responseBuf);
                    ResponseMeta responseMeta = operationMeta.findResponseMeta(response.getStatusCode());
                    for (String headerName : responseMeta.getHeaders().keySet()) {
                        for (String value : httpResponse.headers().getAll(headerName)) {
                            response.getHeaders().addHeader(headerName, value);
                        }
                    }
                    asyncResp.complete(response);
                } catch (Exception e) {
                    asyncResp.fail(invocation.getInvocationType(), e);
                }
            });
        });
    };
    // 从业务线程转移到网络线程中去发送
    httpClientWithContext.runOnContext(httpClient -> {
        HttpClientRequest httpClientRequest = httpClient.post(ipPort.getPort(), ipPort.getHostOrIp(), url, responseHandler);
        httpClientRequest.exceptionHandler(e -> {
            asyncResp.fail(invocation.getInvocationType(), e);
        });
        httpClientRequest.setTimeout(AbstractTransport.getRequestTimeout());
        httpClientRequest.putHeader(HEADER_CONTENT_TYPE, "application/grpc").putHeader(HEADER_TE, "trailers").putHeader(HEADER_USER_AGENT, "cse-client/1.0.0").putHeader(Const.CSE_CONTEXT, cseContext).putHeader(Const.DEST_MICROSERVICE, invocation.getMicroserviceName()).end(requestBuf);
    });
}
Also used : Buffer(io.vertx.core.buffer.Buffer) JsonUtils(io.servicecomb.foundation.common.utils.JsonUtils) OperationMeta(io.servicecomb.core.definition.OperationMeta) OperationProtobuf(io.servicecomb.codec.protobuf.definition.OperationProtobuf) IpPort(io.servicecomb.foundation.common.net.IpPort) ResponseMeta(io.servicecomb.swagger.invocation.response.ResponseMeta) ProtobufManager(io.servicecomb.codec.protobuf.definition.ProtobufManager) JksOptions(io.vertx.core.net.JksOptions) HttpClientWithContext(io.servicecomb.foundation.vertx.client.http.HttpClientWithContext) AsyncResponse(io.servicecomb.core.AsyncResponse) Const(io.servicecomb.core.Const) HttpClientRequest(io.vertx.core.http.HttpClientRequest) HttpClientResponse(io.vertx.core.http.HttpClientResponse) Component(org.springframework.stereotype.Component) VertxUtils(io.servicecomb.foundation.vertx.VertxUtils) Buffer(io.vertx.core.buffer.Buffer) DeploymentOptions(io.vertx.core.DeploymentOptions) HttpVersion(io.vertx.core.http.HttpVersion) AbstractTransport(io.servicecomb.core.transport.AbstractTransport) Response(io.servicecomb.core.Response) HttpClientOptions(io.vertx.core.http.HttpClientOptions) Handler(io.vertx.core.Handler) ClientPoolManager(io.servicecomb.foundation.vertx.client.ClientPoolManager) Invocation(io.servicecomb.core.Invocation) IpPort(io.servicecomb.foundation.common.net.IpPort) AsyncResponse(io.servicecomb.core.AsyncResponse) HttpClientResponse(io.vertx.core.http.HttpClientResponse) Response(io.servicecomb.core.Response) HttpClientRequest(io.vertx.core.http.HttpClientRequest) OperationProtobuf(io.servicecomb.codec.protobuf.definition.OperationProtobuf) ResponseMeta(io.servicecomb.swagger.invocation.response.ResponseMeta) HttpClientResponse(io.vertx.core.http.HttpClientResponse) HttpClientWithContext(io.servicecomb.foundation.vertx.client.http.HttpClientWithContext) OperationMeta(io.servicecomb.core.definition.OperationMeta)

Example 5 with AsyncResponse

use of io.servicecomb.core.AsyncResponse in project java-chassis by ServiceComb.

the class HighwayClient method send.

public void send(Invocation invocation, AsyncResponse asyncResp) throws Exception {
    TcpClientPool tcpClientPool = clientMgr.findThreadBindClientPool();
    OperationMeta operationMeta = invocation.getOperationMeta();
    OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(operationMeta);
    TcpOutputStream os = HighwayCodec.encodeRequest(invocation, operationProtobuf);
    tcpClientPool.send(invocation.getEndpoint().getEndpoint(), os, ar -> {
        invocation.getResponseExecutor().execute(() -> {
            if (ar.failed()) {
                asyncResp.consumerFail(ar.cause());
                return;
            }
            try {
                Response response = HighwayCodec.decodeResponse(invocation, operationProtobuf, ar.result());
                asyncResp.complete(response);
            } catch (Throwable e) {
                asyncResp.consumerFail(e);
            }
        });
    });
}
Also used : AsyncResponse(io.servicecomb.core.AsyncResponse) Response(io.servicecomb.core.Response) OperationProtobuf(io.servicecomb.codec.protobuf.definition.OperationProtobuf) OperationMeta(io.servicecomb.core.definition.OperationMeta) TcpClientPool(io.servicecomb.foundation.vertx.client.tcp.TcpClientPool) TcpOutputStream(io.servicecomb.foundation.vertx.tcp.TcpOutputStream)

Aggregations

AsyncResponse (io.servicecomb.core.AsyncResponse)22 Invocation (io.servicecomb.core.Invocation)18 Test (org.junit.Test)16 RestOperationMeta (io.servicecomb.common.rest.definition.RestOperationMeta)6 Response (io.servicecomb.core.Response)6 IpPort (io.servicecomb.foundation.common.net.IpPort)6 Endpoint (io.servicecomb.core.Endpoint)5 OperationMeta (io.servicecomb.core.definition.OperationMeta)5 HttpClientRequest (io.vertx.core.http.HttpClientRequest)5 MockUp (mockit.MockUp)5 HttpClient (io.vertx.core.http.HttpClient)4 OperationProtobuf (io.servicecomb.codec.protobuf.definition.OperationProtobuf)3 HttpClientWithContext (io.servicecomb.foundation.vertx.client.http.HttpClientWithContext)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ExecutionListener (com.netflix.loadbalancer.reactive.ExecutionListener)2 ProduceProcessor (io.servicecomb.common.rest.codec.produce.ProduceProcessor)2 URLPathBuilder (io.servicecomb.common.rest.definition.path.URLPathBuilder)2 InvocationException (io.servicecomb.core.exception.InvocationException)2 SyncResponseExecutor (io.servicecomb.core.provider.consumer.SyncResponseExecutor)2 URIEndpointObject (io.servicecomb.foundation.common.net.URIEndpointObject)2