场景是这样,
比如有 2000 个客户端在线上,服务端需要重启维护,客户端是自动重连。
这样服务端重启后需要瞬间处理 2000 个请求,包括初始化,登录等,这时还有其他的请求和逻辑需要处理,就会导致有的连接因为心跳超时断开又重新登录;而有的逻辑因为资源抢占,没有得到处理,又会在下一次调用放到检测队列。就像网络堵车一样,慢慢把系统耗死了。
服务器架构是 IOCP,mysql 数据库,没用 redis
请问 c++服务端有什么框架或是类库或是技术可以应对这种问题吗
1
whileFalse 2020-06-18 20:32:14 +08:00
客户端指数退避
|
2
BBCCBB 2020-06-18 20:37:19 +08:00
客户端断开连接后随机一个时间再重连.
|
3
lbmjsls1 OP @whileFalse 客户端目前无法修改
|
4
whileFalse 2020-06-18 20:39:10 +08:00
@lbmjsls1 服务端只有一台?多台可以轮流重启。
|
5
swulling 2020-06-18 20:42:24 +08:00 via iPhone
客户端无法修改就直接拒绝掉,使用令牌桶
逐渐发出 100 200 300 到 2000 的令牌,抢到令牌的客户端处理,其他拒绝让它重试去 但是最好的架构是客户端收到拒绝后自己 delay 重连 |
6
lbmjsls1 OP 怎么找不到 append 了,我再说一下,客户端目前无法修改,就一台服务器
|
7
byaiu 2020-06-18 20:43:13 +08:00
解决瞬时毛刺的方法就一个套路,排队,也叫 buffer 。
至于这个排队是怎么表现的,就会有各种方法了。 可以专门拉一个进程出来负责连接管理。 |
8
lbmjsls1 OP @swulling
@BBCCBB @whileFalse 多谢,目前客户端延时重连算是一个解决方案了。还有一个就是类似于秒杀的,同时有 1k 或是 2k 的请求过来,如何处理呢。这样不适合让连接进来的客户端等一会再发消息吧 |
10
xy90321 2020-06-18 20:52:58 +08:00 via iPhone
如果服务器本身顶得住 2k 的 inbound 连接,那你只需要加个前置处理(代理)批量放行就好了,到处理上限了就 deny,反正客户端会自己再重连。
如果服务器本身扛不住 2k 的 inbound 连接直接就没响应了,那说什么都白搭。 此处服务器代指包括网络规格等等在内的各种 infra 。 |
11
billlee 2020-06-18 21:15:56 +08:00
可以把 2000 个 TCP 连接接下来,但应用层排队处理,只要不在应用层分配缓冲区、线程什么的,维持 2000 个 TCP 连接应该是没问题的。
|
12
Mohanson 2020-06-18 21:21:45 +08:00
=服务器前面挂一个反向代理, 反向代理里限制一下并发数就好了.
|
13
gamexg 2020-06-18 21:26:42 +08:00 via Android
服务器设置个最大连接数限制
服务器接受新链接时检查,超过限制则拒绝连接 服务器启动时,慢慢的增加这个值。 |
14
securityCoding 2020-06-18 21:28:43 +08:00
考虑应用层做下性能优化吧 ,
|
15
opengps 2020-06-18 21:51:26 +08:00 via Android
iocp 使用到位就已经从架构上最优了,承载几万链接很轻松。
此刻你想问的显然不是同时连接数的问题,而是服务器重启瞬间的,每秒新建连接数问题,你应当换个角度考虑,首先服务器不应当是经常重启的,因此不必太在意刚重启动那一会的故障。 你只是想解决并发创建连接比较慢的问题,这个问题确实是有,但是不是程序要做的,而是你需要通过负载均衡等设备,使用多个服务端来对外表现成无故障 我经历过几万链接单机重启时候恢复慢的场景,重启一次服务器,cpu 爆满,半个小时才能降低下来,最终实现的集群,尽可能逐步后台切换新程序,而不是一下子关闭老程序。当然,方式也有不兼容升级的时候,这时候不得不停机,忍受半个小时的不正常 |
16
66450146 2020-06-18 22:33:23 +08:00
在用户少的时候重启维护就行了
|
17
exmario 2020-06-19 17:41:37 +08:00
线程池 /连接池之类,池子满了就等待咯
|