微服务中的服务间通信:使用 gRPC 和消息队列(如 Kafka)
创作时间:
作者:
@小白创作中心
微服务中的服务间通信:使用 gRPC 和消息队列(如 Kafka)
引用
CSDN
1.
https://m.blog.csdn.net/mmc123125/article/details/144978370
在微服务架构中,服务间通信是系统设计的核心部分。服务需要以高效、可靠的方式互相交换数据,而 gRPC 和消息队列(如 Kafka)正是实现这一目标的两种主流技术。本文将从原理到实践详细解析这两种通信方式,帮助你在微服务架构中更好地应用它们。
服务间通信的基本需求
在微服务架构中,每个服务通常是独立的应用程序,但它们需要相互配合来完成业务逻辑。常见的通信需求包括:
- 实时性:服务 A 发出请求后需要立即得到服务 B 的响应。
- 异步性:服务 A 发出请求后无需等待服务 B 的响应,降低耦合。
- 可靠性:确保数据在网络中不会丢失或重复。
通信模型分类
- 同步通信
- 服务直接调用其他服务,常用 HTTP 或 RPC 协议。
- 适用于需要实时响应的场景。
- 异步通信
- 服务通过消息队列或事件流异步传递消息。
- 适用于松耦合、消息高吞吐的场景。
使用 gRPC 实现同步通信
什么是 gRPC?
gRPC 是 Google 开发的高性能、开源的远程过程调用 (RPC) 框架,基于 HTTP/2 协议和 Protocol Buffers(Protobuf)数据格式,具有以下特点:
- 高效的二进制传输。
- 跨语言支持。
- 内置负载均衡、认证与流式通信。
使用 gRPC 的典型场景
- 实时性要求高的微服务调用。
- 数据量大且需要高性能的场景。
- 多语言服务间的通信需求。
gRPC 的实现步骤
1. 定义服务接口
使用 Protocol Buffers 定义 gRPC 服务及消息结构。
示例:calculator.proto
syntax = "proto3";
service Calculator {
rpc Add (AddRequest) returns (AddResponse);
}
message AddRequest {
int32 number1 = 1;
int32 number2 = 2;
}
message AddResponse {
int32 result = 1;
}
2. 生成代码
使用 protoc 工具将 .proto 文件编译成对应语言的代码。
protoc --java_out=. --grpc-java_out=. calculator.proto
3. 实现服务逻辑
服务端:
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
public class CalculatorServer {
public static void main(String[] args) throws Exception {
Server server = ServerBuilder.forPort(50051)
.addService(new CalculatorServiceImpl())
.build();
System.out.println("Server started on port 50051");
server.start();
server.awaitTermination();
}
}
class CalculatorServiceImpl extends CalculatorGrpc.CalculatorImplBase {
@Override
public void add(AddRequest request, StreamObserver<AddResponse> responseObserver) {
int result = request.getNumber1() + request.getNumber2();
AddResponse response = AddResponse.newBuilder().setResult(result).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
客户端:
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
public class CalculatorClient {
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
.usePlaintext()
.build();
CalculatorGrpc.CalculatorBlockingStub stub = CalculatorGrpc.newBlockingStub(channel);
AddRequest request = AddRequest.newBuilder().setNumber1(5).setNumber2(3).build();
AddResponse response = stub.add(request);
System.out.println("Result: " + response.getResult());
channel.shutdown();
}
}
使用 Kafka 实现异步通信
什么是 Kafka?
Apache Kafka 是一个高吞吐量、分布式的消息队列系统,常用于:
- 事件驱动架构:服务通过事件流解耦。
- 日志处理:记录并重放事件。
- 实时数据处理:流式处理大量数据。
Kafka 的工作机制
- 生产者:向 Kafka 中发送消息。
- 消费者:从 Kafka 中读取消息。
- Broker:Kafka 服务器节点,存储消息。
Kafka 的实现步骤
1. 配置 Kafka 环境
安装 Kafka 并启动 Zookeeper 和 Kafka 服务:
zookeeper-server-start.sh config/zookeeper.properties
kafka-server-start.sh config/server.properties
2. 创建主题
kafka-topics.sh --create --topic test-topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
3. 编写生产者与消费者代码
生产者:
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
public class KafkaProducerExample {
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<>(props);
String topic = "test-topic";
String message = "Hello, Kafka!";
producer.send(new ProducerRecord<>(topic, message));
System.out.println("Message sent: " + message);
producer.close();
}
}
消费者:
import org.apache.kafka.clients.consumer.*;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class KafkaConsumerExample {
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
Consumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("test-topic"));
System.out.println("Consumer started...");
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
records.forEach(record -> System.out.println("Received: " + record.value()));
}
}
}
gRPC vs Kafka:选择哪种方式?
特性 | gRPC | Kafka |
|---|---|---|
通信模式 | 同步(或流式) | 异步 |
延迟 | 低延迟 | 较高延迟 |
可靠性 | 依赖底层实现,默认无重试 | 高可靠性(持久化消息) |
适用场景 | 实时通信、点对点调用 | 事件驱动、广播、多消费者 |
学习曲线 | 较低 | 较高 |
总结
在微服务架构中:
- 使用gRPC时,可以实现高效的点对点实时通信。
- 使用Kafka时,可以实现服务解耦和高吞吐的异步通信。
两者并不是互斥的,你可以结合使用 gRPC 和 Kafka 来构建既实时又可靠的微服务架构。了解业务场景和需求,选择合适的工具,是实现高效微服务系统的关键!
热门推荐
教您做传统美食-艾草青团,正宗的手工做法,再用它做馅料,完美
英国工业革命时期的纺织业:论纺织业的技术创新和劳动力组织
医生解答:火锅烫伤出现水泡如何正确处理
枸杞泡水放几粒?泡几次要换新的?这些得知道!
“996”漩涡:是奋进的号角,还是生命的警报?
去昌平的路线怎么走?有哪些?885路及京赞线途径吗?
偏瘫肌张力高如何治疗
肌张力的康复治疗
心智觉醒的六关:从开窍到无为的心灵成长之路
一个伤心脏的坏习惯,你可能天天在重复(不是熬夜)
模拟计算机与数字计算机:工作原理、应用领域及优势分析
动画微课制作入门指南:用来画轻松实现教育创新
装修贷房产证要抵押吗?一文详解不同贷款方式
一入秋冬就龟裂?水嫩足跟好Easy!
全球近500种文化中的洪水传说
充电枪防水性能专利如何提升电动车充电性与可靠性?
充电枪防水性能专利如何提升电动车充电性与可靠性?
粘连性肩关节囊炎的危险因素、机制、分期、诊断和治疗
耳朵边上有个小孔发炎了怎么办
人为什么会做噩梦?原因及应对方法全解析
刚性防水和柔性防水有哪些区别
从南充到重庆的旅途指南:探索沿途必访的风景名胜
治疗唇炎的药物有哪些
如何分析板块的特点并做出合理投资决策?这种决策如何考虑市场趋势?
口腔科普丨种植体周围炎,悄无声息的种植牙杀手
新能源汽车时代的汽车零部件发展趋势分析
2024年厦门人口数据出炉:常住人口535万,城镇化率达91.01%
23类常见食材的储存保鲜指南,通俗易懂,实用详尽,收藏慢慢看
属羊的和属猴的在一起好不好?生肖猴跟生肖羊合财吗?
如何了解早市的情况?早市的运营有哪些要点?