Total Pageviews

Wednesday 11 July 2012

Apache的配置

Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd.conf文件中修改。

  1. 主站点的配置(基本配置)
    (1) 基本配置:
    ServerRoot "/mnt/software/apache2" #你的apache软件安装的位置。其它指定的目录如果没有指定绝对路径,则目录是相对于该目录。
    PidFile logs/httpd.pid #第一个httpd进程(所有其他进程的父进程)的进程号文件位置。
    Listen 80 #服务器监听的端口号。
    ServerName www.clusting.com:80 #主站点名称(网站的主机名)。
    ServerAdmin admin@clusting.com #管理员的邮件地址。
    DocumentRoot "/mnt/web/clusting" #主站点的网页存储位置。

    以下是对主站点的目录进行访问控制:
    <Directory "/mnt/web/clusting">
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
    </Directory>

    在上面这段目录属性配置中,主要有下面的选项:
    • Options:配置在特定目录使用哪些特性,常用的值和基本含义如下:
      ExecCGI: 在该目录下允许执行CGI脚本。
      FollowSymLinks: 在该目录下允许文件系统使用符号连接。
      Indexes: 当用户访问该目录时,如果用户找不到DirectoryIndex指定的主页文件(例如index.html),则返回该目录下的文件列表给用户。
      SymLinksIfOwnerMatch: 当使用符号连接时,只有当符号连接的文件拥有者与实际文件的拥有者相同时才可以访问。
      其它可用值和含义请参阅:http://www.clusting.com/Apache/ApacheManual/mod/core.html#options
    • AllowOverride:允许存在于.htaccess文件中的指令类型(.htaccess文件名是可以改变的,其文件名由AccessFileName指令决定): None: 当AllowOverride被设置为None时。不搜索该目录下的.htaccess文件(可以减小服务器开销)。
      All: 在.htaccess文件中可以使用所有的指令。
      其他的可用值及含义(如:Options FileInfo AuthConfig Limit等),请参看: http://www.clusting.com/Apache/ApacheManual/mod/core.html#AllowOverride
    • Order:控制在访问时Allow和Deny两个访问规则哪个优先:
      Allow:允许访问的主机列表(可用域名或子网,例如:Allow from 192.168.0.0/16)。
      Deny:拒绝访问的主机列表。
      更详细的用法可参看:http://www.clusting.com/Apache/ApacheManual/mod/mod_access.html#order
    DirectoryIndex index.html index.htm index.php  #主页文件的设置(本例将主页文件设置为:index.html,index.htm和index.php)

    (2) 服务器的优化 (MPM: Multi-Processing Modules)
    apache2主要的优势就是对多处理器的支持更好,在编译时同过使用--with-mpm选项来决定apache2的工作模式。如果知道当前的apache2使用什么工作机制,可以通过httpd -l命令列出apache的所有模块,就可以知道其工作方式:
    • prefork:如果httpd -l列出prefork.c,则需要对下面的段进行配置:
      <IfModule prefork.c>
      StartServers 5 #启动apache时启动的httpd进程个数。
      MinSpareServers 5 #服务器保持的最小空闲进程数。
      MaxSpareServers 10 #服务器保持的最大空闲进程数。
      MaxClients 150 #最大并发连接数。
      MaxRequestsPerChild 1000 #每个子进程被请求服务多少次后被kill掉。0表示不限制,推荐设置为1000。
      </IfModule>

      在该工作模式下,服务器启动后起动5个httpd进程(加父进程共6个,通过ps -ax|grep httpd命令可以看到)。 当有用户连接时,apache会使用一个空闲进程为该连接服务,同时父进程会fork一个子进程。 直到内存中的空闲进程达到MaxSpareServers。该模式是为了兼容一些旧版本的程序。我缺省编译时的选项。

    • worker:如果httpd -l列出worker.c,则需要对下面的段进行配置:
      <IfModule worker.c>
      StartServers 2 #启动apache时启动的httpd进程个数。
      MaxClients 150 #最大并发连接数。
      MinSpareThreads 25 #服务器保持的最小空闲线程数。
      MaxSpareThreads 75 #服务器保持的最大空闲线程数。
      ThreadsPerChild 25 #每个子进程的产生的线程数。
      MaxRequestsPerChild 0 #每个子进程被请求服务多少次后被kill掉。0表示不限制,推荐设置为1000。
      </IfModule>

      该模式是由线程来监听客户的连接。当有新客户连接时,由其中的一个空闲线程接受连接。 服务器在启动时启动两个进程,每个进程产生的线程数是固定的(ThreadsPerChild决定),因此启动时有50个线程。 当50个线程不够用时,服务器自动fork一个进程,再产生25个线程。

    • perchild:如果httpd -l列出perchild.c,则需要对下面的段进行配置:
      <IfModule perchild.c>
      NumServers 5 #服务器启动时启动的子进程数
      StartThreads 5 #每个子进程启动时启动的线程数
      MinSpareThreads 5 #内存中的最小空闲线程数
      MaxSpareThreads 10 #最大空闲线程数
      MaxThreadsPerChild 2000 #每个线程最多被请求多少次后退出。0不受限制。
      MaxRequestsPerChild 10000 #每个子进程服务多少次后被重新fork。0表示不受限制。
      </IfModule>
      该模式下,子进程的数量是固定的,线程数不受限制。当客户端连接到服务器时,又空闲的线程提供服务。 如果空闲线程数不够,子进程自动产生线程来为新的连接服务。该模式用于多站点服务器。
    (3) HTTP返头回信息配置:
    ServerTokens Prod #该参数设置http头部返回的apache版本信息,可用的值和含义如下:
    • Prod:仅软件名称,例如:apache
    • Major:包括主版本号,例如:apache/2
    • Minor:包括次版本号,例如:apache/2.0
    • Min:仅apache的完整版本号,例如:apache/2.0.54
    • OS:包括操作系统类型,例如:apache/2.0.54(Unix)
    • Full:包括apache支持的模块及模块版本号,例如:Apache/2.0.54 (Unix) mod_ssl/2.0.54 OpenSSL/0.9.7g
    ServerSignature Off #在页面产生错误时是否出现服务器版本信息。推荐设置为Off

    (4) 持久性连接设置
    KeepAlive On #开启持久性连接功能。即当客户端连接到服务器,下载完数据后仍然保持连接状态。
    MaxKeepAliveRequests 100 #一个连接服务的最多请求次数。
    KeepAliveTimeout 30 #持续连接多长时间,该连接没有再请求数据,则断开该连接。缺省为15秒。
  2. 别名设置 对于不在DocumentRoot指定的目录内的页面,既可以使用符号连接,也可以使用别名。别名的设置如下:
    Alias /download/ "/var/www/download/" #访问时可以输入:http://www.custing.com/download/
    <Directory "/var/www/download"> #对该目录进行访问控制设置
    Options Indexes MultiViews
    AllowOverride AuthConfig
    Order allow,deny
    Allow from all
    </Directory>

  3. CGI设置
    ScriptAlias /cgi-bin/ "/mnt/software/apache2/cgi-bin/" # 访问时可以:http://www.clusting.com/cgi-bin/ 。但是该目录下的CGI脚本文件要加可执行权限!
    <Directory "/usr/local/apache2/cgi-bin"> #设置目录属性
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
    </Directory>
  4. 个人主页的设置 (public_html)
    • UserDir public_html (间用户的主页存储在用户主目录下的public_html目录下 URL http://www.clusting.com/~bearzhang/file.html 将读取 /home/bearzhang/public_html/file.html 文件)
      chmod 755 /home/bearzhang #使其它用户能够读取该文件。
    • UserDir /var/html (the URL http://www.clusting.com/~bearzhang/file.html 将读取 /var/html/bearzhang/file.html)
    • UserDir /var/www/*/docs (the URL http://www.clusting.com/~bearzhang/file.html 将读取 /var/www/bearzhang/docs/file.html)
  5. 日志的设置

    (1)错误日志的设置
    ErrorLog logs/error_log #日志的保存位置
    LogLevel warn #日志的级别
    显示的格式日下:
    [Mon Oct 10 15:54:29 2005] [error] [client 192.168.10.22] access to /download/ failed, reason: user admin not allowed access
    (2)访问日志设置
    日志的缺省格式有如下几种:
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common #common为日志格式名称
    LogFormat "%{Referer}i -> %U" referer
    LogFormat "%{User-agent}i" agent
    CustomLog logs/access_log common

    格式中的各个参数如下:
    • %h --客户端的ip地址或主机名
    • %l --The 这是由客户端 identd 判断的RFC 1413身份,输出中的符号 "-" 表示此处信息无效。
    • %u --由HTTP认证系统得到的访问该网页的客户名。有认证时才有效,输出中的符号 "-" 表示此处信息无效。
    • %t --服务器完成对请求的处理时的时间。
    • \"%r"\ --引号中是客户发出的包含了许多有用信息的请求内容。
    • %>s --这个是服务器返回给客户端的状态码。
    • %b --最后这项是返回给客户端的不包括响应头的字节数。
    • \"%{Referer}i\" --此项指明了该请求是从被哪个网页提交过来的。
    • \"%{User-Agent}i\" --此项是客户浏览器提供的浏览器识别信息。
    下面是一段访问日志的实例:
    192.168.10.22 - bearzhang [10/Oct/2005:16:53:06 +0800] "GET /download/ HTTP/1.1" 200 1228
    192.168.10.22 - - [10/Oct/2005:16:53:06 +0800] "GET /icons/blank.gif HTTP/1.1" 304 -
    192.168.10.22 - - [10/Oct/2005:16:53:06 +0800] "GET /icons/back.gif HTTP/1.1" 304 -
    各参数的详细解释,请参阅:http://www.clusting.com/Apache/ApacheManual/logs.html
  6. 用户认证的配置
    (1)in the httpd.conf:
    AccessFileName .htaccess
    .........
    Alias /download/ "/var/www/download/"
    <Directory "/var/www/download">
    Options Indexes
    AllowOverride AuthConfig
    </Directory>
  7. (2) create a password file:
    /usr/local/apache2/bin/htpasswd -c /var/httpuser/passwords bearzhang

    (3)onfigure the server to request a password and tell the server which users are allowed access.
    vi /var/www/download/.htaccess:
    AuthType Basic
    AuthName "Restricted Files"
    AuthUserFile /var/httpuser/passwords
    Require user bearzhang
    #Require valid-user #all valid user
  8. 虚拟主机的配置
    (1)基于IP地址的虚拟主机配置
    Listen 80
    <VirtualHost 172.20.30.40>
    DocumentRoot /www/example1
    ServerName www.example1.com
    </VirtualHost>
  9. <VirtualHost 172.20.30.50>
    DocumentRoot /www/example2
    ServerName www.example2.org
    </VirtualHost>

    (2) 基于IP和多端口的虚拟主机配置
    Listen 172.20.30.40:80
    Listen 172.20.30.40:8080
    Listen 172.20.30.50:80
    Listen 172.20.30.50:8080
    <VirtualHost 172.20.30.40:80>
    DocumentRoot /www/example1-80
    ServerName www.example1.com
    </VirtualHost>
    <VirtualHost 172.20.30.40:8080>
    DocumentRoot /www/example1-8080
    ServerName www.example1.com
    </VirtualHost>
    <VirtualHost 172.20.30.50:80>
    DocumentRoot /www/example2-80
    ServerName www.example1.org
    </VirtualHost>
    <VirtualHost 172.20.30.50:8080>
    DocumentRoot /www/example2-8080
    ServerName www.example2.org
    </VirtualHost>
    (3)单个IP地址的服务器上基于域名的虚拟主机配置:
    # Ensure that Apache listens on port 80
    Listen 80
    # Listen for virtual host requests on all IP addresses
    NameVirtualHost *:80
    <VirtualHost *:80>
    DocumentRoot /www/example1
    ServerName www.example1.com
    ServerAlias example1.com. *.example1.com
    # Other directives here
    </VirtualHost>
    <VirtualHost *:80>
    DocumentRoot /www/example2
    ServerName www.example2.org
    # Other directives here
    </VirtualHost>
    (4)在多个IP地址的服务器上配置基于域名的虚拟主机:
    Listen 80
    # This is the "main" server running on 172.20.30.40
    ServerName server.domain.com
    DocumentRoot /www/mainserver
    # This is the other address
    NameVirtualHost 172.20.30.50
    <VirtualHost 172.20.30.50>
    DocumentRoot /www/example1
    ServerName www.example1.com
    # Other directives here ...
    </VirtualHost>
    <VirtualHost 172.20.30.50>
    DocumentRoot /www/example2
    ServerName www.example2.org
    # Other directives here ...
    </VirtualHost>
    (5)在不同的端口上运行不同的站点(基于多端口的服务器上配置基于域名的虚拟主机):
    Listen 80
    Listen 8080
    NameVirtualHost 172.20.30.40:80
    NameVirtualHost 172.20.30.40:8080
    <VirtualHost 172.20.30.40:80>
    ServerName www.example1.com
    DocumentRoot /www/domain-80
    </VirtualHost>
    <VirtualHost 172.20.30.40:8080>
    ServerName www.example1.com
    DocumentRoot /www/domain-8080
    </VirtualHost>
    <VirtualHost 172.20.30.40:80>
    ServerName www.example2.org
    DocumentRoot /www/otherdomain-80
    </VirtualHost>
    <VirtualHost 172.20.30.40:8080>
    ServerName www.example2.org
    DocumentRoot /www/otherdomain-8080
    </VirtualHost>
    (6)基于域名和基于IP的混合虚拟主机的配置:
    Listen 80
    NameVirtualHost 172.20.30.40
    <VirtualHost 172.20.30.40>
    DocumentRoot /www/example1
    ServerName www.example1.com
    </VirtualHost>
    <VirtualHost 172.20.30.40>
    DocumentRoot /www/example2
    ServerName www.example2.org
    </VirtualHost>
    <VirtualHost 172.20.30.40>
    DocumentRoot /www/example3
    ServerName www.example3.net
    </VirtualHost>

  10. SSL加密的配置
    首先在配置之前先来了解一些基本概念:
    • 证书的概念:首先要有一个根证书,然后用根证书来签发服务器证书和客户证书, 一般理解:服务器证书和客户证书是平级关系。SSL必须安装服务器证书来认证。 因此:在此环境中,至少必须有三个证书:根证书,服务器证书,客户端证书。 在生成证书之前,一般会有一个私钥,同时用私钥生成证书请求,再利用证书服务器的根证来签发证书。
    • SSL所使用的证书可以自己生成,也可以通过一个商业性CA(如Verisign 或 Thawte)签署证书。
    • 签发证书的问题:如果使用的是商业证书,具体的签署方法请查看相关销售商的说明;如果是知己签发的证书,可以使用openssl自带的CA.sh脚本工具。
    • 如果不为单独的客户端签发证书,客户端证书可以不用生成,客户端与服务器端使用相同的证书。
    (1) conf/ssl.conf 配置文件中的主要参数配置如下:
    Listen 443
    SSLPassPhraseDialog buildin
    #SSLPassPhraseDialog exec:/path/to/program
    SSLSessionCache dbm:/usr/local/apache2/logs/ssl_scache
    SSLSessionCacheTimeout 300
    SSLMutex file:/usr/local/apache2/logs/ssl_mutex
    <VirtualHost _default_:443>
    # General setup for the virtual host
    DocumentRoot "/usr/local/apache2/htdocs"
    ServerName www.example.com:443
    ServerAdmin you@example.com
    ErrorLog /usr/local/apache2/logs/error_log
    TransferLog /usr/local/apache2/logs/access_log
    SSLEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
    SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key
    CustomLog /usr/local/apache2/logs/ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    </VirtualHost>
    (2) 创建和使用自签署的证书:
    a.Create a RSA private key for your Apache server
    /usr/local/openssl/bin/openssl genrsa -des3 -out /usr/local/apache2/conf/ssl.key/server.key 1024
    b. Create a Certificate Signing Request (CSR)
    /usr/local/openssl/bin/openssl req -new -key /usr/local/apache2/conf/ssl.key/server.key -out /usr/local/apache2/conf/ssl.key/server.csr
    c. Create a self-signed CA Certificate (X509 structure) with the RSA key of the CA
    /usr/local/openssl/bin/openssl req -x509 -days 365 -key /usr/local/apache2/conf/ssl.key/server.key -in /usr/local/apache2/conf/ssl.key/server.csr -out /usr/local/apache2/conf/ssl.crt/server.crt
    /usr/local/openssl/bin/openssl genrsa 1024 -out server.key
    /usr/local/openssl/bin/openssl req -new -key server.key -out server.csr
    /usr/local/openssl/bin/openssl req -x509 -days 365 -key server.key -in server.csr -out server.crt
    (3) 创建自己的CA(认证证书),并使用该CA来签署服务器的证书。
    mkdir /CA
    cd /CA
    cp openssl-0.9.7g/apps/CA.sh /CA
    ./CA.sh -newca
    openssl genrsa -des3 -out server.key 1024
    openssl req -new -key server.key -out server.csr
    cp server.csr newreq.pem
    ./CA.sh -sign
    cp newcert.pem /usr/local/apache2/conf/ssl.crt/server.crt
    cp server.key /usr/local/apache2/conf/ssl.key/
---------------------------------------------------------------------------

512M VPS 性能和内存优化(安装的是apache webserver)


对于低端的VPS来说,因为内存本来就不是非常充足,所以如果你对Linux服务器平台的架设非常熟悉的话,完全可以不用什么控制面板;如果是一个 初学者,出于方便的考虑,可以安装轻型的Kloxo控制面板,功能强大,内存占用少(大约4M~8M),除了功能排版有些混乱之外,其他该有的功能都有, 不该有的功能也有,非常实用。
在优化Apache/MySQL之前,首先可以关掉一些不必要的后台守护进程,比如ClamAV(一个杀毒软件),你可以运行chkconfig –list查看哪些后台守护进程是不必要的,当然很多东西取决于你的具体应用。比如如果你不是经常登陆Kloxo,可以把Kloxo关闭;如果不发邮件, 可以关闭QMail,等等。如果碰到一些自己不熟悉的进程,千万别忙着下手,先去Google一下,以免出现其他预料之外的问题。关闭自动启动可以使用 chkconfig 守护进程名 off,但是内存中已经运行的守护进程不会被关闭,需要运行service 守护进程名 stop进行关闭。
接下来是Apache的优化。这个东西在VPS高效运行的时候,会占去至少一半以上的内存。通过修改/etc/httpd/conf/httpd.conf配置文件,用户可以进行内存占用和服务性能之间的微调以达到一个平衡的状态。
httpd.conf里面的几个关乎内存占用和性能的价格重要参数如下(仅用于常见的Apache Prefork模式):
StartServers Apache启动时创建的子进程数量
MinSpareServers 最小空闲子进程数量
MaxSpareServers 最大空闲子进程数量
ServerLimit (此参数只要不比MaxClients小就可以了)
MaxClients 最大同时能够处理的请求数
MaxRequestsPerChild 每个子进程处理多少请求之后自动结束,并且释放内存
KeepAlive 是否保持连接
MaxKeepAliveRequests 并发保持连接的最大数量
KeepAliveTimeout 保持连接超时设置
在Prefork工作模式下,Apache在启动之后会先创建StartServers设置的子进程数量,然后每隔一秒以指数形式(2^)创建更多 的子进程,直到子进程的总数达到MinSpareServers设置的数量为止。在Prefork模式下面,Apache无需等到连接请求时才生成新的子 进程,所以在响应速度上会有更好的性能。同时MaxSpareServers参数规定了Apache最多能够存在的空闲进程数量,在空闲进程数量超过 MaxSpareServers设置后,Apache会自动关闭部分空闲进程,以避免过多的空闲进程占用大量的内存。所以将 MinSpareServers和MaxSpareServers的参数改小,会减少VPS内存的占用,但同时也会降低VPS的性能。但是对于只有 512M内存的低端VPS来说,服务器的稳定性远比性能更为重要,性能再好,打不开网站也是白搭。
MaxClients参数是对性能和内存占用影响最大的参数,直接关系到并发访问的数量,超过MaxClients设置的额外连接请求,需要等待现 有连接断开之后,才能进行正常的连接。所以MaxClients如果设置的太小,会造成长时间的等待,进而会严重影响访问者的心情;但是如果设置的太大, 在有大量并发访问的情况下,Apache会很快用光所有的VPS内存,导致VPS宕机。所以MaxClients参数需要进行仔细的计算。对于一台 512M的VPS来说,通常CentOS启动后,加上Kloxo和MySQL,会占用大约80~100M的内存,所以能够供apache使用的内存不能超 过400M。而通过top命令,可以看到一般一个httpd进程会占用大约4M的内存(在Prefork模式下面),所以在这样的情况 下,MaxClients的设置不宜超过150。150个并发连接,对于普通的网站来说,已经是足够了,如果你的网站访问量非常之大,那么,直接入手高端 服务器即可。
MaxRequestsPerChild参数同样会影响性能和内存。影响性能的地方在于,如果将MaxRequestsPerChild的值设置的 太小,那么Apache需要不停的创建新的子进程来替代因为请求数达到限额的旧进程,而结束旧进程和创建新进程都需要消耗CPU时间,所以大量的结束、创 建动作会让一个VPS消耗不少的CPU,而通常一个VPS的CPU也是有限制的,所以过多的CPU消耗会明显影响VPS的性能;反过来说,如果 MaxRequestsPerChild设置成太大,或者干脆设置成0(不限制),那么如果在进程寿命结束前,碰到内存溢出之类的错误,VPS也会很快因 内存消耗完毕而宕机。
KeepAlive参数,是否保持链接,通常设置成On(打开)会提高性能,但是同时将KeepAliveTimeout超时设置的小一点,比如 5s,会让整个VPS显的更有效率。因为当KeepAliveTimeout设置的过大的时候,一个子进程在超时之前将无法服务更多的用户,这样势必 Apache需要打开更多的进程,进行会消耗本来就不充裕的VPS内存。
附抓抓的512M VPS的httpd.conf相关参数供参考:
StartServers 5
MinSpareServers 5
MaxSpareServers 20
ServerLimit 128
MaxClients 128
MaxRequestsPerChild 1000
KeepAlive On
MaxKeepAliveRequests 200
KeepAliveTimeout 5
在设置完参数之后,还需要精简一部分的模块(LoadModule)以减少不必要的内存占用。根据俺目前在用的经验,除了下面这些模块,其他都不是必须的:
mod_authz_host.so
mod_log_config.so
mod_expires.so
mod_deflate.so
mod_headers.so
mod_setenvif.so
mod_mime.so
mod_autoindex.so
mod_negotiation.so
mod_dir.so
mod_alias.so
mod_rewrite.so
mod_proxy.so(网上其他人的经验是可以不加载这个模块,不过抓抓试过启动apache会出错。。。)
保存httpd.conf,重启Apache即可生效。
在优化完Apache之后,还需要进行MySQL的优化,主要是修改/etc/my.cnf来达到降低MySQL内存占用的目的。
在/etc/my.cnf的[mysqld]段里面添加:
skip-locking
skip-bdb
skip-innodb
同样,保存后重启MySQL生效。
------------------------------------------------
Apache prefork 和 worker 的区别(各种MPM)

总的来说,要确定apache当前的MPM模式,可以执行(具体路径根据自己的apache安装路径情况确定)
/usr/local/apache2/bin/httpd -l  

看compiled in modules中,是worker.c还是perfork.c ?如果改变MPM模式,可以看下面的介绍。

        在支持POSIX线程的Unix系统上,Apache可以通过不同的MPM运行在一种多进程与多线程相混合的模式下。本文只是说明在2.0中影响性能的最核心特性:MPM(Multi-Processing Modules,多道处理模块)的基本工作原理和配置指令。
下面以Red Hat Linux 9为平台,说明在Apache 2.0中如何指定MPM (Apache采用2.0.45)。先解压缩源代码包httpd-2.0.45.tar.gz,生成httpd-2.0.45目录。
进入httpd-2.0.45目录,运行以下代码:
$ ./configure --help|grep mpm

显示如下:
--with-mpm=MPM Choose the process model for Apache to use. MPM={beos|worker|prefork|mpmt_os2| perchild|leader|threadpool}

上述操作用来选择要使用的进程模型,即哪种MPM模块。
Beos、mpmt_os2分别是BeOS和OS/2上缺省的 MPM,
perchild主要设计目的是以不同的用户和组的身份来运行不同的子进程。这在运行多个需要CGI的虚拟主机时特别有用,会比1.3版中的 SuExec机制做得更好。
leader和threadpool都是基于worker的变体,还处于实验性阶段,某些情况下并不会按照预期设想的那样工 作,所以Apache官方也并不推荐使用。
因此,我们主要阐述 prefork 和 worker 这两种和性能关系最大的产品级MPM ( 有关其它的MPM详细说明,请参见Apache官方文档:http://httpd.apache.org/docs-2.0/mod/)。

prefork的工作原理及配置
如果不用“--with-mpm”显式指定某种MPM,prefork就是Unix平台上缺省的MPM。它所采用的预派生子进程方式也是Apache 1.3中采用的模式。prefork本身并没有使用到线程,2.0版使用它是为了与1.3版保持兼容性;另一方面,prefork用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM之一。
若使用prefork,在make编译和make install安装后,使用“httpd -l”来确定当前使用的MPM,应该会看到prefork.c(如果看到worker.c说明使用的是worker MPM,依此类推)。这个图是我的 ./httpd -l  命令的结果



再查看缺省生成的httpd.conf配置文件,里面包含如下配置段:
<IfModule prefork.c>
        StartServers 5
        MinSpareServers 5
        MaxSpareServers 10
        MaxClients 150
        MaxRequestsPerChild 0
</IfModule>

prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销 以增加性能。
MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。 这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为MinSpareServers+1。如果站点负载 较大,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了 “MaxRequestsPerChild”个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如 果设成非零值也有两点重要的好处:
◆ 可防止意外的内存泄漏;
◆ 在服务器负载下降的时侯会自动减少子进程数。
因此,可根据服务器的负载来调整这个值。笔者认为10000左右比较合适。
MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其 缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef | grep http | wc -l来 确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置 和负载情况来动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。如果把这个值设为大于256,那么 Apache将无法起动。事实上,256对于负载稍重的站点也是不够的。在Apache 1.3中,这是个硬限制。如果要加大这个值,必须在“configure”前手工修改的源代码树下的src/include/httpd.h中查找 256,就会发现“#define HARD_SERVER_LIMIT 256”这行。把256改为要增大的值(如4000),然后重新编译Apache即可。在Apache 2.0中新加入了ServerLimit指令,使得无须重编译Apache就可以加大MaxClients。下面是笔者的prefork配置段:
<IfModule prefork.c>
        StartServers 10
        MinSpareServers 10
        MaxSpareServers 15
        ServerLimit 2000
        MaxClients 1000
        MaxRequestsPerChild 10000
</IfModule>

上述配置中,ServerLimit的最大值是20000,对于大多数站点已经足够。如果一定要再加大这个数值,对位于源代码树下server/mpm/prefork/prefork.c中以下两行做相应修改即可:
  1. define DEFAULT_SERVER_LIMIT 256
  2. define MAX_SERVER_LIMIT 20000


worker的工作原理及配置
相对于prefork,worker是2.0 版中全新的支持多线程和多进程混合模型的MPM。在configure -with-mpm=worker后,进行make编译、make install安装。在缺省生成的httpd.conf中有以下配置段:
<IfModule worker.c>
        StartServers 2
        MaxClients 150
        MinSpareThreads 25
        MaxSpareThreads 75
        ThreadsPerChild 25
        MaxRequestsPerChild 0
</IfModule>

worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的 ThreadsPerChild线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和 MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满 足负载,控制进程将派生新的子进程。
MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。
ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000。上述两个值位于源码树server/mpm/worker/worker.c中的以下两行:
  1. define DEFAULT_THREAD_LIMIT 64
  2. define MAX_THREAD_LIMIT 20000

这两行对应着ThreadsPerChild和ThreadLimit的限制数。最好在configure之前就把64改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因Apache不起动使系统很不稳定。
Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于 MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明 ServerLimit(最大值是20000)。这两个值位于源码树server/mpm/worker/worker.c中的以下两行:
  1. define DEFAULT_SERVER_LIMIT 16
  2. define MAX_SERVER_LIMIT 20000

需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于 MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非 期望值)。下面是笔者的worker配置段:
<IfModule worker.c>
        StartServers 3
        MaxClients 2000
        ServerLimit 25
        MinSpareThreads 50
        MaxSpareThreads 200
        ThreadLimit 200
        ThreadsPerChild 100
        MaxRequestsPerChild 0
</IfModule>

通过上面的叙述,可以了解到Apache 2.0中prefork和worker这两个重要MPM的工作原理,并可根据实际情况来配置Apache相关的核心参数,以获得最大的性能和稳定性。
-------------------------------------------------------------
Apache的prefork模式和worker模式

prefork模式
这个多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器,它的工作方式类似于Apache 1.3。它适合于没有线程安全库,需要避免线程兼容性问题的系统。它是要求将每个请求相互独立的情况下最好的MPM,这样若一个请求出现问题就不会影响到其他请求。

这个MPM具有很强的自我调节能力,只需要很少的配置指令调整。最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。

worker模式
此多路处理模块(MPM)使网络服务器支持混合的多线程多进程。由于使用线程来处理请求,所以可以处理海量请求,而系统资源的开销小于基于进程的MPM。但是,它也使用了多进程,每个进程又有多个线程,以获得基于进程的MPM的稳定性。

控制这个MPM的最重要的指令是,控制每个子进程允许建立的线程数的ThreadsPerChild指令,和控制允许建立的总线程数的MaxClients指令。

prefork和worker模式的切换
1.将当前的prefork模式启动文件改名
mv httpd httpd.prefork
2.将worker模式的启动文件改名
mv httpd.worker httpd
3.修改Apache配置文件
vi /usr/local/apache2/conf/extra/httpd-mpm.conf
找到里边的如下一段,可适当修改负载等参数:
<IfModule mpm_worker_module>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
4.重新启动服务
/usr/local/apache2/bin/apachectl restart
即可换成worker方式启动apache2

处于稳定性和安全性考虑,不建议更换apache2的运行方式,使用系统默认prefork即可。另外很多php模块不能工作在worker模式下,例如redhat linux自带的php也不能支持线程安全。所以最好不要切换工作模式。

prefork和worker模式的比较
prefork模式使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。prefork的无线程设计在某些情况下将比worker更有优势:它可以使用那些没有处理好线程安全的第三方模块,并且对于那些线程调试困难的平台而言,它也更容易调试一些。

worker模式使用多个子进程,每个子进程有多个线程。每个线程在某个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,因为Worker MPM的内存使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,如果一个线程崩溃,整个进程就会连同其所有线程一起"死掉".由于线程共享内存空间,所以一个程序在运行时必须被系统识别为"每个线程都是安全的"。

总的来说,prefork方式速度要稍高于worker,然而它需要的cpu和memory资源也稍多于woker。

prefork模式配置详解
<IfModule mpm_prefork_module>
ServerLimit 256
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 256
MaxRequestsPerChild 0
</IfModule>
ServerLimit
默认的MaxClient最大是256个线程,如果想设置更大的值,就的加上ServerLimit这个参数。20000是ServerLimit这个参数的最大值。如果需要更大,则必须编译apache,此前都是不需要重新编译Apache。
生效前提:必须放在其他指令的前面

StartServers
指定服务器启动时建立的子进程数量,prefork默认为5。

MinSpareServers
指定空闲子进程的最小数量,默认为5。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。

MaxSpareServers
设置空闲子进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不要设的太大。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。

MaxClients
限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,你必须同时增大ServerLimit。

MaxRequestsPerChild
每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。将MaxRequestsPerChild设置成非零值有两个好处:
1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。

worker模式配置详解
<IfModule mpm_worker_module>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>

StartServers
服务器启动时建立的子进程数,默认值是"3"。

MaxClients
允许同时伺服的最大接入请求数量(最大线程数量)。任何超过MaxClients限制的请求都将进入等候队列。默认值是"400",16(ServerLimit)乘以25(ThreadsPerChild)的结果。因此要增加MaxClients的时候,你必须同时增加ServerLimit的值。

MinSpareThreads
最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。

MaxSpareThreads
设置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。MaxSpareThreads的取值范围是有限制的。Apache将按照如下限制自动修正你设置的值:worker要求其大于等于MinSpareThreads加上ThreadsPerChild的和。

ThreadsPerChild
每个子进程建立的常驻的执行线程数。默认值是25。子进程在启动时建立这些线程后就不再建立新的线程了。

MaxRequestsPerChild
设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。将MaxRequestsPerChild设置成非零值有两个好处:
1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
注意对于KeepAlive链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为.
---------------------------------------------------------------
    512M vps apache内存优化配置方案(perfork)

本文是对512M 内存并装有apache的vps进行优化.

操作系统(linux):CentOS 5.5 32位(并不是我说这个比较好,只是Cents我用得比较熟练)
内存:512M
apache: 2.2 (建议低版本的,升级到高版本,毕竟旧版有很多问题,且性能也是高版本好点)
运行的主要是PHP程序,其他的不多说了,与本文关系不大。

首先,如题所说,本文所说的优化是针对apache 2.2以上版本,及使用perfork MPM模式的。perfork是apache在linux下默认安装下的模式,如果使用apache作为服务器的放在,还是使用perfork模式比较好,worker模式下对php某些功能并不支持。如果你使用的是win系统或都没有使有和perfork,那么下面可以选择不看或抱着学习的态度看看咯。

以下内容均属于博主自己的见解,实际测试请根据你的服务器,程序及其他因素按需处理。

一般情况下,我们需要优化apache就是因为apache占用大量的内存,导致vps当机,因为perfork是多进程处理的,每个进程都会点用一定的内存数量。所以限制httpd进程的数量,从而达到优化apache的作用。影响单个httpd进程的内存大小,主要都是加载模块,至少什么模块是合适的,我也很难说,因为这个是按由你的需要而定的。网上有些人说,绝大部分都会用不上的模块列出来,我认为这个是有很大的误导作用,因为绝大部分人中,也许你就是其中一个。将有用的模块屏蔽掉,最坏的情况,就是重启apache出错,或部分功能无法使用。所以我也不会列出什么最少模块加载方案什么的。所以,我只会说出一些参考。

apache(perfork)下的模块加载,并不是模块加载列表,没有的模块并不是屏蔽掉了,只是我也不清楚它的实际作用。
一、对于apache2.2,模块名有cache的一般都是有用的,因为有不少的这类模板都是2.1以上的apache才支持的,所以这类的模块不会是无缘无缘而存在的。
二、很有可能或必用到的模块有:
01    LoadModule auth_basic_module modules/mod_auth_basic.so
02    LoadModule authn_file_module modules/mod_authn_file.so
03    LoadModule include_module modules/mod_include.so
04    LoadModule log_config_module modules/mod_log_config.so
05    LoadModule expires_module modules/mod_expires.so
06    LoadModule deflate_module modules/mod_deflate.so
07    LoadModule headers_module modules/mod_headers.so
08    LoadModule setenvif_module modules/mod_setenvif.so
09    LoadModule mime_module modules/mod_mime.so
10    LoadModule autoindex_module modules/mod_autoindex.so
11    LoadModule negotiation_module modules/mod_negotiation.so
12    LoadModule dir_module modules/mod_dir.so
13    LoadModule alias_module modules/mod_alias.so
14    LoadModule rewrite_module modules/mod_rewrite.so

三、我粗略点了一下apache里面的模块约在50+以,要从中选择人人都适用的模块加载列表是不可能的,至少cgi模块我是不会用,但不排除你不会用。

模块加载这一块就说到这里,这个大家多百度,多用自然会识别出一些有用模块并渐渐屏蔽不使用的模块。

接下来,就是最为重要的perfork配置,也是困扰了我很久的问题,尽管参数就那么6个,那是却足以让你的vps当机。先列出需要修改的参数,修改位于httpd.conf的文件里面
01    Timeout 30
02    KeepAlive On
03    MaxKeepAliveRequests 80
04    KeepAliveTimeout 15
05   
06    <IfModule prefork.c>
07    ServerLimit 150
08    StartServers      5
09    MinSpareServers   5
10    MaxSpareServers   10
11    MaxClients       150
12    MaxRequestsPerChild 4000
13    </IfModule>

上面的代码就是要修改的,实际上我们是要修改perfork里在的参数,之所以将Timeout,KeepAlive等也写出来,是因为这个也是影响apache性能的。

Timeout是一个连接多少时间后断开,这个参数设置在30-60是一般的php程序都是适用的,至少要运行一些要占用大量时间的php程序,那么适当调高也是可以的,但请不要太高,否则会影响apache性能,本次优化我们使用30就很足够了。

MaxKeepAliveRequests 是一个连接最大的请求量,对于页面有较多的图片等元素,可以适当调高一点,对于一般的网页设置在80-120是足够的,我们就设置为100,如果设置太高会导致httpd长时间不能退出释放内存的。

KeepAliveTimeout 是当用户处理一次连接时,如果在该参数的时间内还有请求则会继续执行,不需要重新创建新的连接,直到达到MaxKeepAliveRequests的最大值才会退出。对于perfork模式下的,有人认为是将KeepAlive Off会比较好,但是对于绝大多数的网站都会不多不少有些图片元素,所以将该项打开,并将KeepTimeOut设置在2-5秒,不但有效提高服务器性能,也能加快页面打开速度。

接下来,就是正式进入perfork的参数设置了,不想服务器运行一会就内存占满的得看看哦。

首先是参数ServerLimit就是服务器最大支持同时连接的客户端,该值将决定下面参数MaxClient可以设定的值的范围。ServerLimit实际上只是起到一个限制的作用,并没有实际有作用,也许有,我就不知道了。实际上起到作用的是,MaxClient参数,但这个值又受ServerLimit的限制,等下会讲。

另三个参数StartServers,MinSpareServers,MaxSpareServers,为什么将这三个参数一起说呢,因为这三个数是联系在一起的。这三个数都是决定空闲进程数量,StartServers应该范围就是MinSpareServers和MaxSpareServers之间。否则,apache会自动将该值还原到两都之间,所以不要浪费不必要的资源。按照perfork默认的配置,这三个参数分别为:5,5,10。但是对于只有512M内存的vps来说,我认为还是有过大的负载。因此,我认为在这里应该退一步,将这三个参数设置为4,4,10,看起来和上面5,5,10并没有什么不同,最大值还是10,但在实际使用中4,4,10释放的内存速度会明显比5,5,10快很多。

接下来就是MaxClient最大支持多少客户端在同一时间连接服务器,简单说就是最大并发数支持,这个没有特别需要说的。对于512M的vps你也别想你的站能承受百万PV,使用默认的150已是超出负载的了。一般将ServerLimit和MaxClient设为一样值即可。

最后就是MaxRequestsPerChild参数,一个进程在处理多少次之后退出,设置为0则是无限次,也就是说不会退出,那么httpd进程也不会退出。那么,你就等着你的vps当机重启去吧。对于这个参数,我粗略地搜索了一下,不少人推荐在1000次,也有100次的。据我的测试,对于内存只有512M的vps来说,该值设置在500以上都会很快占满内存,但不至少于当机。而观察得知,一但内存占满,cpu的使用率几乎变为0了。由此可知,当机了那什么都干不了了,还不如消耗多一点cpu资源避免,提高稳定性。所以,我最后的决定是将该值定义在30-40之间。这样设定后,可以看出,内存释放速度得到很大的提升,但也可以看到cpu也在频繁上下跳动。这样设置,即使内存占满,也能在最短时间恢复正常。

所以对于512MB的vps,apache(perfork模式)最后的优方配置为:
01    Timeout 30
02    KeepAlive On
03    MaxKeepAliveRequests 100
04    KeepAliveTimeout 2
05   
06    <IfModule prefork.c>
07    ServerLimit 150
08    StartServers      4
09    MinSpareServers   4
10    MaxSpareServers   10
11    MaxClients       150
12    MaxRequestsPerChild 40
13    </IfModule>

这样,我们的配置基本完成,进行负载测试即可。负载测试,我们使用ab测试,先声明一点,是用你本地的虚拟机去测试服务器上的一个静态页面,而不是在服务器上测试。之前,我就是这样做,因为网速一样,效果都是比较好的,但别人都是不同网速的,所以服务器上测试是不准备的。

文章就写到这里.
------------------------
调整/etc/apache2/apache2.conf文件中的各种数据:

1    # worker MPM
2    <IfModule mpm_worker_module>
3        StartServers         1
4        MinSpareThreads      3
5        MaxSpareThreads      32
6        ThreadLimit          16
7        ThreadsPerChild      16
8        MaxClients           128
9        MaxRequestsPerChild  3000
10    </IfModule>

因为是worker模式,所以最大总的工作线程是MaxClients来管的,它等于最大进程数x线程数。我原来设的比较大,所以造成内存问题,现在调成,每个apache进程开16个线程,当空闲线程小于3的时候开始增加线程,空闲线程大于32的时候开始减少——也就是最多开两个进程。每3000个请求就推出这个进程,重新建立。

更改/etc/php5/fpm/pool.d/www.conf文件:
1    pm = dynamic
2    pm.max_children = 32
3    pm.start_servers = 3
4    pm.min_spare_servers = 3
5    pm.max_spare_servers = 5
6    pm.max_requests = 2000
7    request_terminate_timeout = 600s

和上边类似因为以后准备上google的pagespeed模块,会提供缓存,所以初期静态请求会高于动态,而且php出现内存leak的可能行大一些。

更改之后,感觉稳定多了,但是还需要时间的检验.