V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lbmjsls1
V2EX  ›  C++

c++如何应付系统起来时的瞬时并发

  •  1
     
  •   lbmjsls1 · 2020-06-18 20:28:41 +08:00 · 2553 次点击
    这是一个创建于 1620 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景是这样,

    比如有 2000 个客户端在线上,服务端需要重启维护,客户端是自动重连。

    这样服务端重启后需要瞬间处理 2000 个请求,包括初始化,登录等,这时还有其他的请求和逻辑需要处理,就会导致有的连接因为心跳超时断开又重新登录;而有的逻辑因为资源抢占,没有得到处理,又会在下一次调用放到检测队列。就像网络堵车一样,慢慢把系统耗死了。

    服务器架构是 IOCP,mysql 数据库,没用 redis

    请问 c++服务端有什么框架或是类库或是技术可以应对这种问题吗

    17 条回复    2020-06-19 17:41:37 +08:00
    whileFalse
        1
    whileFalse  
       2020-06-18 20:32:14 +08:00
    客户端指数退避
    BBCCBB
        2
    BBCCBB  
       2020-06-18 20:37:19 +08:00
    客户端断开连接后随机一个时间再重连.
    lbmjsls1
        3
    lbmjsls1  
    OP
       2020-06-18 20:38:03 +08:00
    @whileFalse 客户端目前无法修改
    whileFalse
        4
    whileFalse  
       2020-06-18 20:39:10 +08:00
    @lbmjsls1 服务端只有一台?多台可以轮流重启。
    swulling
        5
    swulling  
       2020-06-18 20:42:24 +08:00 via iPhone
    客户端无法修改就直接拒绝掉,使用令牌桶

    逐渐发出 100 200 300 到 2000 的令牌,抢到令牌的客户端处理,其他拒绝让它重试去

    但是最好的架构是客户端收到拒绝后自己 delay 重连
    lbmjsls1
        6
    lbmjsls1  
    OP
       2020-06-18 20:42:58 +08:00
    怎么找不到 append 了,我再说一下,客户端目前无法修改,就一台服务器
    byaiu
        7
    byaiu  
       2020-06-18 20:43:13 +08:00
    解决瞬时毛刺的方法就一个套路,排队,也叫 buffer 。
    至于这个排队是怎么表现的,就会有各种方法了。
    可以专门拉一个进程出来负责连接管理。
    lbmjsls1
        8
    lbmjsls1  
    OP
       2020-06-18 20:45:39 +08:00
    @swulling
    @BBCCBB
    @whileFalse
    多谢,目前客户端延时重连算是一个解决方案了。还有一个就是类似于秒杀的,同时有 1k 或是 2k 的请求过来,如何处理呢。这样不适合让连接进来的客户端等一会再发消息吧
    ljpCN
        9
    ljpCN  
       2020-06-18 20:48:17 +08:00
    @lbmjsls1 队列吧,开个进程专门往队列里喂。然后服务进程一个个地消费这个队列。
    xy90321
        10
    xy90321  
       2020-06-18 20:52:58 +08:00 via iPhone
    如果服务器本身顶得住 2k 的 inbound 连接,那你只需要加个前置处理(代理)批量放行就好了,到处理上限了就 deny,反正客户端会自己再重连。

    如果服务器本身扛不住 2k 的 inbound 连接直接就没响应了,那说什么都白搭。

    此处服务器代指包括网络规格等等在内的各种 infra 。
    billlee
        11
    billlee  
       2020-06-18 21:15:56 +08:00
    可以把 2000 个 TCP 连接接下来,但应用层排队处理,只要不在应用层分配缓冲区、线程什么的,维持 2000 个 TCP 连接应该是没问题的。
    Mohanson
        12
    Mohanson  
       2020-06-18 21:21:45 +08:00
    =服务器前面挂一个反向代理, 反向代理里限制一下并发数就好了.
    gamexg
        13
    gamexg  
       2020-06-18 21:26:42 +08:00 via Android
    服务器设置个最大连接数限制
    服务器接受新链接时检查,超过限制则拒绝连接

    服务器启动时,慢慢的增加这个值。
    securityCoding
        14
    securityCoding  
       2020-06-18 21:28:43 +08:00
    考虑应用层做下性能优化吧 ,
    opengps
        15
    opengps  
       2020-06-18 21:51:26 +08:00 via Android
    iocp 使用到位就已经从架构上最优了,承载几万链接很轻松。
    此刻你想问的显然不是同时连接数的问题,而是服务器重启瞬间的,每秒新建连接数问题,你应当换个角度考虑,首先服务器不应当是经常重启的,因此不必太在意刚重启动那一会的故障。
    你只是想解决并发创建连接比较慢的问题,这个问题确实是有,但是不是程序要做的,而是你需要通过负载均衡等设备,使用多个服务端来对外表现成无故障
    我经历过几万链接单机重启时候恢复慢的场景,重启一次服务器,cpu 爆满,半个小时才能降低下来,最终实现的集群,尽可能逐步后台切换新程序,而不是一下子关闭老程序。当然,方式也有不兼容升级的时候,这时候不得不停机,忍受半个小时的不正常
    66450146
        16
    66450146  
       2020-06-18 22:33:23 +08:00
    在用户少的时候重启维护就行了
    exmario
        17
    exmario  
       2020-06-19 17:41:37 +08:00
    线程池 /连接池之类,池子满了就等待咯
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   922 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 19:56 · PVG 03:56 · LAX 11:56 · JFK 14:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.