苏州网站建设如何选择,wordpress各个页面名称标签,哪个网站专门做灵异文,宁夏高端网站建设大部分做后端开发的朋友#xff0c;都在开发接口。客户端或浏览器h5通过HTTP请求到我们后端的Controller接口#xff0c;后端查数据库等返回JSON给客户端。大家都知道#xff0c;HTTP协议有短连接、无状态、三次握手四次挥手等特点。而像游戏、实时通信等业务反而很不适合用…大部分做后端开发的朋友都在开发接口。客户端或浏览器h5通过HTTP请求到我们后端的Controller接口后端查数据库等返回JSON给客户端。大家都知道HTTP协议有短连接、无状态、三次握手四次挥手等特点。而像游戏、实时通信等业务反而很不适合用HTTP协议。 原因如下 1HTTP达不到实时通信的效果可以用客户端轮询但是太浪费资源2三次握手四次挥手有严重的性能问题3无状态。
比如说两个用户通过App聊天一方发出去的消息对方要实时感知到消息的到来。两个人或多个人玩游戏玩家要实时看到对方的状态这些场景用HTTP根本不可能实现因为HTTP只能pull即“拉”而聊天、游戏业务需要push即“推”。
随着业务蓬勃发展用户的不断增多用户创建的群、加入的群和好友不断增多和聊天活跃度的上升某些用户不在线期间产生大量的离线消息尤其是针对群聊离线消息特别多。
等下次客户端上线时服务端会给客户端强推全部的离线消息导致客户端卡死在登录后的首页。并且产品提出的需求要扩大群成员的人数由之前的百人群扩展到千人群、万人群等。
这样一来某些客户端登录后必定会因为大量离线消息而卡死用户体验极为不好。 和客户端的同事一起分析了一下原因 1用户登录服务端通过循环分批下发所有离线消息数据量较大2客户端登录后进入首页需要加载的数据不光有离线消息还有其他初始化数据3不同价位的客户端处理数据能力有限处理聊天消息时需要把消息存储到本地数据库并且刷新UI界面回复给服务端ack消息整个过程很耗性能。
客户端登录卡顿的主要原因是服务端会强推大量离线消息给客户端客户端收到离线消息后会回复服务端ack然后将消息存储到本地数据库、刷新UI等。客户端反馈即使客户端采用异步方式也会有比较严重的性能问题。即时通讯聊天软件app开发可以加小蓝豆的vweikeyun24咨询
为什么客户端收到消息后还没有将数据存储到数据库就回复给服务端ack很有可能存储失败这本身不合理这是其一。其二服务端强推导致客户端卡死不关心客户端的处理能力不合理。
int max 100; //从新库读 while(max 0) { ListOfflineMsgInfo offlineMsgListNew shardChatOfflineMsgDao.getByToUid(uid, 20); if(CollectionUtils.isEmpty(offlineMsgListNew)) { break; } handleOfflineMsg(uid, offlineMsgListNew, checkOnlineWhenSendingOfflineMsg); max--; }
既然强推不合理我们可以换一种方式根据客户端不同机型的处理能力的不同服务端采用不同的速度下发。
我们可以把整个过程当成一种生产者消费者模型服务端是消息生产者客户端是消息消费者。客户端收到消息将消息存储在本地数据库刷新UI界面后再向服务端发送ack消息服务端收到客户端的ack消息后再推送下一批消息。
这么一来消息下发速度完全根据客户端的处理能力分批下发。但这种方式仍然属于推方式。
然而理想很丰满现实却很骨感。
针对这个方案客户端提出一些问题 1虽然这种方案客户端不会卡死但是如果当前用户的离线消息特别多那么收到所有离线消息的时间会非常长2客户端每次收到消息后会刷新界面很有可能客户端会发生界面上下乱跳的画面。
最后我们也对消息ack的逻辑进行了优化。
优化前服务端采用push模型给客户端推消息不论是在线消息还是离线消息ack的逻辑都一样其中还用到了kafka、redis等中间件流程很复杂我在这里就不详细展开介绍ack的具体流程了反正不合理。
离线消息和在线消息不同的是我们不存储在线消息而离线消息会有一个单独的库存储。完全没必要用在线消息的ack逻辑去处理离线消息反而很不合理不仅流程上有问题也浪费kafka、redis等中间件性能。
优化后我们和客户端决定在每次下拉加载离线消息时将收到的上一批离线消息的msgId或消息偏移量等信息发送给服务端服务端直接根据msgId删除离线库中已经发送给客户端的离线消息再返回给客户端下一批离线消息。
另外我们还增加了消息漫游功能用户切换手机登录后仍然可以查到历史消息这部分内容我就不展开详细介绍给大家了。