Tag Archives: apache

Linux Web服务器性能调优 – Apache的工作模式及配置

一般来说Apache有两种常用工作模式prefork和worker;

要查看当前服务器的工作模式,请用命令 apache2 -l

$ apache2 -l
Compiled in modules:
core.c
mod_log_config.c
mod_logio.c
prefork.c
http_core.c
mod_so.c

可以看到prefork.c 说明现在在用prefork模式。

关于两种模式的区别,根据官方文档:

  • The workerMPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM.
  • The prefork MPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory. Prefork’s threadless design has advantages over worker in some situations: it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.

可以看到,这些主要和进程和线程有关,对于内存有限逻辑简单,不太考虑线程安全的网站,worker模式显然更加适合。

复习下进程和线程的主要区别和联系:

进程与线程区别与联系

  1. 划分尺度:线程更小,所以多线程程序并发性更高;
  2. 资源分配:进程是资源分配的基本单位,同一进程内多个线程共享其资源;
  3. 地址空间:进程拥有独立的地址空间,同一进程内多个线程共享其资源;
  4. 处理器调度:线程是处理器调度的基本单位;
  5. 执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

worker模式是介于纯进程的prefork和纯线程的event模式直接的方式,在稳定性和资源上有一个取舍。

prefork配置解释

一个典型的prefork配置和解释如下

<IfModule prefork.c>
StartServers 20 # 启动服务数,对应启动进程数
MinSpareServers 50 # 最小空闲服务(提高响应能力),当前进程数 > 最小空闲服务 + 工作进程
MaxSpareServers 100 # 最大空闲服务(合理释放资源),当前进程数 < 最大空闲服务 + 工作进程
MaxClients 200 # 最大客户端,对应最大进程数
MaxRequestsPerChild 20000 # 每个服务最多处理的请求数量,设定一个有限值可以避免内存泄漏,但会消耗进程创建和销毁的资源
</IfModule>

prefork是用起来最方便的设置,apache的默认设置也是如此。
但该模式最内存资源消耗巨大。举例来说:
一般情况下,一个PHP网站中,每个server需要30M左右内存。
按照前文的配置,最多将占用6G左右的内存。
如果资源不足,就会引发频繁的page fault,大量的SWAP,系统产生大量IO,导致宕机。

所以合理的调整参数,满足网站并发要求和资源限制,在小内存(1G),prefork模式几乎是不可能做到的。

worker配置解释

<IfModule worker.c>

StartServers 15 # 启动的服务,对应进程

ServerLimit 15 # 最大服务限制 应满足 ServerLimit > MaxClients / ThreadsPerChild

MaxClients 256 # 最大客户端数量
ThreadLimit 256 # 最大线程数量
MinSpareThreads 30 # 最小空闲线程(提高响应能力),当前线程数 > 最小空闲服务 + 工作线程
MaxSpareThreads 305 # 最大空闲线程(合理释放资源),当前线程数 < 最大空闲服务 + 工作线程
ThreadsPerChild 255 # 每个子进程对应对线程数
MaxRequestsPerChild 0 # 每个进程处理的最大请求数量,达到即销毁新建进程
</IfModule>

类似的,我们也主要关注其并发响应能力和资源占用情况。

上面的配置可以支持256的并发,内存占用约大于 15 * 30M = 450M 左右,算上线程的开销,大致小于500M。

其他建议

并发和性能与很多东西相关,不是简单计算能够解决的。

这里的配置主要是避免系统瓶颈,同时保护服务器不要超过应用能力。

实际情况中,和磁盘性能,网络,CPU等都有关系,建议在对硬件的充分理解上,结合性能测试工具不断调优。Linux WEB Perfomance Tunning Toolbox

Linux WEB服务器性能调优 – 工具箱

以下是这两天调优的小笔记。第一部分 – 工具

工具

top

top 命令用于互动查看系统情况,相信linux用户都用过。

备注:H 可以显示线程 u 可以指定用户

ps

ps可以列出进程状态,最经典的用法就是 ps aux

不过我更喜欢加上 ps aux -H 可显示进程层次

另外 ps aux -T 可以显示线程

pstree

以树形方式简单直接显示进程,常用 pstree –ph (带线程)

lsof

使用它既可以知道进程打开了哪些文件,也可以了解一个文件被哪个进程打开。

一般需配合 grep 使用,对于前面几个工具,发现状态经常为D IOWait较高的情况,最适合用lsof分析原因。

举例:

lsof /etc/passwd 查看谁打开了passwd文件

lsof -p 9995 查看进程9995打开的文件

lsof -i -n -p 显示网络连接状态也非常好用

ab

压力测试工具

常用 ab -c 20 -n 1000 http://example.org/

用20并发请求1000次 http://example.org/ 并汇总统计

sar

系统状态统计

vmstat

系统状态统计

短命令

TCP网络连接状态

netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key,”\t”,state[key]}’
会得到类似下面的结果,具体数字会有所不同:
LAST_ACK         1
SYN_RECV         14
ESTABLISHED      79
FIN_WAIT1        28
FIN_WAIT2        3
CLOSING          5
TIME_WAIT        1669

SYN_RECV表示等待响应,如果数值较高,需要提高服务器的吞吐量

ESTABLISHED是成功建立连接的,如果占主导是好事情

其他意义不大,有兴趣可以查看TCP相关资料

继续说Apache的优化

经过了前面一段时间的探索,我们对ApacheMySql的性能调优有了个初步的认识,我本来以为问题到这里应该就解决了,但是运行了十几天后,还是出现了负载达到50+的情况。于是,网站又挂了。

分析access.log与之前并无不同,被盗链的请求还是很多,不过这些都被302重定向了啊,死活想不到办法,一度怀疑是不是因为302或者404的错误日志过多的引起的IO问题导致服务器资源紧张。

除此之外,还是有个现象引起了注意,每次挂掉的不是Apache,而是数据库。为什么盗链会引起数据库问题,这显然无法解释。

不绕圈子了,最后发现的问题,就是为了防盗链而特意写的Rewrite。原本的rewrite是这样的,对于盗链的资源,重定向到首页。

这看起来没有问题,可是瞬间请求数百次到首页,然后运行脚本,执行数据库查询……

还有一点,返回的是302,这就意味着搜索引擎和下载工具会认为资源是存在的,不会停止响应。

所以,最终的解决方案。重定向所有盗链的资源到一个静态LOGO,同时,设定返回Code为403.

整个世界清净了。

Apache性能调优

说来不好意思,服务器的性能一直都是个大问题,访问量不大,却经常死机。

调优了很多次,也没什么效果。

晚上加晚班,现在无事,又搜索了一番,修改了下,这下貌似有效果了,分享如下。

问题描述

RHL Linux 5.0 + Apache Httpd 2.2 + Mysql5.0 + PHP 5.0 环境

问题描述:服务器运行若干时间后,会无法响应请求,分析日志文件和进程,有如下情况

  1. 大量的404错误:盗链和后续处理有关
  2. 一些比较奇怪的Apache程序异常
    [Sat Apr 25 02:06:40 2009] [notice] child pid 5534 exit signal Floating point exception (8)
    [Sat Apr 25 02:06:41 2009] [notice] child pid 5499 exit signal Floating point exception (8)
    [Sat Apr 25 02:06:41 2009] [notice] child pid 5527 exit signal Floating point exception (8)
    ………
    强制重启进程时还有*** glibc detected *** /usr/sbin/httpd: free(): invalid pointer: 0×00359170 ***
    *** glibc detected *** /usr/sbin/httpd: free(): invalid pointer: 0×00359170 ***
  3. 系统负载平衡很高,甚至达到60
  4. CPU使用很高,物理内存使用达到90%,交换内存也将近满了
  5. 有大量的Apache Httpd进程,且多为Sleeping状态

原因分析

常见的引起服务器不稳定的原因:

  1. 程序问题引起的内存泄漏
  2. 不恰当的配置导致资源死锁

关于Apache Httpd的调优,有很多说法,不过个人推荐两篇文章,应该是通俗易懂的,呃,E文

Open Source: Configuring Apache – Don’t Succumb To The “Slashdot Effect” http://blogcritics.org/archives/2006/01/27/175740.php

Tuning Apache, part 1 http://virtualthreads.blogspot.com/2006_01_01_archive.html

还有有中文的

Apache Prefork和Worker模式性能比较

http://www.5dlinux.com/article/9/2009/linux_29722.html

官方文档的中文翻译 性能方面的提示

http://lamp.linux.gov.cn/Apache/ApacheMenu/misc/perf-tuning.html

说说对上面两个问题的方案。

内存泄漏。程序哪里错了,不好说,得跟踪定位,每个系统都有内存跟踪的工具,除此之外还要分析日志,可以通过Apache的日志配置来跟踪脚本运行的时间,找出可能的元凶。

除此之外,还有个很土的办法:定时重启。实在没招了可以参考。

服务器的配置么,那更有说法了。Apache httpd默认是Prefork模式(参考上面),这里就是论事的介绍几个参数:事实上我只是简单摘译一下上面的某篇文章,后面的设置是作者的推荐值,中文里面是我的推荐

  • MaxKeepAliveRequests 0 The KeepAlive directive in httpd.conf allows persistent connections to the web server, so that new connection does not have to be initiated for each request. Setting the MaxKeepAliveRequests directive to 0 enables unlimited number of requests per connection, which makes sense if you think about it. Why allow persistent connections but then terminate them after a short period of time?
  • 最大保持连接请求数:0 – 无限制。保持连接意味着不必为同一客户端的多次请求重新释放和分配资源,也意味着这些资源不会马上释放。这在现在这个Ajax漫天飞,外加无数图片和JS的时代很重要,但是如果控制不好资源的保持与释放,就意味着系统资源的耗尽。不过这里只是能复用的请求数,无限就好了。
  • KeepAliveTimeout 15
    Because persistent connections are allowed, it is important that they are not kept open indefinitely. This directive will close the connection after 15 seconds of inactivity.
  • 保持连接超时 3 秒
    如果连接请求无活动,就有必要关掉它,默认15秒太长了点,3秒钟就够了。
  • MinSpareServers 15
    This is the minimum number of spare servers you want running at any given time. This way, if multiple simultaneous requests are received there will already be child processes running to handle them. Setting this number too high is a waste of system resources and setting it too low will cause the system to slow down.
  • MaxSpareServers 65
    Same as above, but the maximum child processes running at any given time.
  • StartServers 15
    This is the number of servers Apache will start initially. As more servers handle requests a minimum of 15 spare servers will run up to the maximum of 64.
  • 上面这三个参数放在一起说:其实就是Apache用于响应用户的子进程,一般一个子进程消耗20M左右内存,上面三个数字可以控制子进程的数量。于是根据可用的系统资源,就可以计算出个合理的取值了。
  • MaxClients 500
    This is the maximum number of simultaneous clients that can connect to the server at any given time. Setting this number too low will result in users being locked out of the server under normal traffic situations and setting it too high will result in your server being so overloaded that all the requests timeout anyway. I think 500 is about right for most people’s needs.
  • 最大客户端,其实就是并发处理量,这也要根据情况来配置,太大会导致服务器崩溃,太小会导致请求排队,响应缓慢。
  • MaxRequestsPerChild 100000
    Sets the maximum number of requests each child process will handle. This is mostly to prevent memory leaks and other mishaps but is important nonetheless. Setting this too low will cause a large portion of child processes to end for no real reason, thus slowing down the site. This could be set to 0 (unlimited) but that would negate any protection from valid issues like memory leaks.
  • 每个子进程可以处理的最多请求。做限制的好处就是,如果某个程序内存泄漏,那么一段时间后就可以把它释放掉。限制小会导致频繁创建进程,拖慢系统。
  • HostnameLookups off
    This prevents DNS lookups of all the visitors to the site, I am pretty sure it’s off by default. If it’s on in your httpd.conf I would recommend turning it off.这没啥好说的

默认的配置

<IfModule prefork.c>

ServerLimit 10000
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 10000
MaxRequestsPerChild 0
</IfModule>

这个默认配置的缺点就是不能防止内存泄漏,结合KeepAlive的设置,占用过多资源。

KeepAlive on
KeepAliveTimeout 2
MaxKeepAliveRequests 0
MaxClients 150
MinSpareServers 5
MaxSpareServers 12
StartServers 5
MaxRequestsPerChild 100000

较短的保持连接释放,有利于应对无效的盗链请求。

客户端限制用于保护服务器正常运行。

实验继续进行中,本文将不定期更新。