項目情況:
springboot: 2.2.2
grpc-spring-boot-starter: 2.6.1.RELEASE
項目目錄:
mypro:
- person - grpc服務端
- lib - 公共庫
- device - grpc客戶端
項目建立可參考:項目建立部分可參考我另一篇隨筆的項目建立部分:
https://www.cnblogs.com/SamNicole1809/p/12200875.html
步驟一:引入依賴
我是都在lib模塊引入的:
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>2.6.1.RELEASE</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>2.6.1.RELEASE</version>
</dependency>
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
<version>2.6.1.RELEASE</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.26.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.26.0</version>
</dependency>
<properties>
<java.version>1.8</java.version>
<os.plugin.version>1.6.2</os.plugin.version>
<grpc.version>1.26.0</grpc.version>
<protoc.version>3.11.0</protoc.version>
<protobuf.plugin.version>0.6.1</protobuf.plugin.version>
<skipTests>true</skipTests>
</properties>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os.plugin.version}</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
<!-- for more https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html -->
</configuration>
<executions>
<execution>
<!-- run mvn compile -->
<phase>compile</phase>
<goals>
<!-- produce OuterClass -->
<goal>compile</goal>
<!-- produce Grpc class -->
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
person模塊引入:
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>2.6.1.RELEASE</version>
</dependency>
person的application.yml
grpc:
server:
port: 9898
device模塊引入:
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-client-spring-boot-starter</artifactId>
<version>2.6.1.RELEASE</version>
</dependency>
device的application.yml
grpc: client: person: address: 'static://127.0.0.1:9898' enableKeepAlive: true keepAliveWithoutCalls: true negotiationType: plaintext
步驟二:生成proto文件
在lib的main目錄下新建文件夾proto,再在文件夾中新建文件mypro.proto,文件名可隨意。

mypro.proto文件內容:
syntax = "proto3"; option java_package = "com.sam.lib"; option java_multiple_files = true; option java_outer_classname = "MyproRpcProto"; service MyproRpcService { rpc getUser (GrpcStringRequest) returns (GrpcStringResponse) {} } message GrpcStringRequest { string str = 1; } message GrpcStringResponse { string str = 1; }
安裝完相關依賴后,maven中lib的Plugins目錄下找到protobug,依次執行compile和compile-custom

執行時需要下載,下載速度比較慢,第二次就很快了,下載完執行如果出錯,多半是proto文件內容的問題。
執行成功后會出現如下文件:

utils是我自己建的,主要是下面那些。
步驟三:給person和device增加lib掃描,使其能夠引用lib中的所有文件,lib和自己都要加,person同理。
@SpringBootApplication @ComponentScan({"com.sam.lib.*", "com.sam.device.*"}) public class DeviceApplication { public static void main(String[] args) { SpringApplication.run(DeviceApplication.class, args); } }
步驟四:服務端代碼
import com.sam.lib.GrpcStringRequest; import com.sam.lib.GrpcStringResponse; import com.sam.lib.MyproRpcServiceGrpc; import io.grpc.netty.shaded.io.netty.util.internal.StringUtil; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; import java.util.UUID; @GrpcService public class PersonGrpcService extends MyproRpcServiceGrpc.MyproRpcServiceImplBase { @Override public void getUser(GrpcStringRequest request, StreamObserver<GrpcStringResponse> responseObserver) { String name = request.getStr(); // 接收請求的內容
// 定義返回的內容 GrpcStringResponse response = GrpcStringResponse.newBuilder().setStr("").build();
// 如果請求正確,返回name和uuid,不正確返回空字符串 if (!StringUtil.isNullOrEmpty(name)) { String result = name + "--" + UUID.randomUUID().toString(); response = GrpcStringResponse.newBuilder().setStr(result).build(); } responseObserver.onNext(response); responseObserver.onCompleted(); } }
步驟五:客戶端代碼
import com.sam.lib.GrpcStringRequest; import com.sam.lib.GrpcStringResponse; import com.sam.lib.MyproRpcServiceGrpc; import io.grpc.Channel; import net.devh.boot.grpc.client.inject.GrpcClient; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Service public class DeviceGrpcService { @GrpcClient("person") // grpc服務的名稱 private Channel channel; private MyproRpcServiceGrpc.MyproRpcServiceBlockingStub stub; @PostConstruct public void init() { stub = MyproRpcServiceGrpc.newBlockingStub(channel); } public String getUser(String name) { GrpcStringResponse response = stub.getUser(GrpcStringRequest.newBuilder().setStr(name).build()); return response.getStr(); } }
步驟六:controller測試
@GetMapping("/grpc")
public String setGrpc() {
String result = deviceGrpcService.getUser("device");
if ("".equals(result)) {
return "Result is blank";
}
return result;
}
![]()
至此,grpc調用成功。
