2018 年,做为架构负责人,接到一个架构需求:实现一个简单易用的 RocketMQ SDK 。

因为各个团队 RocketMQ 原生客户端配置起来千奇百怪,有的配置存在风险,各团队负责人都需要一个简洁易用的 RocketMQ SDK 。

我立马调研相关开源的方案,当时 RocketMQ-Spring 项目并没有开源,而阿里云的 ONS SDK 是开源的,我只能讲目标转向 阿里云 ONS 。

通过学习 ONS 的设计方式,我对于 RocketMQ 的客户端原理有了进一步了解,同时参考 ONS 的设计,也实现了公司内部使用的 RocketMQ SDK 。

项目地址:https://github.com/makemyownlife/platform-rocketmq

之所以说简单,就是让用户(开发者)使用 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的更多相关文章

  1. 分享一个简单易用的RPC开源项目—Tatala

    http://zijan.iteye.com/blog/2041894 这个项目最早(2008年)是用于一个网络游戏的Cache Server,以及一个电子商务的Web Session服务.后来不断增 ...

  2. 一个简单易用的容器管理平台-Humpback

    什么是Humpback? 在回答这个问题前,我们得先了解下什么的 Docker(哦,现在叫 Moby,文中还是继续称 Docker). 在 Docker-百度百科 中,对 Docker 已经解释得很清 ...

  3. 分享一个简单易用的软件定时器模块(MultiTimer)——基于keil+stm32f103zet+hal库(裸机实现)

    公众号上看到一个比较好的一个github项目:https://github.com/0x1abin/MultiTimer 今天看了看,简单的,就移植了- 且看文档的说明, ============== ...

  4. C# 编写一个简单易用的 Windows 截屏增强工具

    半年前我开源了 DreamScene2 一个小而快并且功能强大的 Windows 动态桌面软件.有很多的人喜欢,这使我有了继续做开源的信心.这是我的第二个开源作品 ScreenshotEx 一个简单易 ...

  5. FineBI:一个简单易用的自助BI工具

    过去,有关企业数据分析的重担都压在IT部门,传统BI分析更多面向的是具有IT背景的人员.但随着业务分析需求的增加,很多公司都希望为业务用户提供自助分析服务,将分析工作落实到业务人员手中.但同时,分析工 ...

  6. 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)

    写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...

  7. 微软新神器-Power BI横空出世,一个简单易用,还用得起的BI产品,你还在等什么???

    在当前互联网,由于大数据研究热潮,以及数据挖掘,机器学习等技术的改进,各种数据可视化图表层出不穷,如何让大数据生动呈现,也成了一个具有挑战性的可能,随之也出现了大量的商业化软件.今天就给大家介绍一款逆 ...

  8. 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)

    flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...

  9. 来来来,告诉你一个简单易上手的KPI打分的方子

    ▋1/3 前言 每个企业都要定期为员工的工作来进行考核,有月度考核.季度考核和年度考核. 这次月度考核,我打算用一种新的方式来执行. 我在我们研发小组内曾分享过能力-意愿四象限图.根据岗位技术能力和工 ...

  10. 一个简单易上手的短信服务Spring Boot Starter

    前言 短信服务在用户注册.登录.找回密码等相关操作中,可以让用户使用更加便捷,越来越多的公司都采用短信验证的方式让用户进行操作,从而提高用户的实用性. Spring Boot Starter 由于 S ...

随机推荐

  1. Docker技术全景:推动云原生架构的关键力量

    本文深入探讨了Docker的发展历程.核心技术.在云服务中的应用以及其庞大生态系统.通过分析Docker如何革新容器化技术.加速云服务的发展,并构建一个多元化的生态系统,本文揭示了Docker在当代云 ...

  2. KingbaseES 数据库连接

    一.数据准备: create table student( id int , s_name varchar(20), t_id int ); create table teacher( id int ...

  3. GraphQl in ASP.NET Core

    GraphQl in ASP.NET Core https://graphql.cn/ https://graphql-dotnet.github.io/docs/getting-started/ar ...

  4. 鸿蒙HarmonyOS实战-ArkUI组件(Progress)

    一.Progress Progress组件是一种用户界面(UI)元素,用于向用户显示某些任务的进度.它通常以进度条的形式出现,显示任务完成的百分比.Progress组件可以在确定任务持续时间未知的情况 ...

  5. Matplotlib绘图设置---图形颜色和风格调整

    绘图函数 plt.plot()函数可以通过相应的参数设置绘图风格. plt.plot(*args, scalex=True, scaley=True, data=None, **kwargs) Doc ...

  6. web.xml最新配置文件

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmln ...

  7. k8s 深入篇———— 编排[八]

    前言 简单整理一下编排. 正文 一个deployment 例子: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployme ...

  8. 跨域是什么?Vue项目中你是如何解决跨域的呢?

    一.跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能 所谓同源(即指在同一个域)具有以下三个相同点 ...

  9. Redis基础(一)——字符串、hash类型的基本使用

    day09--Redis Redis介绍和安装 # Redis:软件,存储数据的,速度非常快,Redis是一个key-value存储系统(没有表的概念),cs架构的软件 服务端 客户端(python作 ...

  10. 简单的使用Echars制作柱状图

    简单的使用Echars制作柱状图 html如下 <!DOCTYPE html> <html lang="en"> <head> <meta ...