关于系统并发问题,请各位 V 友帮忙分析下。

353 天前
 SANJI59

公司业务是物联网方向的,开发产品是共享充电桩,现在系统到了瓶颈期目前已经部署的在线设备量 1500 台左右系统预计部署 1w+。最近发现随着设备量的递增系统方面出现了 BUG ,不确定是否是并发问题还是程序代码问题,五一前以为是 SQL 问题然针对慢 SQL 一顿优化可以系统卡顿问题已解决,但是设备消息处理问题还是没解决,1000 台设备在线 30 秒最少有 1000 条消息。也没确定出现问题的原因。 业务流程是这样的,用户小程序扫码设备进入选择充电界面这时候会连接一个 WebSocket 并订阅一个设备的消息主题。当用户选择端口开启充电时,服务器会下发指令给设备,设备开启充电时会返回开启端口成功的指令到服务器,在服务再将消息处理之后使用 ws 推送给前端小程序表示订单已开启。 目前出现的问题是用户扫码开启端口充电时后台没有推送 WS 消息,导致订单处于为正常开启的状态(故障)其实设备已经回复开启成功了但是服务器还没有处理过来。出现问题的时间都是高峰期(下午六七点)。系统到这个点进行中订单有 800 多个。但是系统有时候会出现此问题有时候有没有。 目前问题不好确定导致不好下手解决,根据观察到的问题可能是出在高并发,WebSocket 使用的 Java 开发,处理设备业务消息使用线程池,WebSocket 、单服务、服务器 8 核 16G 。麻烦各位 V 友帮忙分析下。有好的设计思路和框架也可以向我提供。我可以跟公司申请有偿

1755 次点击
所在节点    问与答
33 条回复
opengps
353 天前
主要就是找到瓶颈点,逐个击破即可
具体问题点出在哪,单看这段问题是没办法准确定位的
opengps
353 天前
我现在能盲猜到一个因素是,你现在的 websocket 建立连接太慢
brader
353 天前
ws 断线重连机制做了吗?心跳机制做了吗?及时剔除下线客户端,减轻 ws 连接列表维护的压力,然后记录一下 ws 连接数或者开个服务可以查询到连接数,还要记录或者能看到一次请求过来到响应的具体时长,观察下高峰期的数据,以及服务器的 cpu ,内存,带宽状况
shore507
353 天前
你这种情况建议长连接的服务就不要自己做了,用云服务比较好。另外从业务上来说,你小程序上的 ws 其实不是必要的,用户支付后用 api 获取订单详情即可,从业务流程上想办法省掉 ws 应该是可行的
bootvue
353 天前
这种场景不适合 ws 吗 改造成 mqtt
bootvue
353 天前
@bootvue
pubby
353 天前
java 增加日志记录订单对应的 ws 消息是否发送成功

小程序不在前台 5s 后会断开 ws ,不知道扫码唤起摄像头过程会不会出现这种情况

小程序再加个 http api 轮询机制,主动查看设备是否已成功打开,不要只依赖 ws 消息
SANJI59
353 天前
@pubby 是的,主要这个问题还不好复现,现在系统又没问题由于在运营中也不好随便更新😂😂
SANJI59
353 天前
@bootvue 嗯嗯有这个想法。现在猜测 ws 可能有问题,但是系统出现的问题没法复现,不好下手。
hhjswf
353 天前
盲猜不是性能问题,代码的问题
SANJI59
353 天前
@brader 这些都做了,服务器够大跑单体是没问题的。估计代码哪里有问题吧
liqinliqin
353 天前
这个用 swoole 最好,
git00ll
353 天前
http 轮询好了,这点并发量肯定没啥问题的
corningsun
353 天前
服务器会下发指令给设备,设备开启充电时会返回开启端口成功的指令到服务器,在服务再将消息处理之后使用 ws 推送给前端小程序表示订单已开启

改成

服务器下发指令给设备的同时推送给前端小程序表示订单已开启。

设备开启充电成功 /失败时,返回开启结果到服务器。如果失败了,再推失败的消息到小程序。
sujin190
353 天前
1500 个设备都很少了,话说都没写日志的么?你这描述了半天看起来也没弄清楚是设备给服务器回开启成功有问题还是服务器给小程序回开启成功有问题,你这设备接入用的 mqtt ?而且你小程序是用 ws 发送给的开启指令么?其实阿里云的 IOT 云的 RR 消息就很容易处理这种,小程序这边短时请求用 ws 确实费劲,几千台设备么单体服务也足够也不复杂
SANJI59
353 天前
@sujin190 是的用的 MQTT ,生成订单的时候服务器就会下发指令给设备开启端口。服务器收到设备开启端口的返回指令之后将该消息处理之后再使用 ws 推给小程序。这个小程序收不到消息的问题时而有时而没有。
sujin190
353 天前
@sujin190 #15 那就是说小程序其实是通过单独的 http 接口创建订单然后给设备发送指定的,那话说你怎么保证这时候 ws 是已经建立好的了啊?那会不会高峰期无论是带宽紧张还是应用负载原因导致 ws 建立成功时间变长了那是不是要出错了?设备执行命令成功给服务器通知结果其实应该是更新数据订单状态了吧,小程序通过数据库订单信息补偿就好了啊
sujin190
353 天前
@SANJI59 #16 其实如果订单通过 http 请求发送的话,结果通过一个 long poll http 接口来获取应该是更简单可靠的

https://segmentfault.com/a/1190000041190907

我们直接也搞过不少这种,还是 http long poll 更方便,搞过 openrest 的,用 spring boot 的话担心连接占用过多线程,其实可以用 DeferredResult ,工作线程会被释放,连接放到底层 nio 了,也可以支持大量并发请求
yishengyongyi
353 天前
1000 台设备太少了,现在充电桩市场都饱和了,随便几万就能买一套源码,能带上万台设备
cheng6563
353 天前
推送本来就是要和轮训配合同时使用的,只单独靠推送就是这样非常不可靠。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/939148

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX