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



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

我的问题是我如何使客户端拥有多个 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);
}
}

看看这里总结的方法,每种方法都有优缺点:

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

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

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

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

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

谢谢。

最新更新