1.概述

最近看了一篇关于热key导致redis服务集群挂掉的文章, 非常的精彩导致我在想当流量非常大时为什么redis服务会挂掉,于是我就找了大量的资料研究服务为什么会挂掉及其原理,服务器为什么会宕机等等就有了如下内容。

其实服务崩溃总结起来无非就两种,一种是资源枯竭导致的服务崩溃,另一种就是超时引起的服务崩溃。


2.资源枯竭导致

先说第一种资源枯竭导致的服务崩溃,顾名思义就是因为服务器的资源或者分配的资源不能满足服务运行的需要从而引发服务崩溃。比较常见有内存溢出,磁盘满载,带宽不足等三种。

写java的程序员遇到最多的估计就是内存溢出了,比如操作系统给jvm分配了2G的物理内存供程序运行使用,可能有个程序头铁在一段代码中创建了循环引用的对象或者大量未能及时回收的对象,在请求量大时gc不能及时回收垃圾对象导致堆内存一直在增大超过了操作系统所分配的2G内存,此时就会触发操作系统的kill -9信号把程序杀死这样用户再请求服务时就无响应了。

电商大促期间前有很多准备工作,其中有一项就是去运营商那里购买宽带,这是因为在大促期间有大量用户访问,如果机器带宽不足会导致服务崩溃,进而导致非常大损失。我们以一台机器80M的宽带为例,经过计算能承受的最大下载速度就是10M/s, 拿单个用户的一个请求数据大小为10k为例,在1s内有1024个用户请求时需要80M的宽带机器刚好能满足要求,如果是1s内有2000用户请求时需要160M的流量那么处理完这2000个用户的请求需要2s,如果持续30s都有2000个用户来请求服务,那么就需要4800M的流量处理完需要600多s那么就会大量请求出现等待进而引发超时导致服务崩溃。


3.超时导致

第二种超时引起的服务崩溃,就是大量用户请求服务时因为大面积连接超时导致服务崩溃,和宽带不足的例子很像,我们以单台机器服务启动单进程为例,在一个进程中我们通常会通过线程池去处理请求,我们假设线程池中一共有1000个请求来处理请求且每个请求的响应时间为100ms,当1s钟有10000个请求发来时我们可以很快的处理并返回,当1s内有20000个请求发来时服务器要处理就需要2s钟的时间了,那么在一段持续时间20000请求来时就会积压大量的请求不能被处理导致超时,然后后面过来的请求肯定超时,这样服务就崩溃了。


4.总结

在真实的生产环境,崩溃的原因可能会非常复杂且是多种因素互相作用的结果,但了解了服务奔溃的本质后就能很快找到对应的解决方案,如万能的增加机器,优化代码逻辑,加入缓存等等。完毕!

04-06 09:46