git项目
理解
text
复制代码
rpc其实跟http类似,也是一种协议
大部分的rpc都采用的protobuf序列化协议
简单来说性能比http高
而对于java服务之间的rpc调用,可以使用dubbo,简化开发
但是对于跨语言的rpc调用,只能使用官方SDK,需要自己编写proto文件
然后用编译插件编译出proto关联的文件(java则为类)
如果不使用springboot的grpc-starter,就需要自己手写grpc服务端和客户端
引用springboot的grpc-starter后
只需要在yml中配置grpc服务端口,再结合@GrpcService,即可启动grpc服务和注入接口
在yml配置grpc客户端参数,再结合@GrpcClient,即可注入grpc客户端,以此调用grpc服务
grpc是rpc的一种实现,g=google
其他rpc实现:dubbo、Thrift
demo
简述
text
复制代码
依赖引好,插件引好,就可以编译出proto关联的类
如果JDK高,但是生成的类有错误,例如有javax的类,则引入annotations-api来解决
如果common中的grpc依赖版本和服务端/客户端的版本不一致,也可能导致启动报错
具体可点进starter中查看版本
或者直接在common中引入starter包
yml配置好,即可启动grpc服务端、客户端
服务端用@GrpcService实现接口
客户端用@GrpcClient注入grpc客户端,用于调用grpc服务
父pom
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.paws.game</groupId>
<artifactId>grpc-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>grpc-test</name>
<description>grpc-test</description>
<packaging>pom</packaging>
<modules>
<module>grpc-server</module>
<module>grpc-client</module>
<module>grpc-common</module>
</modules>
<properties>
<java.version>21</java.version>
</properties>
</project>
common
依赖
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.paws.game</groupId>
<artifactId>grpc-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>grpc-common</artifactId>
<properties>
<grpc.version>1.63.0</grpc.version>
</properties>
<dependencies>
<!-- 如下依赖需要参与编译 -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<!-- 用于JDK 9+的注解支持 -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<extensions>
<!-- 用来自动识别操作系统(win / mac / linux) -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<!-- protoc 编译器 -->
<protocArtifact>
com.google.protobuf:protoc:3.25.1:exe:${os.detected.classifier}
</protocArtifact>
<!-- gRPC Java 代码生成器 -->
<pluginId>grpc-java</pluginId>
<pluginArtifact>
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
proto
protobuf
复制代码
syntax = "proto3";
option java_multiple_files = true;
// 这里包名就是最后service引用的包
option java_package = "com.paws.game.grpccommon.grpc";
option java_outer_classname = "GreetProto";
package greet;
// The greeting service definition.
service GreetService {
// Sends a greeting
rpc Greet (GreetRequest) returns (GreetResponse);
}
// The request message containing the user's name.
message GreetRequest {
string name = 1;
}
// The response message containing the greetings.
message GreetResponse {
string greeting = 1;
}
server
依赖
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.paws.game</groupId>
<artifactId>grpc-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>grpc-server</artifactId>
<dependencies>
<dependency>
<groupId>com.paws.game</groupId>
<artifactId>grpc-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--单独引用server-->
<!-- <dependency>-->
<!-- <groupId>net.devh</groupId>-->
<!-- <artifactId>grpc-server-spring-boot-starter</artifactId>-->
<!-- <version>3.1.0.RELEASE</version>-->
<!-- </dependency>-->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml
yaml
复制代码
spring:
application:
name: grpc-server
# 若单独引用server,可以不配置tomcat端口,会只启动grpc服务
server:
port: 8080
# grpc端口
grpc:
server:
port: 9090
代码
java
复制代码
// 该包为proto中的java_package
import com.paws.game.grpccommon.grpc.*;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class GreetingService extends GreetServiceGrpc.GreetServiceImplBase {
@Override
public void greet(GreetRequest request, StreamObserver<GreetResponse> responseObserver) {
String name = request.getName();
String greeting = "Hello, " + name + "!";
GreetResponse response = GreetResponse.newBuilder()
.setGreeting(greeting)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
client
依赖
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.paws.game</groupId>
<artifactId>grpc-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>grpc-client</artifactId>
<dependencies>
<dependency>
<groupId>com.paws.game</groupId>
<artifactId>grpc-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--单独引用client-->
<!-- <dependency>-->
<!-- <groupId>net.devh</groupId>-->
<!-- <artifactId>grpc-client-spring-boot-starter</artifactId>-->
<!-- <version>3.1.0.RELEASE</version>-->
<!-- </dependency>-->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yaml
yaml
复制代码
spring:
application:
name: grpc-client
server:
port: 8081
grpc:
# 若服务只做客户端(只引入client依赖),可以不配置server端口(表示只是client)
server:
port: 9091
# grpc server配置
client:
# 服务名(@GrpcClient注解中填写)
grpc-server:
# 服务地址(除了static还有dns等)
address: static://localhost:9090
negotiation-type: PLAINTEXT
代码
java
复制代码
import com.paws.game.grpccommon.grpc.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import jakarta.annotation.PostConstruct;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/client/test")
public class TestController {
// 标注引用哪个server
@GrpcClient("grpc-server")
private GreetServiceGrpc.GreetServiceBlockingStub stub;
@PostConstruct
public void init() {
System.out.println("init,stub:" + stub);
}
@GetMapping("/test1")
public Object test1(@RequestParam String name) {
GreetRequest request = GreetRequest.newBuilder().setName(name).build();
// 自动注入
GreetResponse greet = stub.greet(request);
return greet.toString();
// 手动创建
// ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("127.0.0.1", 9090).usePlaintext().build();
// GreetServiceGrpc.GreetServiceBlockingStub stub1 = GreetServiceGrpc.newBlockingStub(managedChannel);
// GreetResponse greet1 = stub1.greet(request);
// return greet1.toString();
}
}