Reputation: 599
So far I've built a simple client-server architecture and manage it to work. I am able to send a request and get back a valid response.
My problem it's how do I make the client to have multiple grpc servers to be able to distribute the work. Suppose I have a master (client) which sends requests to mutiple servers which are on different machines (therefore different IP's. Is there something that might help me on the client side? Have a list of hosts and ports and create a load balancer / mannagedchannel factory? The thing is here that I want to have multiple machines connected to one master machine in a distributed system. Each request in grpc it's a file which the server (worker) computes it and return a response.
Thank you. So far here is the code for the client/server with grpc which works very fine.
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);
}
}
Upvotes: 0
Views: 9674
Reputation: 599
For every one who follows this topic, including @DazWilkin who specified to use a proxy. I used NGINX and it's quite the best approach and works just fine.
Follow https://medium.com/@alextan/grpc-load-balancing-with-nginx-673d5d4df708 to a simple guide and then you can extend to TSL etc.
Thanks.
Upvotes: 0
Reputation: 40051
Have a look at the approaches summarized here with pros-and-cons for each:
https://grpc.io/blog/loadbalancing/
Your most important decision is whether to (a) thicken your client to include code that manages a roster of multiple servers and determine how to route traffic to them; (b) use an external proxy or load-balancer to abstract this decision-making.
If you choose option (b), I encourage you to focus on L7 (HTTP/2) load-balancing rather than TCP. gRPC requires HTTP/2 and uses sessions for streaming. For this reason, routing is more complicated than with L7 and REST. Increasingly, industry-proven proxies including Envoy, NGINX and HAProxy support HTTP/2 and gRPC.
Upvotes: 2