modb

【原创】modb 功能设计之“跨线程通信”

北慕城南 提交于 2019-11-30 12:15:31
在《 modb 功能设计之“支持多消费者单生产者” 》中曾提到,需要解决“rabbitmq 线程与 sql 执行线程之间的跨线程通信手段”。本文针对这个问题进行一些说明。 【第一个版本】 使用 pipe 作为跨线程通信方式, 使用如下代码来支持 pipe: # 使用 _pipe 来模拟 pipe #if defined(WIN32) || defined(_WIN32) #include <io.h> #include <fcntl.h> #define pipe(fds) _pipe(fds, 4096, _O_BINARY) #endif 此时运行实现了 sql 线程的 demo,发现 sql 线程总是无法正常运行,在调用 libevent 接口 event_base_dispatch 时会有错误 “10038” 报出。最终查出的结论是: WSAENOTSOCK (10038) Socket operation on non-socket. 操作试图不是在套接字上进行。它可能是套接字句柄参数没有引用到一个合法套接字,或者是调用 select() 函数时,一个 fd_set 中的成员不合法。 查来查去,结果发现,就是 windows 下不能将 pipe(其实是 _pipe)和 select 一起使用的原因。因为 windows 平台上会认为 pipe 产生的 fd 不是一个合法的

【原创】modb 功能设计之“多级 modb 之间的同步”

为君一笑 提交于 2019-11-30 12:15:13
modb 在最初设计中采用的是两级模型,但很快就遇到了多级同步的需求。解决多级同步问题首先需要引入多级路由 key ,即将原来两级模型中的单个 key 值扩展为 key 的 array ,具体变化如下: 两级使用的数据格式 { "src" : "172.16.80.111", "keys" : "key_1", "app" : "A", "state" : "transfer" "sql" : "insert into users values(?,?,?)"; "sql-args" : [1, 2, "abc"] } 多级使用的数据格式 { "src" : "172.16.80.111", "keys" : ["key_1","key_2"] "app" : "A", "sql" : "insert into users values(?,?,?)"; "sql-args" : [1, 2, "abc"] } 而在 modb 的业务逻辑处理中也需要增加相应的处理,具体如下: 假设处理的是三级数据同步情况,分别为 modb-A 、modb-B 和 modb-C 三级平台域(分别位于三级服务域中),且 A 是 B 的上级,B 是 C 的上级。A 级平台域中某业务对数据进行了变更,然后需要将此变更信息同步到 B 和 C 级平台域。 通过数据操作入口进行数据变更后,将发送如下消息给

【原创】modb 中日志的设计

让人想犯罪 __ 提交于 2019-11-30 12:14:55
【日志格式】 在 之前 确定好通信所用的 json 数据格式后,到 确定 最终生成的 日志内容的时候了。之前提到日志内容至少要包括下面几点: 日志记录的时间戳( 在本地生成 ) 日志的“流向”(从哪里来,到哪里去)->( 从本地各种 app 来,到外部云去 ) sql 语句本身( JSON 数据中携带 ) sql 语句的执行情况( 分成:直接在 MySQL 上执行成功后在 modb 上记录;通过 modb 向 MySQL 发送执行命令后记录 )->(OK/ERR) 其实需要思考的问题只有“用哪些信息表明日志流向”而已。modb 作为基于 rabbitmq 的、消息转发处理服务,“流向”只能通过消息内容本身获得,即通过 JSON 消息体中相关字段指明。通过上面定义的 JSON 数据结构,可以得到消息来源自哪个 app ,对应 ip 地址,以及路由消息时的 routing_key(rk) 。 关于时间戳如何获取,在各类开源项目中具有类似的程序可参考,无外乎使用 C 库中定义的 标准 API 进行组合。具体的获取方式可以参考:《 C语言时间函数简介 》。 关于 json 数据的解析使用的是 jansson 开源项目。关于各种开源 json 项目的简单比较可以参考:《 各种 JSON 解析库的功能简介 》。 而写日志的相关代码,参考了 Redis 中实现的 log 机制并与 Atlas

【原创】modb 功能设计之“支持对sql语句的相关日志记录”

随声附和 提交于 2019-11-30 12:14:42
在《 modb 开发之需求和总体设计 》中,第三个要实现的功能点就是 “ 支持对 sql 语句的相关日志记录 ”。下面就讲解下设计这个功能的。 【需求分析】 终于到了处理 sql 日志的阶段了,万里长征重点的关键一步。 需要考虑解决的问题点如下: 在哪个模块上做 sql 日志记录 都要记录哪些信息才能做到跨机房数据同步时,具有可查询、可分析、可监控的目的 sql 日志记录的模式或者说频率 针对 MoDB 要做跨机房数据的同步这个功能,那么可以对 sql 语句进行记录的“地方”有: modb 应用中 Atlas 应用中 其中 Atlas 目前已支持 sql 日志的记录,格式如下: [11/25/2013 14:58:54] C:172.16.80.111 S:127.0.0.1 OK 0.155 "SET NAMES utf8" 其中所涵盖的内容包括:时间戳、源和目的 ip 地址、查询对应的应答状态信息、查询耗时,以及查询语句本身。 Atlas 会对所有经由 Atlas 发往 MySQL 服务器的类型为 COM_QUERY 的查询按照上述形式进行记录。 而 modb 中对 sql 的日志记录需要自己实现。 从总体设计上讲,访问 Atlas (访问 MySQL 数据库)的入口有两处:一个是通过 modb 进行访问;另一个是各种业务应用程序直接访问。 而只有经由 modb 访问

【原创】modb 功能设计之“支持部分MySQL客户端协议”-1

那年仲夏 提交于 2019-11-29 09:55:33
在 《 modb 功能设计之“支持多消费者单生产者” 》中说到:需要有一个单独的线程来处理 sql 语句。本文就针对“ 支持部分 MySQL 客户端协议”做第一部分讲述。 最初的想法是,rabbitmq 客户端从 queue 消费到了包含 sql 语句的消息后,需要提取并分析该 sql 后,通过 MySQL 协议再要求数据库执行该 sql 语句。这就要求我这个 demo 必须实现了 MySQL 客户端侧所需的协议部分。要实现这个,有三种途径: 利用公司已有的 dbi 的库实现 MySQL 访问 基于 mysqlclient 库做开发实现 MySQL 客户端侧协议 自己实现 MySQL 客户端侧需要的协议 我的选择: 不打算用公司的 dbi 库,首先,该库基于了其他的公司库,而我并不想使用;其次,该库封装的也不是很好,之前我还查出了 4 处崩溃,不排除还有其他问题;最后,该库其实也是在 mysqlclient 上做的封装,和上面第 2条其实是一样的。所以,最终我决定选择第 2 种方式,自己搞个“山头”出来。 PS:其实开始的时候也想过采用上面的第 3 种方式,自己从底层开始实现如何支持 MySQL 客户端协议,结果“呵呵”了,难度和工作量不是一般的大~~ 确定基于什么来做开发后,该做下一步目标选择了: 直接使用 mysqlclient 提供的 API