psub_syn批订阅同步的实现

前言

最近有空在给skynet_fly_demo增加用户日志相关,用于记录游戏中产生的日志,比如用户登录登出记录道具增加,减少记录。我的想法是把用户日志对接上orm,这样写的日志的方便日志服采集后,根据orm设定的字段索引信息直接构建对接数据库orm,从而实现日志服无需修改就能采集新增或者变更的日志数据。这个过程就遇到一个问题,日志服如何同步到其他服务的日志orm信息。之前的subsyn监听同步模块,只支持监听指定通道名的数据,而对于orm日志数据对象会有多个,比如道具变更记录,玩家登录记录。按照监听一个通道名的做法就需要把数据全部汇聚到一个服务上然后进行pubsyn,这样做,缺点有2:1是增加了业务实现的复杂度,2是每次同步的数据量变大,有点牵一发而动全身的感觉。考虑再三,最终还是决定实现psubsyn

实现思路

实现思路借鉴了redis watch的psub 通配公式的习惯,例如name:*:address, 这样就能监听channel_namename:*:address, *可以任意(不包括*,:, 最好是字母和数字或者(_,-))的字符串。
对于name:age:address用组合的方式可以拆解出6通配公式

  1. *:age:address
  2. name:*:address
  3. name:age:*
  4. *:*:address
  5. *:age:*
  6. name:*:*

实现的方式就是通过推送端推送的channel_name拆解出匹配的通配公式,再用通配公式关联上channel_name, 这时候监听端通过psubsyn命令把需要监听的通配公式发到推送端推送端通配公式匹配的channel_name都同步给监听端监听端再逐个做subsyn监听同步。这样就实现psubsyn

使用例子

1
2
3
4
5
6
7
watch_syn_client.pwatch("frpc_s", "*:age:address", "handle-*:age:address", function(cluter_name, ...)
log.info("pwatch handle-*:age:address >>> ", cluter_name, ...)
end)

watch_syn_client.pwatch_byid("frpc_s", 1, "*:age:address", "handle-*:age:address", function(cluter_name, ...)
log.info("pwatch_byid handle-*:age:address >>> ", cluter_name, ...)
end)

使用注意点

由于psubsyn最终还是用subsyn,所以如果既要psubsyn,又要单独监听(subsyn)某一个的时候,此时psubsyn其实是包含subsyn监听的channel_name了,比如pwatch(*:age:address),watch(name1:age:address)。这时候不要用相同的handle_name,否决会出现pwatchwatch只有一个能收到name1:age:address的同步回调。


psub_syn批订阅同步的实现
https://huahua132.github.io/2025/04/03/skynet_fly_ss/psub_syn/
作者
huahua132
发布于
2025年4月3日
许可协议