记swoole数据库连接池消失问题的解决方式

问题背景:

    物联网项目saas,为分布式+集群模式.swoole(worker+task+协程) + web + mysql(pool) + 客户server(记为cserver,设备的数据最终会往cserver发送一份).

    有个法兰克福客户有三千台设备,想着该地区暂时没有新客户,所以只是单机部署,想着4核8g配置肯定够用了.

    周五收到通知,客户的3k设备集体掉线,紧忙分析+处理,此处记下笔记!

 

分析结果:

    根据日志很快速定位到问题所在,为客户所在cserver宕机,导致cserver不能正确处理swoole发送过来的数据.我们的swoole采用同步重发机制,保证数据是及时+稳定送达的.此机制导致短时间内,会有大量的重复信息在数据库中分析+分发,此过程耗尽了连接池中所有连接.而我们的每个数据库连接都为一个协程.

    swoole在没有设置max_coroutine参数的情况下,默认每个进程创建协程数量为3k.这就会导致协程数过多而致使task进程异常退出!从而该task对应的数据库连接池也全部断开连接!

        当task退出时,manager进程会重新拉起同样pid的task,此task会瞬间接受woker分配给刚才挂掉task所未能完成的包,这种瞬间式的堵塞导致task再次挂掉.manager重新拉起,task再挂掉,如此循环导致manager挂掉,当manager挂掉后,所有的task没有管理进程,当挂掉后无进程能够拉起,所有最后所有task挂掉,所有数据库连接断开.进而使得swoole的master守护进程依然在值守,却不再具备数据接收与处理的能力!即swoole变相挂掉,mysql也不能再重新拉起连接!

 

解决方案:

    • 根据模拟场景的慢日志,添加一些平时未注意的索引

    • 调整mysql max_connection参数,默认未224,我此前设置的为1000.当并发太大的时候,1k明显不够用了.

    • 调整mysql innodb_buffer_pool_size参数(数据和索引缓存的地方),当你的server只做mysql时,此值设置为内存的70%~75%.因为我是单机设备,设置为40%.

    • 适当加大了mysql  innodb_log_file_size参数值

    • 增大swoole中max_coroutine参数值,按常理,单worker能理想分配1g内存的时候,max_coroutine能设置成1w  乃至10w,因为一个coroutine默认为8k内存.

    • 增大swoole中task_worker_num,理想情况下,tasknum可设置为1000.根据你的task处理速度看着调整,我此处设置为50来应对突如其来的高并发.

    • 调整swoole中的worker_num,默认该参数为cpu核数,我平时也是这么设置的,明显,当我task_worker_num增大的时候,worker的压力也变大,所以我设置为cpu核数的2倍.

    • swoole_table的初始内存调整,这个设置不能在程序中动态调整,而每个连接id我这边都是在sw_tb中记录,所以初始化的大小需要大于未来几年设备最大量.

    • 新增managerStart和managerStop的回调,使得我们能更直观地观测manager的生命周期.

    • 对数据库连接池程序进行修改,尽量在抛出异常后妥善退出,而非导致worker/task的exit.

    • 保证连接池程序内部参数以接口的形式暴露给swoole,从而我们在可视化界面了解每个task的连接池情况

    • 对channel的errcode进行追踪,当errcode为-1的时候,打印error日志,-2的时候发送短信通知/微信魔板通知

    • swoole程序中对数据库连接池进行死链接排查

    • 增大mysql的连接最长空闲时间,保证它大于swoole程序中连接池的最长空闲时间.

    • 增加应急处理方案,即cserver宕机+swoole挂掉.此处我们的解决方案是,引导设备切换server到另一集群.(此处虽然是单机部署,但是也有个中央服务器是留作调控的. 不过周五此服务器未起作用是因为,中央服务器我这有个调控程序,使得符合条件在若干时间后自动切换到相应服务器x,而此时x不是挂了吗? 所以就有个循环,设备一直处于离线状态!后面我们进一步完善了这个机制)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值