企业微信会话归档 结构设计与实现
前言: 本司接受某会监管,每年都会进行场地检查。
销售售卖产品的整个流程,聊天语音等要求全部留痕,检查时提供进行查阅。
3年前都是销售都是通过电话销售,后面过渡为企业微信进行销售售卖。

企业微信提供 会话归档 功能,帮助企业进行消息留痕

接口详情 获取会话内容&获取媒体文件

先放出整体流程

企业 微信 架构 企业微信架构是什么_企业 微信 架构

共3个服务,这样设计的好处是,三个服务完全分离,处理会话内容与 处理媒体文件 可服务多开,提高消息即时性

1. 获取会话内容服务
因为消息有很多,所以不考虑接入回调,采用循环拉取接口,拉取消息后,直接放入消息队列 MQ 中
2. 处理消息服务
接入MQ,消费消息 包括解密消息,入库 ES, 消息敏感敏感词通知,提取文件消息入文件的消息队列 MQ
1. 解密入库es
    一条mq消息中最多1000条会话内容消息,处理后插入 ES
2. 提取敏感词通知
    
3. 提取文件类消息,得到 Md5Sum 值,生产媒体件 MQ
3. 处理媒体文件服务
接入 MQ,消费消息, 包括文件下载,上传对象存储, 入库 ES
媒体文件消息处理是比较复杂的一个模块功能,要考虑到以下几点:
1.文件去重以及服务多开时,文件下载重复问题
    每天的营销素材,或是表情GIF 图片,很多重复的文件,不能把所有文件全部下载,那样太占存储空间,微信提供 MD5Sum 值,可进行去重处理
    还有服务多开时,两个服务可能同时会得到相同的 MD5Sum 值,导致大家一起下载和上传,导致的资源浪费
    解决:采用 redis 分步式锁,setnx 命令,EXPIRE为24小时。 这样能够保证所有服务同一时间不会处理相同的文件
         sys.Redis().Do("SET", rkMidTagLock.Key, 1, "NX", "EX", expInt)
         可是这样又会导致一个新的问题: 
         服务重启时,文件被锁,虽然 MQ 消费到此 MD5Sum 值,但是发现文件已被抢占,导致文件漏下(看2)

2.服务重启时,未处理完成的文件如何让它下次再次下载
    解决:服务关闭前走优雅关闭,捕捉关闭信号,清除所有分布锁,
         下次文件下载时,先抢占锁,然后去 ES 中查询是否已经被下载,如果不存在,则进行后续处理

3.微信未给文件提供 MD5Sum 值
    有些时候企业微信并未提供文件 MD5Sum 值, 导致文件在对象存储中被覆盖
    解决:未提供 MD5Sum 值时,自己随机一个值,不过这样无法进行文件去重。

4.大文件单线程下载
    当文件过大时,微信提供的文件单线程下载接口已经不能满足需求,表现为:
    文件过大时,分片下载时间过长,消息实时度过低,同时也会导致MQ消费超时
    解决:分析接口请求参数,自己算出每个文件的间隔区间,进行多线程请求
         同时采用 channel 进行最大下载数量限制,否则机器撑不住会崩
         具体代码逻辑可见,上一篇文章