如何使grpc客户端调用多个服务器?

时间:2019-07-14 13:53:00

标签: java client-server load-balancing grpc

到目前为止,我已经建立了一个简单的客户端-服务器体系结构并对其进行管理。我能够发送请求并获得有效的回复。

我的问题是如何使客户端具有多个grpc服务器以能够分发工作。假设我有一个主服务器(客户端),它将请求发送到位于不同机器(因此具有不同IP的多个服务器)上的请求。在客户端方面有什么可以帮助我的吗?有主机和端口列表,并创建负载均衡器/管理通道厂? 问题是,我希望在分布式系统中将多台计算机连接到一台主机。 grpc中的每个请求都是一个文件,服务器(工作人员)会对其进行计算并返回响应。

谢谢。到目前为止,这里是使用grpc的客户端/服务器的代码,可以很好地工作。

  
    
      

客户端

    
  
@Component
public class DocumentParserClient {

    private static final Logger LOGGER = LoggerFactory.getLogger(DocumentParserClient.class);
    private static final String GRPC_HOST = "localhost";
    private static final int GRPC_PORT_I1 = 6565;
    private static final int GRPC_PORT_I2 = 6566;

    private ManagedChannel managedChannel;
    private WikiDocParserGrpc.WikiDocParserBlockingStub wikiDocParserBlockingStub;

    @PostConstruct
    private void init() {
        this.managedChannel = ManagedChannelBuilder.forAddress(GRPC_HOST, GRPC_PORT_I1).usePlaintext(true).build();
        this.wikiDocParserBlockingStub = WikiDocParserGrpc.newBlockingStub(managedChannel);
    }

    public String parseDocument(WikiOWrapperDto wikiOWrapperDto) {
        long start = System.currentTimeMillis();
        LOGGER.info("client sending {}",start);
        WikiOWrapper wikiOWrapper = GrpcDtoTransform.wrapINPUTFromDtoToGRPC(wikiOWrapperDto);
        LOGGER.info("client parsing {}", System.currentTimeMillis() - start);
        TokenCompressorDoc tokenCompressorDoc = wikiDocParserBlockingStub.parseWikiDOC(wikiOWrapper);
        LOGGER.info("client received {}", System.currentTimeMillis() - start);
        return "Success";
    }

}
  
    
      

服务器端

    
  
@GRpcService
public class WikiDocParserGrpcService extends WikiDocParserGrpc.WikiDocParserImplBase {

    private static final Logger LOGGER = LoggerFactory.getLogger(WikiDocParserGrpcService.class);
    private JSoupParser jSoupParser;

    @Autowired
    public WikiDocParserGrpcService(JSoupParser jSoupParser) {
        this.jSoupParser = jSoupParser;
    }

    @Override
    public void parseWikiDOC(WikiOWrapper wikiOWrapper, StreamObserver<TokenCompressorDoc> responseObserver) {
        long start = System.currentTimeMillis();
        LOGGER.info("server received {}", start);
        WikiOWrapperDto wikiOWrapperDto = GrpcDtoTransform.wrapOUTPUTfromGrpcToDto(wikiOWrapper);
        TokenCompressorDocDto tokenCompressorDocDto = jSoupParser.parseJsonParseWrapperFromObject(wikiOWrapperDto);
        responseObserver.onNext(GrpcDtoTransform.wrapOUTPUTFromGRPCToDto(tokenCompressorDocDto));
        responseObserver.onCompleted();
        LOGGER.info("server responded in {}", System.currentTimeMillis()- start);
    }
}

2 个答案:

答案 0 :(得分:1)

看看这里总结的方法,每种方法各有利弊:

https://grpc.io/blog/loadbalancing/

您最重要的决定是(a)扩大您的客户端以包括管理多个服务器花名册并确定如何将流量路由到它们的代码; (b)使用外部代理或负载平衡器来抽象该决策。

如果您选择选项(b),建议您重点关注L7(HTTP / 2)负载平衡,而不是TCP。 gRPC需要HTTP / 2,并使用会话进行流传输。因此,路由比使用L7和REST更复杂。包括EnvoyNGINXHAProxy在内的业界公认的代理越来越多地支持HTTP / 2和gRPC。

答案 1 :(得分:0)

对于每个遵循此主题的人,包括指定使用代理的@DazWilkin。我使用了NGINX,这是最好的方法,而且效果很好。

按照https://medium.com/@alextan/grpc-load-balancing-with-nginx-673d5d4df708进行简单指导,然后您可以扩展到TSL等。

谢谢。