如何实现一个简单易用的 RocketMQ SDK
2018 年,做为架构负责人,接到一个架构需求:实现一个简单易用的 RocketMQ SDK 。
因为各个团队 RocketMQ 原生客户端配置起来千奇百怪,有的配置存在风险,各团队负责人都需要一个简洁易用的 RocketMQ SDK 。
我立马调研相关开源的方案,当时 RocketMQ-Spring 项目并没有开源,而阿里云的 ONS SDK 是开源的,我只能讲目标转向 阿里云 ONS 。
通过学习 ONS 的设计方式,我对于 RocketMQ 的客户端原理有了进一步了解,同时参考 ONS 的设计,也实现了公司内部使用的 RocketMQ SDK 。

之所以说简单,就是让用户(开发者)使用 SDK 时,减少心智负担。
举三个例子:
1 发送顺序消息
使用原生代码发送消息时,会使用如下的代码:
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}
}, orderId);
我们可以将 SDK API 简化为:
SendResult send(final ProducerMessage message, final String shardingKey);
开发者不需要定义队列选择器,只需要传递分片键 orderId 即可。
2 单条消息消费
使用原来代码定义消费监听器时,使用如下的代码:
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
// 返回消息消费状态,ConsumeConcurrentlyStatus.CONSUME_SUCCESS为消费成功
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
监听器内部,对于开发者操作的对象是消息列表 msgs ,很多开发同学想只操作一条消息。
于是,我们可以将 SDK API 简化为:
consumer.subscribe("mytest", new ConsumerListener() {
@Override
public ConsumerAction consumer(ConsumerMessage msg) {
byte[] body = msg.getBody();
System.out.println("msg:" + new String(body));
return ConsumerAction.CommitMessage;
}
});
开发者在消费时,可以一条一条操作,代码简洁了不少。
同时,很多开发者在使用普通消费、顺序消费时,需要返回延时消费的状态码时,两种消费模式定义的枚举也不相同。我们将枚举做了统一:
/**
* 消费消息的返回结果
*/
public enum ConsumerAction {
/**
* 消费成功,继续消费下一条消息
*/
CommitMessage,
/**
* 消费失败,告知服务器稍后再投递这条消息,继续消费其他消息
*/
ReconsumeLater;
}
3 订阅关系一致
实际场景里,订阅关系不一致是极容易发生的事情,就算是高级别的架构师也会翻车,每次翻车现场都是惨不忍睹。
正确的订阅关系见下图:

代码逻辑角度来看,每个消费者实例内订阅方法的主题、 TAG、监听逻辑都需要保持一致。

当订阅关系不一致时,在 Broker 端同一个消费组内的各个消费者客户端的订阅信息相互被覆盖,从而导致某个消费者客户端无法拉取到新的消息。
怎么解决呢 ?
我当时想起了阿里技术专家沈询的一句话:
世界上解决一个计算机问题最简单的方法:“恰好”不需要解决它 !
公司内部出现订阅关系一致99%的问题是:消费者组一致的前提下,主题相同,但 TAG 不相同。
基于此,我的设计思路就明确了:不开放订阅 TAG 的权限!
没想到吧,我就是这么粗暴。
按照这种设计思路,虽然开始有的程序员会有质疑,但你和他梳理好消费者组的定义,以及做好领域划分,对业务来讲,反而清晰了。
4 写到最后
我并不认为我们写得多么的好,只是想让同学们理解:
1、成长的第一步就是模仿;
2、把开发者当用户,以用户的体验为先。
我经常去阅读阿里云产品的 SDK , 去思考他们为什么这么设计, 为什么和开源的有所不同,有的时候开始没想明白,但模仿得多了,好像也慢慢懂了。
要紧的是果敢地迈出第一步,对与错先都不管,自古就没有把一切都设计好再开步的事。
别想把一切都弄清楚,再去走路。鲁莽者要学会思考,善思者要克服的是犹豫。
——史铁生
如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

如何实现一个简单易用的 RocketMQ SDK的更多相关文章
- 分享一个简单易用的RPC开源项目—Tatala
http://zijan.iteye.com/blog/2041894 这个项目最早(2008年)是用于一个网络游戏的Cache Server,以及一个电子商务的Web Session服务.后来不断增 ...
- 一个简单易用的容器管理平台-Humpback
什么是Humpback? 在回答这个问题前,我们得先了解下什么的 Docker(哦,现在叫 Moby,文中还是继续称 Docker). 在 Docker-百度百科 中,对 Docker 已经解释得很清 ...
- 分享一个简单易用的软件定时器模块(MultiTimer)——基于keil+stm32f103zet+hal库(裸机实现)
公众号上看到一个比较好的一个github项目:https://github.com/0x1abin/MultiTimer 今天看了看,简单的,就移植了- 且看文档的说明, ============== ...
- C# 编写一个简单易用的 Windows 截屏增强工具
半年前我开源了 DreamScene2 一个小而快并且功能强大的 Windows 动态桌面软件.有很多的人喜欢,这使我有了继续做开源的信心.这是我的第二个开源作品 ScreenshotEx 一个简单易 ...
- FineBI:一个简单易用的自助BI工具
过去,有关企业数据分析的重担都压在IT部门,传统BI分析更多面向的是具有IT背景的人员.但随着业务分析需求的增加,很多公司都希望为业务用户提供自助分析服务,将分析工作落实到业务人员手中.但同时,分析工 ...
- 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)
写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...
- 微软新神器-Power BI横空出世,一个简单易用,还用得起的BI产品,你还在等什么???
在当前互联网,由于大数据研究热潮,以及数据挖掘,机器学习等技术的改进,各种数据可视化图表层出不穷,如何让大数据生动呈现,也成了一个具有挑战性的可能,随之也出现了大量的商业化软件.今天就给大家介绍一款逆 ...
- 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)
flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...
- 来来来,告诉你一个简单易上手的KPI打分的方子
▋1/3 前言 每个企业都要定期为员工的工作来进行考核,有月度考核.季度考核和年度考核. 这次月度考核,我打算用一种新的方式来执行. 我在我们研发小组内曾分享过能力-意愿四象限图.根据岗位技术能力和工 ...
- 一个简单易上手的短信服务Spring Boot Starter
前言 短信服务在用户注册.登录.找回密码等相关操作中,可以让用户使用更加便捷,越来越多的公司都采用短信验证的方式让用户进行操作,从而提高用户的实用性. Spring Boot Starter 由于 S ...
随机推荐
- Kingbase ES 自定义聚合函数浅析
文章概要: 基于前面的博文<Kingbase ES 自定义聚合函数和一次改写案例>这篇文章,我们只考虑了自定义聚合函数非并行的情况, 因此,本篇文章将着重解析一下使用PLPGSQL编写并行 ...
- KingbaseES 数据表复制语句的功能差异
Kingbase 数据表复制操作 数据库使用过成中,经常会遇到在现有的表结构基础上,对表结构进行复制.在KingbaseES数据库可以采用select into,create table as sel ...
- KingbaseES Json 系列五--Json数据操作函数三
KingbaseES Json 系列五:Json数据操作函数三(JSONB_SET,JSONB_INSERT,JSON_QUERY) JSON 数据类型是用来存储 JSON(JavaScript Ob ...
- 正则表达式 (?<= 与 (?= 的区别
(?=pattern) 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串.这是一个非获取匹配, 也就是说,该匹配不需要获取供以后使用.例如,"Windows(?=95|98 ...
- USACO 4.1
目录 洛谷 2737 麦香牛块 分析 代码 洛谷 2738 篱笆回路 分析 代码 麦香牛块洛谷传送门,麦香牛块USACO传送门,篱笆回路洛谷传送门,篱笆回路USACO传送门 洛谷 2737 麦香牛块 ...
- 前端使用 Konva 实现可视化设计器(2)
作为继续创作的动力,继续求 github Star 能超过 50 个(目前惨淡的 0 个),望多多支持. 源码 示例地址 在上一章,实现了"无限画布"."画布移动&quo ...
- JDK14性能管理工具:Jconsole详解
目录 简介 JConsole 概览 内存 线程 类 VM信息 MBean 总结 简介 我们在开发java项目的时候,或多或少都会去用到Java的性能管理工具.有时候是为了提升应用程序的性能,有时候是为 ...
- OpenHarmony社区运营报告(2023年9月)
●9月12日,由宁夏回族自治区教育厅.OpenAtom OpenHarmony(以下简称"OpenHarmony")项目群工作委员会指导,北京新大陆时代科技有限公司主办,宁夏职 ...
- C#中超链接方法
linkLabel控件:双击事件打开网页:System.Diagnostics.Process.Start("http://www.baidu.com"); 截图:
- Viu联合华为HMS生态,共创影音娱乐新体验
华为HMS生态携手流媒体平台Viu,为海外消费者打造精品移动娱乐应用体验,并助力提升流量变现能力.Viu在中东非.东南亚等16个国家及地区提供广告合作和付费会员服务,支持优质视频内容高清点播和直播.自 ...