一、背景

很久以前写了DAO框架和MVC框架,前段时间又重写了DAO框架-GDAO(手写DAO框架(一)-从“1”开始,源码:https://github.com/shuimutong/gdao.git)和MVC框架-GMVC(手写MVC框架(一)-再出发,源码:https://gitee.com/simpleha/gmvc.git)。

之前也尝试过写RPC框架(源码:https://github.com/shuimutong/grpc_beta.git),客户端、服务端的方法调用写完了,但是网络传输没有写。

其实写框架也好,写博客也好,主要是为了学习。所以现在再开始的时候,我就在思考写什么好?

我的想法很简单:把目前用到的框架,能自己实现的尽量都实现一遍。站在这个时间点,写哪个框架有两个选择:继续写RPC;写MQ。这两个框架个人认为有很多相似的地方:MQ虽然是异步的,其实也是有“长连接”在连着的。比如订阅方,会有长连接连着MQ的服务端。RPC框架不分订阅、发送,而是客户端、服务端,当客户端找到服务端之后,客户端会尽量和服务端保持连接。

相比MQ,RPC框架不需要持久化的动作,而MQ不仅需要考虑持久化,还需要考虑如何进行高效的持久化。

通过一番对比,我最终选择实现MQ框架,以学习序列化、网络传输、高效持久化方面的知识。选择的参照框架是kafka。

二、如何下手

既然选择了实现MQ,那从何下手呢?

先了解一下kafka吧。

1、mq框架大致流程

生产方和服务端建立连接,将消息发送到服务端。

订阅方和服务端建立连接,服务端将订阅方订阅的消息推送给订阅方,或者订阅方自己拉取指定的消息。

2、了解一下kafka

1)为什么kafka有如此高的qps

kafka服务可以部署在机械硬盘上,接收到的每条消息都会存盘,但是qps可以轻松过万,甚至达到百万级别(数据来源于网上,本人暂未亲测)。怎么做到的?

通过官网可以了解到,我记录的有3点。

首先,采用磁盘顺序读写。其次,基于java,使用堆外内存,避免gc的干扰。再次,所有数据写两份,防止丢失。此外,还有零拷贝技术等。

以上各个方面结合起来,最终成就了kafka的英名!

2)是推消息还是拉消息

推消息的话,如果消息骤增,可能导致订阅方崩掉,所以kafka采用的是拉的方式。以什么频率拉,由订阅方自己决定。

其实采用拉消息的方式也有缺点,比如订阅方为了拉消息,就会一直在哪里循环请求。如果没有新消息,订阅方就会频繁的请求,白白浪费资源。

针对这个循环空请求的问题,kafka增加了一个特性。当拉消息的时候,可以设置:如果没有消息,就先夯住请求,等到消息来了,再返回结果。这样,就能够避免这类问题了。

3、写框架计划

在稍微看了kafka之后,感觉这个技术含量还是很高的。虽然上面只列了几点,其实还有很多很重要的点没有提及。但是,我就是要学写。如果等我先把kafka看透之后再写,那可能得等很长时间。(其实我已经磨蹭了很长时间)

所以我决定,先把架子搭起来。万丈高楼也得平地起!

1)大致方案

写服务端,网络传输使用http,序列化使用json(传输字符串,其实无所谓json),数据持久化使用DB。

虽然使用http传输,但是需要封装成具体的工具,避免客户端自己写请求工具,方便后期升级。

2)生产方发消息

消息包括:主题、消息内容

3)订阅方拉消息

主题、消息内容、offset(拉多少条)

4)服务端处理

消息来了之后,将消息存在DB,编offset。

拉消息动作,根据offset,返回取的多少条。

offset的提交应在客户端里进行封装,可先实现为自动提交。

5)框架组成

a、服务端

b、生产消息客户端(服务配置)

c、消费消息客户端(服务配置)

6)配置项

a、服务地址

b、主题号

大致计划已定,那就开始实现吧

三、服务端功能梳理

1、注册主题号

校验主题号是否存在,不存在则新增

2、接收消息

参数:主题号、消息体

先校验主题号是否存在,存在则保存消息到DB,然后返回结果

3、拉消息

参数:主题号、offset、希望取的消息数量

校验主题号是否存在,校验offset是否正常,正常则返回希望的消息数量(如果有消息)。

4、更改offset

参数:主题号、offset

校验主题号是否存在,校验offset。

重复消费功能后期做。

四、结语

关于手写MQ,暂时想的就这么多,后面想到其他的再加上。

先实现一个简易的服务端,接下来就是代码实现了。

写代码中……

第一个版本在上周写完了,欢迎指教->手写MQ框架(二)-服务端实现

手写MQ框架(一)-准备启程的更多相关文章

  1. 手写MQ框架(二)-服务端实现

    一.起航 书接上文->手写MQ框架(一)-准备启程 本着从无到有,从有到优的原则,所以计划先通过web实现功能,然后再优化改写为socket的形式. 1.关于技术选型 web框架使用了之前写的g ...

  2. 手写MQ框架(三)-客户端实现

    一.背景 书接手写MQ框架(二)-服务端实现  ,前面介绍了服务端的实现.但是具体使用框架过程中,用户肯定是以客户端的形式跟服务端打交道的.客户端的好坏直接影响了框架使用的便利性. 虽然框架目前是通过 ...

  3. 手写MQ框架(四)-使用netty改造梳理

    一.背景 书接上文手写MQ框架(三)-客户端实现,前面通过web的形式实现了mq的服务端和客户端,现在计划使用netty来改造一下.前段时间学习了一下netty的使用(https://www.w3cs ...

  4. 手写 jQuery 框架

    1.测试页面; <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  5. 手写DAO框架(三)-数据库连接

    -------前篇:手写DAO框架(二)-开发前的最后准备--------- 前言 上一篇主要是温习了一下基础知识,然后将整个项目按照模块进行了划分.因为是个人项目,一个人开发,本人采用了自底向上的开 ...

  6. 手写DAO框架(二)-开发前的最后准备

    -------前篇:手写DAO框架(一)-从“1”开始 --------- 前言:前篇主要介绍了写此框架的动机,把主要功能点大致介绍了一下.此篇文章主要介绍开发前最后的一些准备.主要包括一些基础知识点 ...

  7. 手写DAO框架(一)-从“1”开始

    背景: 很久(4年)之前写了一个DAO框架-zxdata(https://github.com/shuimutong/zxdata),这是我写的第一个框架.因为没有使用文档,我现在如果要用的话,得从头 ...

  8. 手写DAO框架(四)-SQL执行

    -------前篇:手写DAO框架(三)-数据库连接--------- 前言 通过上一篇写的方法,可以灵活的获取.释放数据库连接,拿到连接之后,我们就可以执行sql了!所以,本篇介绍的就是SQL执行器 ...

  9. (二)springMvc原理和手写springMvc框架

    我们从两个方面了解springmvc执行原理,首先我们去熟悉springmvc执行的过程,然后知道原理后通过手写springmvc去深入了解代码中执行过程. (一)SpringMVC流程图 (二)Sp ...

随机推荐

  1. RSA前台加密后台解密的应用

    写在前面 项目安全测试需要将登录功能修改, AES加密不符合要求, 现改为RSA非对称加密.(将登录密码加密后传给后台, 后台解密后再进行一系列的校验) .期间遇到了前台js加密但是后台解密失败的问题 ...

  2. yum -y install pip No package pip available. Error: Nothing to do

    centos下安装pip时失败: [root@wfm ~]# yum -y install pipLoaded plugins: fastestmirror, refresh-packagekit, ...

  3. CentOS7.6 X64搭建mysql服务

    1.官方安装文档 http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/ 2.下载 Mysql yum包 http://dev.mysql.co ...

  4. C# RSA 无 长度限制 加密解密 示例

    RSA 是一种非对称加密算法.由于算法特性,加密和解密过程用不同密钥,即公钥和私钥,而被广泛应用于数字证书的安全管理. 在具体应用中,公钥用加密而私钥用于解密,或 私钥用于数字签名而公钥用于签名验证. ...

  5. x3d

    目录 3d format introduction x3d resources open source C++ implementations file formats 1. Feature matr ...

  6. 多线程高效合作之master-warker模式

    对于高并发的任务,有些任务是相互独立的,任务与任务之间没有依赖关系,因此可以采用 master - worker 模式. master 用于接受任务和分发任务给 worker,并将 worker 返回 ...

  7. but only one is allowed(重复处理跨域请求)

    情景:vue的项目中在本地调试项目,在前端的跨域配置没有问题的情况下,出现这样的报错. 解决方案,参考: https://www.cnblogs.com/zsg88/articles/11576324 ...

  8. .NET 小程序微信用户支付

    微信支付有两种模式:微信用户主动发起的支付.签约委托支付协议后自动支付. 自动支付又分为两种:首次支付时签约.纯签约. 首次支付时签约和纯签约在后续周期若需要发起自动扣款时,需要在应用服务中发起申请扣 ...

  9. js:如何在iframe重载前执行特定动作

    问题说明: 点击左侧菜单时,右侧页面中的iframe加载菜单内容,在iframe加载的页面A中使用了websocket.点击其它菜单时,无法主动关闭websocket, 可能会造成websocket链 ...

  10. idea 打开eclipse 项目 编译出现 Error:(1, 1) java: 非法字符: ‘\ufeff’

    原因分析: Eclipse可以智能的把UTF-8+BOM文件转为普通的UTF-8文件,IDEA没有这个智能转换. 解决: 1 用IDEA转换,先转换为GBK,再转回UTF-8