写一个Q

起因

最近一个项目中使用mq做多节点间消息的路由和转发,要求实时性比较强,包括pull和push两种模式,并且同一个topic需要支持多个业务线或者子功能调用。当前的选型和问题如下:

  • 希望对这个模块有完全的掌控力,不懂erlang,所以直接排除了目前生产使用的rabbitmq
  • 目前项目中使用的是rocketmq,对于使用项目和团队来说的优缺点:
    • 优点:
      • 基于java,方面随时查看源代码
      • 接口定义清晰
      • 消息堆积能力很强
      • 社区较活跃,有官方开发者长期维护和答疑
    • 缺点:
      • rocketmq对于这个应用来说占用资源太多,谁用谁知道
      • 管理和运维都比较重,比如rocketmq严重依赖文件系统,需要配置vm参数(比如由于一个参数忘记打开导致压力测试的时候频繁崩溃),相关的监控工具也只有rocket-console,而且不够好用。
      • 基于rocketmq二次开发或者定制一套工具类更重,而且由于是非广泛通用需求,多半不会被官方合并。

其它选择

业界有大量的mq产品可供选择,但对我来说或多或少用着都不太舒服。

  • activemq,java系,也是广泛使用的一个mq,一个字,太重
  • memcacheQ,微博用的比较多,是c系的,更像一个kv,不满足我的需求
  • nsq,golang编写,不保证消息严格有序(大部分mq其实都是这样做的,目前采用的roketmq也是如此),无单点,看上去很美好,但短时间内想做到细节可控不太容易
  • uq,搜索memcacheQ时搜到的,@招牌疯子作品。据说用于部分替代微博内部广泛使用的memcacheQ,但作者开源出来的也只是简化后的版本,在给uq贡献了一个java库后通读了一遍uq的代码,发现还是没有我想要的功能。

除此之外还有其它好多个mq可供选择,比如redis作者刚推出的disque。目前调研的产品,总而言之,要么太重难以动刀,而轻量级的几个又不满足我需要的几种场景。于是萌生了另造一个轮子的想法。

造个轮子

这个轮子应该是这样的:

  1. 语言方面: 不采用java,略看了下rocketmq的代码,想实现我要的功能用java写起来实在是个折磨。基于golang,最终编译成一个文件,方便运维等,同时利用语言模型带来的红利(如goroutine、channel)简化这个mq轮子的制造过程。
  2. 它应该满足的要求:
    • 消息的存储应支持内存和磁盘
    • 应该具备较高的性能和较低的延迟,以替换当前的rocketmq
    • 如文章伊始所说,一个topic或是queue应该可以被多个消费者消费,消息应支持回溯
    • 有比较全面的客户端支持,应优先支持java、go、node.js
    • 应支持多个协议,但优先级最高的应该是tcp和http,之后是redis等
    • 应该有一个好用的web ui以支持监控和管理

进展

参考其他几个框架,已实现了一个简陋的网络传输库,即一个简单的server/client模型,包括一个简单的重连和超时控制逻辑。

下一步着重实现消息协议设计,可参考以前使用java实现的一个rpc系统里的协议设计,即包头+定长消息体。序列化采用约定好的原生序列化来实现,也有可能采用protobuf。

待续。。。