您的位置:首页 > 运维架构 > Apache

Apache 服务器负载低访问慢的原因分析和优化方案

2018-03-06 13:46 806 查看
门户网站采用的Apache服务器,搭建在阿里云上,最近总是出现访问慢,甚至无法访问。重启Apache服务后,才可以正常访问,初步原因是米扑博客的访客增量过多,百度等爬虫抓取压力过大。统计访客IP和PV数量,发现跟平时差不多,甚至还略低,服务器应该不至于响应这么慢,从而需要针对这个问题进行分析,来解决网站访问过慢。原因分析1、在页面访问变慢情况发生时,使用 top 命令查看了服务器的负载情况,发现负载并不高,初步估计不是程序的问题。 
2、查看 httpd 进程数量ps -ef | grep httpd | wc -l查看结果
上面数据发现,线程数已经达到了 apache 设置的最大值。由此断定是网站访问人数过多造成了访问过慢。 3、查看了服务器连接数和当前的建立连接数1)查看连接数netstat -ant | grep -E ":80|:443"结果如下:
 2)查看建立连接数netstat -ant | grep ESTABLISHED | grep -E ":80|:443"结果如下:
发现连接数特别多,远远超过了米扑博客设置的Apache服务器允许的估计值。 4、熟悉服务器的 MPM 配置刚开始的时候,对于Apache服务器的 MPM 配置方式不是特别的熟悉,认为修改服务器配置可以解决问题。MPM是Apache的核心,它的作用是管理网络连接、调度请求。Apache2.0中MPM分为3种:perfork、worker、eventperfork 从Apache1.3中继承下来的,它采用的是进程管理方式,所以它可以提供更可靠的性能和更好的兼容性;worker 是Apache2.0中新增加的方式,它采用了线程控制方法,可以比perfork更节 约系统开销、处理更多的数据量,但同时兼容性并不是很好,很多旧的程序无法工作在worker下;event仍处于试验阶段,它为每个任务分配不同的进程池,目前不应该采用。通过命令 httpd -l 可以获取目前Apache采用的是哪种 MPM本文主要介绍的Apache配置,包括 prefork 或者 work 模式的配置1) prefork 模式以 prefork 模式工作的 apache 的默认配置: 
当Apache被启动时,自动会采用 prefork 控制进程在最初建立 StartServers 个子进程后,为了满足 MinSpareServers 设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers 设置的值为止。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。 MaxSpareServers 设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比 MinSpareServers小,Apache会自动把其调整为 MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServersMaxClients 是这些指令中最为重要的一个,设定的是 Apache可以同时处理的请求,是对Apache性能影响最大的参数。MaxClients 缺省值150,一般是远远不够的,如果请求总数已达到这个值(可通过 ps -ef | grep httpd | wc -l 来查看),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。虽然理论上 MaxClients 这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256在 apache2 中通过ServerLimit指令无须重编译Apache就可以加大MaxClients,此时必须 MaxClients ≤  ServerLimit  ≤ 20000MaxRequestsPerChild用来控制每个进程在处理了多少次请求之后自动销毁,这个参数可以设置为0表示无限,即不销毁进程而且 ServerLimit 必须大于等于 MaxClients 数量,否则报错虽然通过设置ServerLimit,可以把MaxClients加得很大,但是往往会适得其反,系统耗光所有内存。以一台服务器为例:内存2G,每个apache进程消耗大约3%(可通过ps aux来确认,如上面的top命令结果)的内存,也就是60M,这样,理论上这台服务器最多跑30个apache进程就会耗光系统所有内存,所以,设置MaxClients要慎重。 使用场景:周末晚上,在访问量高峰期,经常会出现突然之间发生非常多的并发连接(ps -ef | grep httpd | wc -l),然后突然之间减少了很多访问。如果Apache没有准备足够数量的预备进 程,那访问只能等待Apache每秒1个的新增进程,随后又要将多余的进程删除,那Apache只能一直忙于新建和销毁进程,大大地降低了访问速度。可以 适当的提前增加 StartServers、MinSpareServers、MaxSpareServers 来使得Apache不需要一直忙于作无用功。最后,推荐MaxRequestsPerChild不要设置为0,强烈推荐设置为非0,可以保护Apache进程免遭内存泄漏的影响,因为你不知道运行在Apache上的应用程式在什么时候会出错导致内存泄漏。优化设置如下:
 2)worker 模式以 worker 模式工作的 apache 的默认配置为: 
Worker 由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程, MinSpareThreads 和 MaxSpareThreads 设置了最少和最多的空闲线程数;MaxClients 设置了同时连入的clients最大总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。 MinSpareThreads 和 MaxSpareThreads的最大缺省值分别是75和250,这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。ThreadsPerChild 是worker MPM中与性能相关最密切的指令。 ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000Worker 模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild 值决定的,应该大于等于MaxClients处理请求总数 = 子进程总数 * ThreadsPerChild  >= MaxClients如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。需要注意的是,如果显式声明了ServerLimit,那么它乘以 ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则 Apache将会自动调节到一个相应值。 3)itk.c 模式仔细查看分析httpd.conf配置文件后,发现还有一种 itk 模式直接给出其默认配置,供参考
服务器的apache采用的是 prefork 的工作模式对 MaxClients 进行了相应的调整,发现服务启动后很短时间,连接数就能够达到最大。  5、查看用户访问日志查看用户访问日志和详情页面,将配置中的 access_log 打开,发现85%以上的访问都是直接访问的资源文件,由此判定,用户可能使用了多线程的下载工具,或者这些资源遭受了盗链(可能性更大)。 优化方案1. 限制单个IP进行连接的线程,不允许多线程连接资源对于IP限制,采用了 mod_limitipconn 这个模块。这个模块的优点是配置简单,缺点是不能够针对单独的文件夹或者文件进行设置,而且不支持虚拟主机。 在 apache 中安装了这个模块后,在配置文件中添加如下几段就可以生效了: 
 2. 添加URL重写,防止盗链防止盗链,一个重要的方法就是判断请求的 refer但是如果一些浏览器发出请求的时候将 refer 去掉,或者伪装,这个办法就无能为力了。但是貌似还有更高级的方法,还是可以实现这个功能。 安装apache的 mod_rewrite 模块后,在apache配置文件中添加 
这样盗链的请求会被重定向到一个错误页面,从而减少下载带给服务器的压力。3. 网站打不开,httpd无法启动,提示错误“No space left on device: Cannot create SSLMutex”错误信息如下:
根据错误提示第一行“[error] server reached MaxClients setting, consider raising the MaxClients setting”,认为是MaxClients数量太少查看 apache 工作模式:# httpd -lCompiled in modules:  core.c  prefork.c  http_core.c  mod_so.c工作模式为 prefork.c ,于是进一步查看 httpd.conf 的 prefork.c 配置vim  httpd.conf
因为服务器配置不高、日访客并发不大,于是 MaxClients 配置数较小,是合理的。进一步分析,关注到错误提示“No space left on device: Cannot create SSLMutex”,这一句的含义是没有剩余资源创建 SSLMutex 共享变量联想到了Linux无法创建句柄,并会无法提供服务,于是查看共享变量资源的占用情况ipcs : ipcs provides information on the ipc facilities for which the calling process has read access.
发现共享变量有数百个被apache进程占用,无法释放,资源耗尽了。于是,需要删除占尽的共享变量信号资源,删除命令如下:
重新启动Apache httpd 服务器:/etc/init.d/httpd restarthttpd无法重启的问题解决! 查看正常情况下的共享变量信号:ipcs -s
 查看 ipcs 的限制参数:ipcs -l
显示发现,Semaphore Limits 最大为128,超过了这个数量,httpd 服务将会无法再启动,也就导致了上面的网站打不开。总结通过优化 prefork 模式,启用限制IP和防盗链,米扑博客的访问速度提升非常明显而且,CPU、内存、负载、MySQl等指标不仅没有上升,反而大幅下降了
 客户请求连接数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: