前面有篇文章JAVA调用go实现负载均衡(RoundRobin),这样的方式想要实现负载均衡需要配置很多ip
和port
,显然用起来很不方便,于是想到了注册中心,把所有的grpc
端口号都注册到naocs
上面,通过grpc
的服务名获取所有的实例,这样交给grpc
去做负载均衡,然后在用spring
这个胶水进行封装即可实现简单的负载均衡。
代码已经封装好了,可以参考https://github.com/fafeidou/fast-cloud-nacos/blob/master/fast-common/fast-common-grpc,下面给出封装代码的使用说明:
需要依赖这个fast-common-grpc
,读者可以把代码下载下来安装到本地。
<dependency>
<groupId>fast.cloud.nacos</groupId>
<artifactId>fast-common-grpc</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
需要配置grpc
的端口,服务的端口,以及naocs
的地址。
grpc.port=50051
server.port=8080
nacos.addr=http://127.0.0.1:8848
确定让你的程序扫描到博主写的那些配置包fast.cloud.nacos.common
。
@SpringBootApplication(scanBasePackages = {"fast.cloud.nacos.common","fast.cloud.nacos.grpc.example"})
首先定义proto
文件
syntax = "proto3";
option java_generic_services = true;
option java_multiple_files = true;
option java_outer_classname = "GrpcTestServiceProto";
service GrpcTestService {
rpc reqString (GrpcTestService_Request_String) returns (GrpcTestService_Response_String) {};
rpc reqStringClientStream (stream GrpcTestService_Request_String) returns (GrpcTestService_Response_String){};
rpc reqStringServerStream (GrpcTestService_Request_String) returns(stream GrpcTestService_Response_String){};
rpc reqStringBothStream (stream GrpcTestService_Request_String) returns(stream GrpcTestService_Response_String){};
}
message GrpcTestService_Request_String {
string name = 1;
}
message GrpcTestService_Response_String {
string result = 1;
}
使用idea
的compile
帮助你生成,这一步不在详细,可以参考【go语言专题】JAVA&GO通过GRPC互相调用,可以获取怎样生成java
的idl
。
provider
的服务注册到nacos
上你需要把哪些grpc
的服务注册到naocs
,就需要加上
@GRpcService
,这个需要实现GrpcTestServiceGrpc.GrpcTestServiceImplBase
。
@GRpcService
public class GrpcTestServiceImpl extends GrpcTestServiceGrpc.GrpcTestServiceImplBase {
@Value("${grpc.port}")
private int port;
@Override
public void reqString(GrpcTestService_Request_String request,
StreamObserver<GrpcTestService_Response_String> responseObserver) {
String name = request.getName();
responseObserver.onNext(GrpcTestService_Response_String.newBuilder()
.setResult("success:" + name +"===" + "port:" + port)
.build());
responseObserver.onCompleted();
}
@Override
public void reqStringServerStream(GrpcTestService_Request_String request,
StreamObserver<GrpcTestService_Response_String> responseObserver) {
String name = request.getName();
responseObserver.onNext(GrpcTestService_Response_String.newBuilder().setResult("success_1:" + name).build());
responseObserver.onNext(GrpcTestService_Response_String.newBuilder().setResult("success_2:" + name).build());
responseObserver.onNext(GrpcTestService_Response_String.newBuilder().setResult("success_3:" + name).build());
responseObserver.onCompleted();
}
}
消费房需要给你的stub配上channel,具体实现代码如下。
@Service
public class HelloService {
@Autowired
ManagedChannel managedChannel;
private GrpcTestServiceGrpc.GrpcTestServiceBlockingStub blockingStub;
public String hello(String name) {
GrpcTestService_Response_String grpcTestService_response_string = blockingStub.reqString(GrpcTestService_Request_String
.newBuilder()
.setName(name)
.build());
return grpcTestService_response_string.getResult();
}
@PostConstruct
private void initializeClient() {
blockingStub = GrpcTestServiceGrpc.newBlockingStub(managedChannel);
}
}
写个controller
接口,用于测试。
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/{name}")
public String sayHello(@PathVariable String name) {
return helloService.hello(name);
}
}
启动服务,访问http://localhost:8080/123,你会看到
在启动一个grpc
端口为50052
,和服务端口为8081
这样访问接口会看到,50052
和50051
会轮询访问。
上面的example
也给出github
地址,https://github.com/fafeidou/fast-cloud-nacos/blob/master/fast-common-examples/fast-common-grpc-example,不要忘记star,有什么问题欢迎下面评论。
感谢参考以下大佬的博客,使我茅塞顿开。