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

How to make a grpc client to call multiple servers?

到目前为止,我已经构建了一个简单的客户端-服务器架构并管理它正常工作。我能够发送请求并返回有效响应。

我的问题是如何让客户端拥有多个 grpc 服务器以便能够分发工作。假设我有一个主机(客户端),它向不同机器上的多个服务器发送请求(因此 IP 不同。在客户端有什么可以帮助我的吗?有一个主机和端口列表并创建一个负载平衡器/mannagedchannel工厂? 事情就在这里,我想让多台机器连接到分布式系统中的一台主机。 grpc 中的每个请求都是一个文件,服务器(工作人员)计算它并 return 一个响应。

谢谢。到目前为止,这里是使用 grpc 的 client/server 的代码,它工作得很好。

Client side

@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";
    }

}

Server side

@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);
    }
}

查看此处总结的方法,每个方法 pros-and-cons:

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

您最重要的决定是是否 (a) 加厚您的客户端以包括管理多个服务器名册的代码并确定如何将流量路由到它们; (b) 使用外部代理或 load-balancer 抽象此 decision-making.

如果您选择选项 (b),我鼓励您关注 L7 (HTTP/2) load-balancing 而不是 TCP。 gRPC 需要 HTTP/2 并使用会话进行流式处理。因此,路由比 L7 和 REST 更复杂。越来越多的 industry-proven 代理包括 Envoy, NGINX and HAProxy 支持 HTTP/2 和 gRPC。

对于所有关注此主题的人,包括指定使用代理的@DazWilkin。我使用了 NGINX,它是最好的方法并且工作得很好。

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

谢谢。