gRPC 是一种由 Google 开发的高性能、开源的远程过程调用(Remote Procedure Call, RPC)框架。它答应在不同的计算机系统或进程之间举行通信,使得分布式系统和微服务架构中的服务之间能够轻松地相互调用方法。gRPC 基于 HTTP/2 协议,并利用 Protocol Buffers(Protobuf)作为其接口界说语言和序列化格式。
gRPC 的重要特点和优点:
- 跨语言支持:
gRPC 支持多种编程语言,包括 C++, Java, Python, Go, C#, Node.js 等,因此不同语言编写的服务之间可以无缝通信。
- 高性能:
gRPC 利用 HTTP/2 协议,这意味着它支持双向流、多路复用和头部压缩,能更高效地利用网络资源,降低耽误。
- 协议界说:
gRPC 利用 Protocol Buffers 作为其接口界说语言(IDL)。开发者通过界说 .proto 文件,描述服务和消息布局,gRPC 工具可以自动生成对应语言的客户端和服务器端代码。
- 简朴易用:
gRPC 提供了一套简便的 API,开发者可以轻松创建和调用远程服务,就像调用本地方法一样。
- 双向流和流控:
gRPC 不但支持传统的一次性哀求-响应模子,还支持双向流,使得客户端和服务器之间可以发送多个消息,而且这些消息可以并行地传输和处置惩罚。
- 安全性:
gRPC 原生支持 SSL/TLS,可以很轻易地实现安全的通信。
gRPC 的应用场景:
- 微服务架构:
在微服务架构中,服务之间需要举行大量的通信,gRPC 提供了高效、跨语言的办理方案,适用于需要低耽误和高吞吐量的应用。
- 分布式系统:
在分布式系统中,多个节点之间可能需要频仍通信,gRPC 的高性能和双向流支持非常适合这种场景。
- 实时通信:
gRPC 的双向流特性使其非常适合需要实时数据交换的应用,例如实时聊天、视频流、物联网(IoT)应用等。
- 跨平台服务:
由于 gRPC 支持多种语言和平台,它非常适合构建跨平台的分布式服务。
总结来说,gRPC 是一种高效、灵活的远程调用框架,特别适合需要跨语言、高性能通信的分布式系统和微服务架构。
一个常见的 gRPC 利用实例是在微服务架构中,尤其是像 Uber 如许的公司,它们拥有多个微服务,需要在不同的服务之间举行高效、低耽误的通信。
需求:用户服务和订单服务的通信
假设有一个电商平台,它的系统由多个微服务组成,其中包括:
- 用户服务(User Service):管理用户信息,如注册、登录、个人资料等。
- 订单服务(Order Service):处置惩罚用户的订单信息,如创建订单、查询订单状态等。
- grpc-api:将 gRPC 的 Protobuf 界说提取到一个独立的 grpc-api 模块中,其他微服务(如用户服务和订单服务)可以引用该模块,共享 gRPC 界说和生成的代码。
用户在下订单时,订单服务需要验证用户的身份,并获取用户的干系信息(如地址、支付方式等)。在这种情况下,订单服务需要调用用户服务来获取这些信息。
模块的目录布局
- ├─grpc-api
- │ └─src
- │ └─main
- │ ├─java
- │ │ └─com
- │ │ └─song
- │ │ └─api
- │ ├─proto
- │ └─resources
- ├─grpc-order
- │ └─src
- │ └─main
- │ ├─java
- │ │ └─com
- │ │ └─song
- │ │ ├─service
- │ │ └─web
- │ └─resources
- └─grpc-user
- └─src
- └─main
- ├─java
- │ └─com
- │ └─song
- │ └─service
- └─resources
复制代码 1. 创建 grpc-api 模块
创建一个 Maven 项目 grpc-api,用于存放 .proto 文件和生成的 gRPC Java 代码。这个模块将被其他服务(如用户服务和订单服务)依靠。
2. 在 grpc-api 模块中界说 .proto 文件
在 grpc-api 模块的 src/main/proto/ 目录下创建 .proto 文件,例如:
- syntax = "proto3";
- package com.song.api;
- // 创建一个rpc 服务
- service UserService {
- rpc GetUserInfo (GetUserInfoRequest) returns (GetUserInfoResponse);
- }
- //方法的入参请求对象与入参 。参数必须有唯一标识并还是有顺序的
- message GetUserInfoRequest {
- string user_id = 1;
- }
- //方法的响应请求对象与响应参数 。参数必须有唯一标识并还是有顺序的
- message GetUserInfoResponse {
- string name = 1;
- string email = 2;
- string address = 3;
- }
复制代码 3. 配置 grpc-api 模块的 pom.xml
在 grpc-api 模块的 pom.xml 中,配置 gRPC 和 Protobuf 干系的依靠和插件,以便自动生成 gRPC 代码。
- <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>yqmm-grpc</artifactId>
- <groupId>com.song</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>grpc-api</artifactId>
- <description>grpc公共api提取</description>
- <properties>
- <maven.compiler.source>8</maven.compiler.source>
- <maven.compiler.target>8</maven.compiler.target>
- <grpc-version>1.40.1</grpc-version>
- <protobuf-version>3.21.9</protobuf-version>
- </properties>
- <dependencies>
- <!-- gRPC 依赖 -->
- <dependency>
- <groupId>io.grpc</groupId>
- <artifactId>grpc-all</artifactId>
- <version>${grpc-version}</version>
- </dependency>
- <dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- <version>${protobuf-version}</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/com.google.protobuf/protoc -->
- <dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protoc</artifactId>
- <version>${protobuf-version}</version>
- <type>pom</type>
- </dependency>
- </dependencies>
- <build>
- <extensions>
- <extension>
- <groupId>kr.motd.maven</groupId>
- <artifactId>os-maven-plugin</artifactId>
- </extension>
- </extensions>
- <plugins>
- <plugin>
- <groupId>org.xolstice.maven.plugins</groupId>
- <artifactId>protobuf-maven-plugin</artifactId>
- <version>0.6.1</version>
- <configuration>
- <protocArtifact>com.google.protobuf:protoc:3.19.1:exe:${os.detected.classifier}</protocArtifact>
- <pluginId>grpc-java</pluginId>
- <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.50.2:exe:${os.detected.classifier}</pluginArtifact>
- <!-- 设置输出目录 -->
- <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
- <!-- 设置proto文件所在目录 -->
- <protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
- <!-- 是否清除输出目录 -->
- <clearOutputDirectory>false</clearOutputDirectory>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- <goal>compile-custom</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <configuration>
- <layout>NONE</layout>
- <skip>true</skip> <!-- 自己打出的包也能用 ,就是打出的包不包含BOOT-INF目录 -->
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
复制代码 4. 生成 gRPC 代码
在 grpc-api 模块根目录下运行以下命令来生成 gRPC 代码:
大概
编译后,Protobuf 文件会被编译成 Java 类,生成的 gRPC 类会存放在 target/generated-sources/protobuf 目录中,并打包到 grpc-api 的 jar 文件中。
5. 创建用户服务模块
创建一个新的 Maven 模块(如 grpc-user),该模块将实现 gRPC 服务端,利用 grpc-api 共享的 gRPC 界说。
用户服务模块的 pom.xml
在 grpc-user 模块的 pom.xml 中,添加对 grpc-api 的依靠以及 gRPC 干系的依靠:
- <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>yqmm-grpc</artifactId>
- <groupId>com.song</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>grpc-user</artifactId>
- <description>服务端</description>
- <properties>
- <maven.compiler.source>8</maven.compiler.source>
- <maven.compiler.target>8</maven.compiler.target>
- <grpc-service-version>2.14.0.RELEASE</grpc-service-version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>com.song</groupId>
- <artifactId>grpc-api</artifactId>
- <version>1.1-SNAPSHOT</version>
- </dependency>
- <!-- 服务端-->
- <dependency>
- <groupId>net.devh</groupId>
- <artifactId>grpc-server-spring-boot-starter</artifactId>
- <version>${grpc-service-version}</version>
- </dependency>
- </dependencies>
- </project>
复制代码 实现 gRPC 服务
在 grpc-user 模块中,基于 grpc-api 中的生成代码实现 gRPC 服务端:
- /**
- * 自定义数据查询 提供给客户端数据
- */
- @GrpcService
- @Slf4j
- public class UserService extends UserServiceGrpc.UserServiceImplBase{
- @Override
- public void getUserInfo(User.GetUserInfoRequest request,
- StreamObserver<User.GetUserInfoResponse> responseObserver) {
- log.info("客户端发来的请求参数UserId>>>>>>>{}",request.getUserId());
- // todo 客户端发来的请求参数UserId 查询数据库db
- // todo 模拟db返回出来的用户数据
- User.GetUserInfoResponse response = User.GetUserInfoResponse.newBuilder()
- .setName("song-name")
- .setEmail("song.com")
- .setAddress("北京")
- .build();
- responseObserver.onNext(response);
- responseObserver.onCompleted();
- }
- }
复制代码 配置:application.yml
- grpc:
- server:
- port: 9190 # 设置 gRPC 服务器端口
- server:
- port: 10002
- spring:
- application:
- name: grpc-user
复制代码 启动类
- @SpringBootApplication
- public class UserApplication {
- public static void main(String[] args) {
- SpringApplication.run(UserApplication.class, args);
- }
- }
复制代码 6. 创建订单服务模块
同样,创建订单服务模块(如 grpc-order),该模块将作为 gRPC 客户端调用用户服务。
订单服务模块的 pom.xml
在 grpc-order 模块的 pom.xml 中,添加对 grpc-api 模块的依靠以及 gRPC 干系的依靠:
- <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>yqmm-grpc</artifactId>
- <groupId>com.song</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <artifactId>grpc-order</artifactId>
- <description>客户端</description>
- <properties>
- <maven.compiler.source>8</maven.compiler.source>
- <maven.compiler.target>8</maven.compiler.target>
- <grpc-client-version>2.14.0.RELEASE</grpc-client-version>
- </properties>
- <dependencies>
- <!-- 客户端-->
- <dependency>
- <groupId>net.devh</groupId>
- <artifactId>grpc-client-spring-boot-starter</artifactId>
- <version>${grpc-client-version}</version>
- </dependency>
- <!-- grpc-api -->
- <dependency>
- <groupId>com.song</groupId>
- <artifactId>grpc-api</artifactId>
- <version>1.1-SNAPSHOT</version>
- </dependency>
- </dependencies>
- </project>
复制代码 调用 gRPC 客户端
在 grpc-order 中,通过 gRPC 客户端调用用户服务获取用户信息:
- @Service
- public class UserClient {
- @GrpcClient("grpc-user") // yml里面指定访问服务端地址
- private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;
- public User.GetUserInfoResponse getUserInfo(String userId) {
- User.GetUserInfoRequest request = User.GetUserInfoRequest.newBuilder()
- .setUserId(userId)
- .build();
- return userServiceBlockingStub.getUserInfo(request);
- }
- }
复制代码 订单服务控制调用层
在订单服务中,可以利用 UserServiceClient 来获取用户信息并处置惩罚订单:
- @RestController
- public class OrderController {
- private final UserClient userClient;
- public OrderController(UserClient userClient) {
- this.userClient = userClient;
- }
- @GetMapping("/order")
- public String createOrder(@RequestParam String userId) {
- // 远程调用
- User.GetUserInfoResponse userInfo = userClient.getUserInfo(userId);
- // 处理订单逻辑
- return "为用户创建的订单:" + userInfo.getName()+userInfo.getAddress()+userInfo.getEmail();
- }
- }
复制代码 配置:application.yml
- server:
- port: 10001
- grpc:
- client:
- grpc-user: # 自定义服务名
- address: 'static://127.0.0.1:9190' # 调用 gRPC 的地址
- negotiation-type: plaintext # 明文传输
- spring:
- application:
- name: grpc-order
复制代码 启动类
- @SpringBootApplication
- public class OrderApplication {
- public static void main(String[] args) {
- SpringApplication.run(OrderApplication.class, args);
- }
- }
复制代码 7. 启动和运行微服务
确保用户服务和订单服务的端口配置精确,启动两个服务:
- 启动用户服务,它会在指定的 gRPC 端口监听(如 9190)。
- 启动订单服务,通过 gRPC 客户端调用用户服务来获取用户信息并处置惩罚订单。
客户端调用地址
http://localhost:10001/order?userId=123
服务端执行信息
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |