在微服务中使用Apache Kafka进行异步通信

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 在微服务中使用Apache Kafka进行异步通信

尽管微服务架构可能并不是所有系统的灵丹妙药,但它无疑具有其优势,尤其是在构建具有许多不同组件的复杂系统时。如果您正在考虑微服务,则考虑不同服务的通信方式。在本文中,我们将研究如何设置Apache Kafka实例,创建用户服务以将数据发布到主题,以及构建通知服务以使用这些主题中的数据。具体来说,我们将构建一个两步验证应用程序,用户可以在该程序中进行注册,接收带有验证码的邮件,并使用该代码完成注册。源代码可以在这里找到。

为什么选择Apache Kafka?

Kafka是LinkedIn于2011年创建的分布式流媒体平台,用于处理高吞吐量,低延迟传输以及实时处理记录流。它的三大功能使其非常适合此用例:

  • 发布和订阅记录流。在这方面,它类似于消息队列或企业消息传递系统。
  • 以容错方式存储记录流。
  • 处理发生的记录流。

设置Apache Kafka

开始本教程之前,需要满足以下条件:

  • Mac版Docker或Windows版Docker
  • Docker Compose的知识
  • Node.js的知识

我们将使用Wurstmeister Kafka Docker映像。请注意,Kafka使用Zookeeper在不同的Kafka节点之间进行协调。

docker-compose.yml类似docker-compose.yml用于为Kafka和Zookeeper提取图像。Kafka服务所需的配置选项之一是KAFKA_ZOOKEEPER_CONNECT ,它告诉Kafka在哪里可以找到Zookeeper实例。

1. version: '2.1'
2. services:
3. zookeeper:
4. container_name: zookeeper
5. image: wurstmeister/zookeeper
6. ports:
7. - "2181:2181"
8. kafka:
9. container_name: kafka
10. image: wurstmeister/kafka
11. ports:
12. - "9092"
13. depends_on:
14. - "zookeeper"
15. environment:
16. KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181

将数据发布到Kafka主题

要将数据发布到Kafka主题,我们将创建一个提供两个端点的用户服务:

  • /api/register –将用户详细信息存储在内存中存储节点缓存中,并将用户数据发布到Kafka主题user_account_created
  • /api/verify –验证提供的代码正确,并将用户数据发布到Kafka主题user_account_verified

我们使用node-rdkafka NPM软件包创建一个生产者,该生产者从我们的节点应用程序连接到Kafka:

1. let producerReady;
2. producer = new kafka.Producer({
3. debug: 'all',
4. 'client.id': 'user-api',
5. 'metadata.broker.list': KAFKA_BROKER_LIST,
6. 'compression.codec': 'gzip',
7. 'retry.backoff.ms': 200,
8. 'message.send.max.retries': 10,
9. 'socket.keepalive.enable': true,
10. 'queue.buffering.max.messages': 100000,
11. 'queue.buffering.max.ms': 1000,
12. 'batch.num.messages': 1000000,
13. dr_cb: true
14. });
15. producer.connect({}, err => {
16. if (err) {
17. logger.error('connect', err);
18. }
19. });
20. producerReady = new Promise((resolve, reject) => {
21. producer.on('ready', () => {
22. logger.info('producer ready');
23. resolve(producer);
24. });
25. });

我们创建一个新的Promise对象,该对象解析为准备开始发布数据的生产者。这在我们的sendMessage函数中使用,该函数将数据发布到Kafka主题分区:

1. KafkaService.prototype.sendMessage = function sendMessage(
2.     topic,
3.     payload,
4.     partition = 0
5. ) {
6. return producerReady
7. .then(producer => {
8. const message = Buffer.from(JSON.stringify(payload));
9. producer.produce(topic, partition, message);
10. })
11. .catch(error => logger.error('unable to send message', error));
12. };

使用Kafka主题中的数据

为了使用Kafka主题中的数据,我们将创建一个通知服务,以监听来自我们主题的数据,并根据从中获取数据的主题发送带有验证码或成功消息的电子邮件。

我们创建一个连接到Kafka的使用者,其中KAFKA_BROKER_LIST是所有Kafka实例的逗号分隔列表。

1. process.stdin.resume(); // keep process alive
2. 
3. require('dotenv').config();
4. 
5. const Kafka = require('node-rdkafka');
6. 
7. const logger = require('./logger');
8. 
9. const sendMail = require('./email');
10. 
11. const KAFKA_BROKER_LIST = process.env.KAFKA_BROKER_LIST;
12. 
13. const consumer = new Kafka.KafkaConsumer({
14. //'debug': 'all',
15. 'metadata.broker.list': KAFKA_BROKER_LIST,
16. 'group.id': 'notification-service',
17. 'enable.auto.commit': false
18. });

node-rdkafka返回的使用者对象是可读流的实例。我们等待ready事件订阅我们的主题user_account_createduser_account_verified ,并侦听这些主题中的数据:

1. const topics = [
2. 'user_account_created',
3. 'user_account_verified'
4. ];
5. 
6. //counter to commit offsets every numMessages are received
7. let counter = 0;
8. let numMessages = 5;
9. 
10. consumer.on('ready', function(arg) {
11. logger.info('consumer ready.' + JSON.stringify(arg));
12. 
13. consumer.subscribe(topics);
14. //start consuming messages
15. consumer.consume();
16. });
17. 
18. consumer.on('data', function(metadata) {
19. counter++;
20. 
21. //committing offsets every numMessages
22. if (counter % numMessages === 0) {
23. logger.info('calling commit');
24. consumer.commit(metadata);
25. }
26. 
27. // Output the actual message contents
28. const data = JSON.parse(metadata.value.toString());
29. logger.info('data value', data);
30. 
31. if(metadata.topic === 'user_account_created'){
32. const to = data.email;
33. const subject = 'Verify Account';
34. const content = `Hello ${data.first_name},
35.       Please use this code ${data.code} to complete your verification`;
36. sendMail(subject, content,to);
37. }else if(metadata.topic === 'user_account_verified') {
38. const to = data.email;
39. const subject = 'Account Verified';
40. const content = `Hello ${data.first_name},
41.       You have successfully been verified`;
42. sendMail(subject, content,to);
43. }
44. 
45. });
46. 
47. consumer.on('disconnected', function(arg) {
48. logger.info('consumer disconnected. ' + JSON.stringify(arg));
49. });
50. 
51. //logging all errors
52. consumer.on('event.error', function(err) {
53. logger.error('Error from consumer', err, 'code: ', err.code);
54. });
55. 
56. //starting the consumer
57. consumer.connect();

当消息发布到我们正在侦听的任何主题时,将调用data事件处理程序。在这里,我们解析传入的消息并检查元数据对象,以了解接收到的数据所针对的主题,因此我们可以执行适当的操作。

结论

我们的两因素身份验证应用程序演示了使用Apache Kafka(还有其他系统,例如RabbitMQ , ZeroMQ )的两个微服务之间的通信模式,相对于Feign增加了未来的灵活性。

例如,假设我们将来会添加一个推荐服务,当新用户登录时,该服务需要发送推荐;它仅订阅user_account_verified主题,因此无需更改用户服务。

系统架构结论(1)数据管道场景,MQ比cache更合适;(2)服务化架构,不应该绕过service读取其后端的cache/db,而应该通过RPC接口访问;(3)MQ通信可扩展

相关文章
|
26天前
|
消息中间件 前端开发 Kafka
【Azure 事件中心】使用Apache Flink 连接 Event Hubs 出错 Kafka error: No resolvable bootstrap urls
【Azure 事件中心】使用Apache Flink 连接 Event Hubs 出错 Kafka error: No resolvable bootstrap urls
|
22天前
|
Dubbo Java 应用服务中间件
💥Spring Cloud Dubbo火爆来袭!微服务通信的终极利器,你知道它有多强大吗?🔥
【8月更文挑战第29天】随着信息技术的发展,微服务架构成为企业应用开发的主流模式,而高效的微服务通信至关重要。Spring Cloud Dubbo通过整合Dubbo与Spring Cloud的优势,提供高性能RPC通信及丰富的生态支持,包括服务注册与发现、负载均衡和容错机制等,简化了服务调用管理并支持多种通信协议,提升了系统的可伸缩性和稳定性,成为微服务通信领域的优选方案。开发者仅需关注业务逻辑,而无需过多关心底层通信细节,使得Spring Cloud Dubbo在未来微服务开发中将更加受到青睐。
45 0
|
7天前
|
存储 搜索推荐 数据库
MarkLogic在微服务架构中的应用:提供服务间通信和数据共享的机制
随着微服务架构的发展,服务间通信和数据共享成为关键挑战。本文介绍MarkLogic数据库在微服务架构中的应用,阐述其多模型支持、索引搜索、事务处理及高可用性等优势,以及如何利用MarkLogic实现数据共享、服务间通信、事件驱动架构和数据分析,提升系统的可伸缩性和可靠性。
17 5
|
26天前
|
消息中间件 Java Kafka
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
|
30天前
|
消息中间件 Java Kafka
|
19天前
|
Java 数据库连接 Spring
当在线购物遇上数据危机:Hibernate 事务管理如何力挽狂澜,确保每一次交易都万无一失?
【8月更文挑战第31天】数据一致性和事务管理对任何企业级应用至关重要,尤其是在使用 Hibernate 时。本文通过在线购物系统的具体案例,介绍了正确管理事务的重要性。以 `Product` 和 `Order` 实体为例,阐述了如何通过编程式或声明式事务管理(如 Java 代码示例中的 `@Transactional` 注解)来确保数据一致性。正确配置事务能显著提升应用质量和系统稳定性。
27 0
|
20天前
|
JSON API 数据格式
揭秘微服务间沟通的神秘语言!Ruby如何化身“信使”,让服务间通信畅通无阻?
【8月更文挑战第31天】随着应用程序规模的不断扩大,微服务架构因高度模块化、可扩展性和可维护性成为现代软件开发的首选。本文通过示例代码展示如何使用 Ruby 实现微服务间的通信,重点介绍 RESTful API 的应用。首先,通过安装 HTTParty 库简化 HTTP 请求处理;然后创建微服务客户端,演示如何调用用户服务的 API 并获取用户信息;最后,介绍如何解析 JSON 响应,使数据处理更加便捷。这种方式不仅简单高效,还能满足大多数微服务架构下的通信需求。
28 0
|
22天前
|
消息中间件 Kafka 数据处理
实时数据流处理:Dask Streams 与 Apache Kafka 集成
【8月更文第29天】在现代数据处理领域,实时数据流处理已经成为不可或缺的一部分。随着物联网设备、社交媒体和其他实时数据源的普及,处理这些高吞吐量的数据流成为了一项挑战。Apache Kafka 作为一种高吞吐量的消息队列服务,被广泛应用于实时数据流处理场景中。Dask Streams 是 Dask 库的一个子模块,它为 Python 开发者提供了一个易于使用的实时数据流处理框架。本文将介绍如何将 Dask Streams 与 Apache Kafka 结合使用,以实现高效的数据流处理。
22 0
|
26天前
|
消息中间件 Java Kafka
【Azure 事件中心】开启 Apache Flink 制造者 Producer 示例代码中的日志输出 (连接 Azure Event Hub Kafka 终结点)
【Azure 事件中心】开启 Apache Flink 制造者 Producer 示例代码中的日志输出 (连接 Azure Event Hub Kafka 终结点)
|
30天前
|
消息中间件 人工智能 Kafka
Apache Kafka + 向量数据库 + LLM = 实时 GenAI
生成式AI(GenAI)革新了企业架构,催生新数据集成模式与最佳实践。借助Apache Kafka与Apache Flink,企业能高效处理大规模实时数据,连接各类数据库与分析平台。Kafka作为核心组件,支持GenAI应用如服务台自动化、聊天机器人及内容审核。结合大型语言模型(LLM)、检索增强生成(RAG)与向量数据库,Kafka与Flink共同打造强大数据流处理能力,克服GenAI挑战,如昂贵训练成本、数据时效性与准确性。通过语义搜索与RAG设计模式,确保LLM生成内容可靠无误。
41 0

推荐镜像

更多