高并发解决方案很难吗?轻松聊清楚高并发设计
高请求并发就一定会有高并发问题吗?其实不是的。可以设想一下,假如我们的应用全是内存逻辑,无论请求量再大,其实我们简单的增加节点就可以解决问题,那么自然不存在所谓高并发问题。高并发问题之所以存在,是因为系统中存在一些单点瓶颈,这个瓶颈是无法靠粗暴扩容解决的,所以我们才需要找别的方案解决这个问题。
事实上,这个瓶颈,绝大多数情况下都是数据库。
对于90%以上的场景来说,高并发问题本质的难点就在于数据库能够承载的并发是有限的。而各种高并发技术方案的作用归根结底其实也都是去降低单库的连接数,
比如:
系统拆分:首先将不同业务的库分开,每个业务可以各自独享一个数据库;
缓存:使用缓存降低需要访问数据库的比例;
MQ等方式削峰:避免瞬时的数据库连接数过多;
分库、分表、读写分离:对同一业务的数据库做进一步的拆分,降低单库的访问量;
引入elastic search, clickhouse等其他存储:与上一条类似,将一些不适合mysql的业务拆分出来,进一步降低mysql的并发;
上面的思路,是提升应用的处理能力;不需要所有请求都去连数据库,那么自然就可以承载更高的并发了。
另一个方向的思路,是限流,这样做的主要意义有两个:保证处理能力内的这一部分请求能够被正常处理,而不是拖垮所有请求; 即使有问题,也将问题限制在一个很小的范围。
限流的方式很多,比如我们熟悉的漏桶、令牌桶等算法,这里就不再细说。
除此之外,还有各种我们所熟悉的“池子”,比如tomcat连接池、线程池等,包括应用里的mysql连接池,其实也是在限制能够被发出的最大请求数。
为了确定这些池子的状态,要做好监控,比如tomcat的活跃连接数、mysql的活跃连接数等等,快要满的时候就要看情况准备扩容了。
如何给这些池子设置更合理的参数,保证:机器的数据库的资源被充分利用;池子未满时,确定不会超过数据库的负载
这样理解下来,我们也就知道为什么大部分讲高并发处理思路的文章,关注焦点都在缓存、分库分表、连接池优化这些事情上了。