最近还是有客户陆续问到高并发的解决方案的问题, 总体来说高并发是一种表现, 对于每个项目每个程序的处理方式都是不同的, 不能一概而论的说一种方法就能解决所有的高并发问题. 高并发的问题从根本上讲也可以说是成本的问题, 说白了就是用最少的钱接最多的客. 艾思软件结合最近解决的客户问题, 总结了以下几条常规思路, 让不懂这方面的客户有个大体认识.
1. 限流方式为限流接口即可:
因为http请求是无状态的, 一次请求完成后, 服务器会自动释放资源. 即使用户一直停在小程序的某一界面也不会对服务器造成压力, 所以只要在后台统计所有接口在某一时间内访问的数量即可
2. 统计多少数量时进行限流:
某一时间内统计多少数量开始限流, 这个需要对服务器的有代表性的, 频繁访问的接口(如首页的接口, 产品列表的接口, 产品详情的接口, 产品下单的一系列接口)进行压力测试, 设置的值比这个压力结果稍小.
3. 高并发优化的建议:
服务器的高并发的瓶颈主要体现在5个方面: 数据库, 带宽, CPU, 内存, 硬盘. 优化高并发主要是在这些方面进行平衡, 每一部分都充分利用以提高并发量. 在以往的经验当中数据库的读写是最关键的地方, 所以优化高并发最关键的地方是减少数据库的读写.
写缓存是压力给内存(radis)和硬盘(filecache)是最有效的方法. 如上面提到的接口中, 首页接口, 产品列表, 产品详情基本上数据变化较小, 可以直接写到硬盘缓存中, 当后台数据有变化时, 清除缓存, 前端有访问时重新生成缓存即可.
CPU优化只能是逻辑代码上的优化, 除有严重的代码逻辑编写不合理, 一般来说可优化程度不高, 而且在以往的经验中, 服务器堵塞时CPU占用量并不高, 除非某一接口单独访问时就明显卡顿然后去做代码优化, 否则如果出现CPU占到80%左右时就只能硬件升级CPU.
带宽优化就是把类似视频, 图片, JS/CSS(小程序不需要考虑)等, 单独放OSS上, 咱们的系统本身也是如此, 所以也没有太多可优化的地方.
综上所述, 在做高并发压力测试时, 要统计以上5种资源的利用情况. 根据实际情况做分析进行优化. 高并发优化没有统一的优化标准. 主要思想就是把数据库读写压力缓存到内存或硬盘.
4. 接口访问数量的如何统计:
在统计时有两个方案. 一个是识别用户, 一个是不识别用户.
两种方式都需要用到radis, 数据库两个键值对, 一个是用户ID或token, 一个是访问时间, 新登录用户访问任何接口写入用户的ID及访问时间, 用户再次访问接口更新用户的访问时间即可. 每新进一个用户统计数量加1, 当超过某一并发值时(压力测试的并发值), 统计某一时间(如10秒)内"在线的"用户数量, 如果在线用户数量也大于预设值, 新进用户再访问接口, 直接返回排队信息, 不写入Radis. 在线的老用户可以正常访问接口. 有新请求时再次统计, 当统计结果低于预设值时, 新用户可以正常访问, 新用户访问时在线人数再添加, 超过之后再循环统计... 这种方案的好处是确保老用户能一直在线, 完成一个正常流程, 如定单流程需要好几步, 不至于正在下定单过程中不能访问接口. 当然如果定单流程中停顿10秒还是会被视为新用户. 这一方案的缺点是如果已经在线的用户频繁访问接口, 依然有风险超过服务器的极限并发量.
不识别用户方案, 只有一个键值:接口访问时间, 每新进一个访问写入一条记录, 同时统计一定时间内(接口平均正常返应时间)的访问数量, 如果也超过预设值(测试的并发量略小), 新进访问直接返回排队信息, 不写入数据, 删除旧的访问记录(超过接口平均反应时间的记录), 新进请求触发统计, 直到统计结果低于预设值为止. 如果没有超过预设值, 写入记录, 删除旧的访问时间, 正常访问. 优点时统计效率会更高, 限流效果和实时性更好, 缺点是同一用户在购买过程中会出现排队消息, 等待的情况
5. 注意:
以上两种方式都受radis并发量限制. 同时也受带宽和其它硬件的最高并发量, 如果并发量实在太大, 以上方案不能解决. 解决的办法只能添加硬件, 做分布式等