java 版 gRPC 实战之七:基于 eureka 的注册发现
implementation 'org.springframework.boot:spring-boot-starter'
// 依赖 eureka
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
// 状态暴露需要的依赖
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// 依赖自动生成源码的工程
implementation project(':grpc-lib')
}
配置文件 bootstrap.yml,设置自己的 web 端口号和应用名,另外 eureka.client.serviceUrl.defaultZone 的配置请改成自己的 IP:
server:
port: 8085
spring:
application:
name: cloud-eureka
eureka:
instance:
hostname: localhost
prefer-ip-address: true
status-page-url-path: /actuator/info
health-check-url-path: /actuator/health
lease-expiration-duration-in-seconds: 30
lease-renewal-interval-in-seconds: 30
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://192.168.50.5:8085/eureka/
server:
enable-self-preservation: false
endpoints:
shutdown:
enabled: true
这个模块只有一个类 CloudEurekaApplication.java:
package com.bolingcavalry.grpctutorials;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class CloudEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(CloudEurekaApplication.class, args);
}
}
以上就是一个简单通用的 eureka 服务了;
gRPC 服务端开发
依赖 eureka 的 gRPC 服务端,其重点在于:第一,配置使用 eureka,第二,不要指定端口;
在父工程 grpc-turtorials 下面新建名为 cloud-server-side 的模块,其 build.gradle 内容如下,注意要引入 gRPC 服务端相关的 starter:
// 使用 springboot 插件
pl
ugins {
id 'org.springframework.boot'
}
dependencies {
implementation 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter'
// 作为 gRPC 服务提供方,需要用到此库
implementation 'net.devh:grpc-server-spring-boot-starter'
// 作为 eureka 的 client
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
// 状态暴露需要的依赖
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// 依赖自动生成源码的工程
implementation project(':grpc-lib')
// annotationProcessor 不会传递,使用了 lombok 生成代码的模块,需要自己声明 annotationProcessor
annotationProcessor 'org.projectlombok:lombok'
}
配置文件 application.yml,设置自己的应用名,另外值得注意的是 server.port 和 grpc.server.port 这两个配置的值都是 0,这样两个端口就会被自动分配未被占用的值:
spring:
application:
name: cloud-server-side
server:
port: 0
grpc:
server:
port: 0
eureka:
instance:
prefer-ip-address: true
instanceId: {vcap.application.instance_id:{spring.application.instance_id:{random.value}}}
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://192.168.50.5:8085/eureka/
启动类 CloudServerSideApplication.java:
package com.bolingcavalry.grpctutorials;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class CloudServerSideApplication {
public static void main(String[] args) {
SpringApplication.run(CloudServerSideApplication.class, args);
}
}
提供 gRPC 服务的类 GrpcServerService,和 local-server 模块中的一样:
package com.bolingcavalry.grpctutorials;
import com.bolingcavalry.grpctutorials.lib.HelloReply;
import com.bolingcavalry.grpctutorials.lib.SimpleGrpc;
import net.devh.boot.grpc.server.service.GrpcService;
import java.util.Date;
@GrpcService
public class GrpcServerService extends SimpleGrpc.SimpleImplBase {
@Override
public void sayHello(com.bolingcavalry.grpctutorials.lib.HelloRequest request,
io.grpc.stub.StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("1. Hello " + request.getName() + ", " + new Date()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
以上就是服务端代码了,可见除了将 gRPC 端口设置为 0,以及常规使用 eureka 的配置,其他部分和 local-server 模块是一样的;
gRPC 客户端开发
依赖 eureka 的 gRPC 客户端,其重点在于:第一,配置使用 eureka,第二,配置中的 gRPC 配置项的名字要等于 gRPC 服务端在 eureka 注册的名字,如下图红框所示:
在父工程 grpc-turtorials 下面新建名为 cloud-client-side 的模块,其 build.gradle 内容如下,注意要引入 gRPC 客户端相关的 starter:
// 使用 springboot 插件
plugins {
id 'org.springframework.boot'
}
dependencies {
implementation 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter'
// 作为 gRPC 服务使用方,需要用到此库
implementation 'net.devh:grpc-client-spring-boot-starter'
// 作为 eureka 的 client
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
// 状态暴露需要的依赖
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// 依赖自动生成源码的工程
implementation project(':grpc-lib')
// annotationProcessor 不会传递,使用了 lombok 生成代码的模块,需要自己声明 annotationProcessor
annotationProcessor 'org.projectlombok:lombok'
}
配置文件 application.yml,设置自己的 web 端口号,另外值得注意的是 gRPC 配置项 cloud-server-side 的名字要等于 gRPC 服务端在 eureka 注册的名字,并且不需要 address 配置项:
server:
port: 8086
spring:
application:
name: cloud-client-side
eureka:
instance:
prefer-ip-address: true
status-page-url-path: /actuator/info
health-check-url-path: /actuator/health
instanceId: {vcap.application.instance_id:{spring.application.instance_id:{random.value}}}
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://192.168.50.5:8085/eureka/
grpc:
client:
gRPC 配置的名字,GrpcClient 注解会用到
cloud-server-side:
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext
启动类 CloudClientSideApplication.java,使用了 eureka 相关的注解:
package com.bolingcavalry.grpctutorials;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class CloudClientSideApplication {
public static void main(String[] args) {
SpringApplication.run(CloudClientSideApplication.class, args);
}
}
封装 gRPC 调用的服务类 GrpcServerService,和 local-server 模块中的一样,GrpcClient 注解对应配置中的 gRPC 配置项:
package com.bolingcavalry.grpctutorials;
import com.bolingcavalry.grpctutorials.lib.HelloReply;
import com.bolingcavalry.grpctutorials.lib.HelloRequest;
import com.bolingcavalry.grpctutorials.lib.SimpleGrpc;
import io.grpc.StatusRuntimeException;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
@Service
public class GrpcClientService {
@GrpcClient("cloud-server-side")
private SimpleGrpc.SimpleBlockingStub simpleStub;
public String sendMessage(final String name) {
try {
final HelloReply response = this.simpleStub.sayHello(HelloRequest.newBuilder().setName(name).build());
return response.getMessage();
} catch (final StatusRuntimeException e) {
return "FAILED with " + e.getStatus().getCode().name();
}
}
}
再做一个 web 接口类,这样我们就能通过 web 调用验证 gRPC 服务了:
package com.bolingcavalry.grpctutorials;
评论