go语言实现在线聊天 go语言教程( 四 )


哪些因素决定推送系统的效果?
首先是sdk的完善程度,sdk策略和细节完善度,往往决定了弱网络环境下最终推送质量.
SDK选路策略,最基本的一些策略如下:有些开源服务可能会针对用户hash一个该接入区域的固定ip , 实际上在国内环境下不可行,最好分配器(dispatcher)是返回散列的一组 , 而且端口也要参开,必要时候,客户端告知是retry多组都连不上,返回不同idc的服务器 。因为我们会经常检测到一些case,同一地区的不同用户,可能对同一idc内的不同ip连通性都不一样 , 也出现过同一ip不同端口连通性不同,所以用户的选路策略一定要灵活 , 策略要足够完善.另外在选路过程中 , 客户端要对不同网络情况下的长连接ip做缓存,当网络环境切换时候(wifi、2G、3G),重新请求分配器 , 缓存不同网络环境的长连接ip 。
客户端对于数据心跳和读写超时设置,完善断线检测重连机制
针对不同网络环境,或者客户端本身消息的活跃程度,心跳要自适应的进行调整并与服务端协商,来保证链路的连通性 。并且在弱网络环境下,除了网络切换(wifi切3G)或者读写出错情况,什么时候重新建立链路也是一个问题 。客户端发出的ping包 , 不同网络下,多久没有得到响应,认为网络出现问题 , 重新建立链路需要有个权衡 。另外对于不同网络环境下 , 读取不同的消息长度,也要有不同的容忍时间 , 不能一刀切 。好的心跳和读写超时设置,可以让客户端最快的检测到网络问题,重新建立链路 , 同时在网络抖动情况下也能完成大数据传输 。
结合服务端做策略
另外系统可能结合服务端做一些特殊的策略,比如我们在选路时候,我们会将同一个用户尽量映射到同一个room service实例上 。断线时,客户端尽量对上次连接成功的地址进行重试 。主要是方便服务端做闪断情况下策略,会暂存用户闪断时实例上的信息,重新连入的 时候,做单实例内的迁移,减少延时与加载开销.
客户端保活策略
很多创业公司愿意重新搭建一套push系统,确实不难实现,其实在协议完备情况下(最简单就是客户端不回ack不清数据),服务端会保证消息是不丢的 。但问题是为什么在消息有效期内,到达率上不去?往往因为自己app的push service存活能力不高 。选用云平台或者大厂的,往往sdk会做一些保活策略 , 比如和其他app共生,互相唤醒,这也是云平台的push service更有保障原因 。我相信很多云平台旗下的sdk,多个使用同样sdk的app,为了实现服务存活 , 是可以互相唤醒和保证活跃的 。另外现在push sdk本身是单连接,多app复用的,这为sdk实现 , 增加了新的挑战 。
综上,对我来说,选择推送平台 , 优先会考虑客户端sdk的完善程度 。对于服务端,选择条件稍微简单,要求部署接入点(IDC)越要多 , 配合精细的选路策略 , 效果越有保证,至于想知道哪些云服务有多少点 , 这个群里来自各地的小伙伴们,可以合伙测测 。
go语言开发问题与解决方案
下面讲下 , go开发过程中遇到挑战和优化策略 , 给大家看下当年的一张图,在第一版优化方案上线前一天截图~
可以看到,内存最高占用69G,GC时间单实例最高时候高达3~6s.这种情况下,试想一次悲剧的请求,经过了几个正在执行gc的组件,后果必然是超时... gc照成的接入方重试,又加重了系统的负担 。遇到这种情况当时整个系统最差情况每隔2,3天就需要重启一次~

推荐阅读