【问题标题】:How to make a grpc client to call multiple servers?如何让一个grpc客户端调用多个服务器?
【发布时间】:2019-07-14 13:53:00
【问题描述】:

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

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

谢谢。到目前为止,这里是使用 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);
    }
}

【问题讨论】:

    标签: java client-server load-balancing grpc


    【解决方案1】:

    查看此处总结的方法以及每种方法的优缺点:

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

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

    如果您选择选项 (b),我鼓励您关注 L7 (HTTP/2) 负载平衡而不是 TCP。 gRPC 需要 HTTP/2 并使用会话进行流式传输。因此,路由比 L7 和 REST 更复杂。越来越多的经过行业验证的代理(包括 EnvoyNGINXHAProxy)支持 HTTP/2 和 gRPC。

    【讨论】:

    • 感谢您的回复。 (a) 实施起来并不是很糟糕。来自 grpc 的 ManagedChannel 非常消耗资源并且超过 1.. 可能会使事情复杂化。我将依靠选项(b)并使用您提到的代理之一。会这样尝试。谢谢。
    【解决方案2】:

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

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

    谢谢。

    【讨论】:

      猜你喜欢
      • 2021-04-10
      • 2022-10-05
      • 1970-01-01
      • 2022-01-13
      • 2019-07-25
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多