springboot——grpc实现demo

本文介绍如何使用SpringBoot构建gRPC服务和客户端。应用背景是Java作为服务端为Go提供接口。详细阐述了gRPC的数据序列化和进程间通信,并通过步骤详细解析了项目构建,包括各模块的pom配置、服务端接口定义和客户端调用测试。

一、前言

1、应用场景:Java做为服务端给go 提供接口

 有两种方式:**http:网络传输协议**, **rpc(Remote Produce Call)远程过程调用**

两者区别: RPC 是根据语言API来定义,不是根据网络的应用定义

2、 grpc: 数据的序列化以及进程数据通信的交互方式

主要有以下几个过程

(1) 通过.proto文件定义传输的接口和消息体。

(2) 通过protocol编译器生成server端和client端的stub程序。

(3) 将请求封装成HTTP2的Stream。

(4) 通过Channel作为数据通信通道使用Socket进行数据传输。

二、springboot 构建grpc 的demo

1、版本对应:

springboot : 2.1.4.RELEASE
JDK1.8

2、项目构建

2.1 项目结构

在这里插入图片描述

2.2 根pom文件
<?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>2.1.4.RELEASE</version>
    </parent>
    <groupId>com.lrbj</groupId>
    <artifactId>grpc-springboot-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>grpc-springboot-demo</name>
    <description>Demo project for Spring Boot</description>
    <packaging>pom</packaging>
    <!--引入的子模块-->
    <modules>
        <module>grpc-lib</module>
        <module>grpc-server</module>
        <module>grpc-client</module>
    </modules>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-boot.version>2.1.4.RELEASE</spring-boot.version>
        <net-devh-grpc.version>2.0.1.RELEASE</net-devh-grpc.version>
    </properties>
    <dependencyManagement>
    <dependencies>

        <dependency>
            <groupId>com.lrbj</groupId>
            <artifactId>grpc-lib</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--核心grpc-spring-boot依赖-->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
            <version>${net-devh-grpc.version}</version>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>${net-devh-grpc.version}</version>
        </dependency>

    </d
<think>好的,我现在需要帮助用户了解如何在Spring Boot中使用gRPC实现微服务的发布订阅模式。首先,我需要回顾一下gRPC的基本概念以及它在Spring Boot中的应用方式。根据用户提供的引用内容,特别是引用3和4,已经提到了gRPC在微服务中的集成和通信方式,这可以作为基础。 发布订阅模式通常涉及消息代理,但gRPC本身是点对点的RPC框架,可能不直接支持发布订阅。不过,可以结合消息队列如Kafka或RabbitMQ来实现,或者利用gRPC的流式通信特性。用户可能需要一个纯gRPC实现示例,或者结合其他技术。需要明确用户的需求,但根据问题描述,用户可能希望仅使用gRPC和Spring Boot,所以可能需要利用gRPC的流式特性。 接下来,我需要查阅相关引用。引用3提到使用grpc-server-spring-boot-starter和Eureka,引用4则展示了服务启动和调用的示例。因此,可能需要使用gRPC的客户端和服务端,以及可能的流式通信来实现发布订阅。例如,服务端可以保持流式连接,客户端订阅后,服务端推送消息。 然后,我需要设计一个示例,包含服务注册、消息发布和订阅的逻辑。可能需要定义protobuf服务,包含流式RPC方法。例如,定义一个Subscription服务,客户端通过流式调用订阅主题,服务端在发布消息时通过流发送给所有订阅者。 同时,需要考虑如何在Spring Boot中集成这些组件。例如,使用@GrpcService注解创建服务端实现,使用gRPC的StreamObserver处理流式通信。客户端需要连接到服务端,并保持连接以接收消息。 还需要确保依赖配置正确,如引用3提到的grpc-server-spring-boot-starter和Eureka,以及引用4中的端口配置。可能需要配置服务发现,以便客户端能够找到发布者的地址。 最后,验证示例的正确性,包括启动服务、订阅主题、发布消息并确认订阅者接收。可能需要编写测试代码或使用curl命令进行测试。 总结步骤:定义protobuf服务,实现服务端和客户端,配置依赖和注册中心,编写发布订阅逻辑,测试功能。</think>### 在Spring Boot中使用gRPC实现发布订阅模式的步骤 #### 1. 定义gRPC服务接口(proto文件) ```protobuf syntax = "proto3"; option java_multiple_files = true; option java_package = "com.example.pubsub"; service PubSubService { // 客户端订阅主题(流式响应) rpc Subscribe(SubscribeRequest) returns (stream Message); // 发布消息到主题 rpc Publish(PublishRequest) returns (PublishResponse); } message SubscribeRequest { string topic = 1; } message PublishRequest { string topic = 1; string content = 2; } message PublishResponse { bool success = 1; } message Message { string content = 1; int64 timestamp = 2; } ``` #### 2. 服务端实现(发布者) ```java @GrpcService public class PubSubServiceImpl extends PubSubServiceGrpc.PubSubServiceImplBase { private final ConcurrentMap<String, List<StreamObserver<Message>>> topicSubscribers = new ConcurrentHashMap<>(); @Override public void subscribe(SubscribeRequest request, StreamObserver<Message> responseObserver) { topicSubscribers.computeIfAbsent(request.getTopic(), k -> new CopyOnWriteArrayList<>()) .add(responseObserver); } @Override public void publish(PublishRequest request, StreamObserver<PublishResponse> responseObserver) { List<StreamObserver<Message>> subscribers = topicSubscribers.getOrDefault(request.getTopic(), Collections.emptyList()); Message message = Message.newBuilder() .setContent(request.getContent()) .setTimestamp(System.currentTimeMillis()) .build(); subscribers.forEach(observer -> observer.onNext(message)); responseObserver.onNext(PublishResponse.newBuilder().setSuccess(true).build()); responseObserver.onCompleted(); } } ``` #### 3. 客户端实现(订阅者) ```java @Component public class SubscriberClient { @GrpcClient("pubsub-service") private PubSubServiceGrpc.PubSubServiceBlockingStub blockingStub; @GrpcClient("pubsub-service") private PubSubServiceGrpc.PubSubServiceStub asyncStub; public void subscribe(String topic) { asyncStub.subscribe(SubscribeRequest.newBuilder().setTopic(topic).build(), new StreamObserver<Message>() { @Override public void onNext(Message message) { System.out.println("Received: " + message.getContent()); } @Override public void onError(Throwable t) { t.printStackTrace(); } @Override public void onCompleted() { System.out.println("Subscription ended"); } }); } } ``` #### 4. 配置服务发现(application.yml) ```yaml grpc: client: pubsub-service: address: static://localhost:9190 # 发布者服务地址 server: port: 9190 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ ``` #### 5. 运行验证 1. 启动Eureka注册中心 2. 启动发布者服务(端口9190) 3. 启动订阅者服务(自动注册到Eureka) 4. 发送订阅请求: ```java @RestController public class DemoController { @Autowired private SubscriberClient subscriberClient; @GetMapping("/subscribe") public String subscribe(@RequestParam String topic) { subscriberClient.subscribe(topic); return "Subscribed to " + topic; } } ``` 5. 发送发布请求: ```bash curl -X POST http://localhost:9190/pubsub/publish?topic=news&content=HelloWorld ``` #### 技术要点说明 1. **流式通信**:通过gRPC的`stream Message`实现持续消息推送[^3] 2. **线程安全**:使用`CopyOnWriteArrayList`处理并发订阅者列表 3. **服务发现**:通过Eureka实现服务地址解析[^4] 4. **连接管理**:gRPC底层使用HTTP/2保持长连接,适合实时通信场景[^2]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值