200 行代码告诉你 TDMQ 中 Pulsar 广播如何实现

导读css

Pulsar 做为 Apache 社区的相对新的成员,在业界受到很是大量的关注。新产品的文档相对不齐全也是很是可以理解的。今天客户问过来广播怎么实现的,我解释了半天,又找了不少介绍产品的 PPT,最终也没有找到“官方”的文档说明这个事情。因而我就写了这篇文章,方便你们 copy/paste 。java



做者介绍
web


徐为spring


腾讯云微服务团队高级解决方案构架师apache

毕业于欧盟 Erasmus Mundus IMMIT,得到经济和IT管理硕士学位api

自2006年以来,曾就任于SonyEricsson、SAP等多家公司,历任软件开发工程师,数据开发工程师,解决方案架构师微信



Pulsar订阅模型分类架构


Pulsar 原文支持的几种模式以下,依次是 独占模式 / 高可用模式 / 分享模式 / 基于键值 的分享模式。app



若是这几个模式尚未理解的,能够去官网先看一下,我我的以为看过应该是能够理解的:maven

https://pulsar.apache.org/docs/en/concepts-messaging/#subscriptions



Pulsar 广播模式


Pulsar 的订阅模式和不少 MQ 不太同样。好比 RabbitMQ/Kafka 等,通常消费端(Consumer)是直接去对接 Topic 的,而后 Consumer 本身又有个组的概念在配置中心去设置 offset,以此来决定是一块儿分享 Topic 的数据,仍是每一个人都接收一样的数据。在 Pulsar 的消费订阅模型里,添加了一个 Subscription 的逻辑,Subscription 的 Type 决定了消费是独享仍是分享。


因而广播模式能够用不一样 Subscription 独享的模式来实现,具体架构能够参照下图:




代码实现


1. Full-mesh 的形建立 Java 项目(好比:Springboot - 这个应该是相对简单的 IDE 集成开发组件)


画重点


  • pulsar-client-api 和 tdmq-client 须要2.6.0
  • tdmq-client 须要在腾讯的repo里才能拿到,须要使用介绍连接介绍的方式进行maven的配置(gradle方法相似)
  • 介绍连接:https://cloud.tencent.com/document/product/1179/44914


<?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.4.3</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.examble.demo</groupId> <artifactId>tdmq-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>tdmq-demo</name> <description>demo project to test tdmq</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.tencent.tdmq</groupId> <artifactId>tdmq-client</artifactId> <version>2.6.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.pulsar/pulsar-client-api --> <dependency> <groupId>org.apache.pulsar</groupId> <artifactId>pulsar-client-api</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>


2. 建立一个 Component 用来全局使用 Producer 和 Consumers


这里建立了1个 Producer 和3个拥有 exclusive subscription 的 consumers(广播模式 - 咱们期待他们3个每次都收到同样的信息)


package com.example.demo.tdmq.instance;
import javax.annotation.PostConstruct;
import org.apache.pulsar.client.api.AuthenticationFactory;import org.apache.pulsar.client.api.Consumer;import org.apache.pulsar.client.api.Message;import org.apache.pulsar.client.api.MessageListener;import org.apache.pulsar.client.api.Producer;import org.apache.pulsar.client.api.PulsarClient;import org.apache.pulsar.client.api.PulsarClientException;import org.apache.pulsar.client.api.SubscriptionType;import org.springframework.beans.factory.config.ConfigurableBeanFactory;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;
@Component@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public class Global { PulsarClient client; public Producer<byte[]> producer; public Consumer<byte[]> consumer01; public Consumer<byte[]> consumer02; public Consumer<byte[]> consumer03;
public Global() {
}
@PostConstruct public void init() { try { client = PulsarClient.builder().serviceUrl("pulsar://<Your TDMQ Pulsar Service URL>:6000/") .listenerName("custom:<TDMQ Pulsar Instance ID>/<TDMQ VPC ID>/<TDMQ Subnet ID>") .authentication(AuthenticationFactory.token( "<Your Credential Token from TDMQ>")) .build(); producer = client.newProducer().topic("persistent://<TDMQ Pulsar Instance ID>/<your name space>/<your topic>").create(); consumer01 = client.newConsumer().subscriptionType(SubscriptionType.Exclusive) .topic("persistent://<TDMQ Pulsar Instance ID>/<your name space>/<your topic>") .messageListener(new MessageListener<byte[]>() {
/** * */ private static final long serialVersionUID = 1L;
@Override public void received(Consumer<byte[]> consumer, Message<byte[]> msg) { System.out.println("Consumer01" + " - " + System.currentTimeMillis() + " - " + new String(msg.getData())); try { consumer.acknowledge(msg); } catch (PulsarClientException e) { // TODO Auto-generated catch block e.printStackTrace(); }
} }).subscriptionName("my-subscription01").subscribe(); consumer02 = client.newConsumer().subscriptionType(SubscriptionType.Exclusive) .topic("persistent://<TDMQ Pulsar Instance ID>/<your name space>/<your topic>") .messageListener(new MessageListener<byte[]>() {
/** * */ private static final long serialVersionUID = 1L;
@Override public void received(Consumer<byte[]> consumer, Message<byte[]> msg) { System.out.println("Consumer02" + " - " + System.currentTimeMillis() + " - " + new String(msg.getData())); try { consumer.acknowledge(msg); } catch (PulsarClientException e) { // TODO Auto-generated catch block e.printStackTrace(); }
} }).subscriptionName("my-subscription02").subscribe(); consumer03 = client.newConsumer().subscriptionType(SubscriptionType.Exclusive) .topic("persistent://<TDMQ Pulsar Instance ID>/<your name space>/<your topic>") .messageListener(new MessageListener<byte[]>() {
/** * */ private static final long serialVersionUID = 1L;
@Override public void received(Consumer<byte[]> consumer, Message<byte[]> msg) { System.out.println("Consumer03" + " - " + System.currentTimeMillis() + " - " + new String(msg.getData())); try { consumer.acknowledge(msg); } catch (PulsarClientException e) { // TODO Auto-generated catch block e.printStackTrace(); }
} }).subscriptionName("my-subscription03").subscribe();
} catch (PulsarClientException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
}


3. 最外层的测试代码和简单的 Message 模型


public class MessageModel {
private String messageText = null;
public String getMessageText() { return messageText; }
public void setMessageText(String messageText) { this.messageText = messageText; }}


跑起来测试一下,果真3个一块儿接收同样的消息



话很少说,赶忙跑起来玩玩吧!


有相关需求的读者欢迎留言告诉咱们你的想法!



往期

推荐


《你不得不知道的 Apache Pulsar 三大跨地域复制解决方案》

《基于 SkyWalking 的腾讯云微服务观测最佳实践》

《拥抱 Agent,“0” 代码玩转 Trace 之 OpenTelemetry 系列第二弹!》





扫描下方二维码关注本公众号,

了解更多微服务、消息队列的相关信息!

解锁超多鹅厂周边!


戳原文,了解更多消息队列TDMQ的信息

点亮在看,你最好看

本文分享自微信公众号 - 腾讯云中间件(gh_6ea1bc2dd5fd)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。