Apache-配置、测试和调试
首先执行下面的指令列出有用的Apache配置信息
grep -v '#' /usr/local/apache2/etc/httpd.conf |grep -v '^$'
ServerRoot "/usr/local/apache2/" #指定守护进程httpd的运行目录, 服务器的根目录, 不要在目录结尾加'/', 配置文件内使用的目录都是以此目录为根节点, 比如modules/mod_rewrite.so就存储在/usr/local/apache2/modules
文件夹下 Listen 8000 #服务器监听的端口
BindAddress * #绑定监听IP地址
Listen 12.34.56.78:80 #Listen参数可以指定服务器除了监视标准的80端口之外, 还监视其他端口的HTTP请求, 由于FreeBSD系统可以同时拥有多个IP地址, 因此也可以指定服务器只听取对某个BindAddress</B>的IP地址的HTTP请求,
如果没有配置这一项, 则服务器会回应对所有IP的请求, 即使使用了BindAddress参数, 使得服务器只回应对一个IP地址的请求, 但是通过使用扩展的Listen参数, 仍然可以让HTTP守护进程回应对其他IP地址的请求, 此时Listen参数
的用法与上面的第二个例子相同, 这种比较复杂的用法主要用于设置虚拟主机, 此后可以用 VirtualHost参数定义对不同IP的虚拟主机, 然而这种用法是较早的HTTP 1.0标准中设置虚拟主机的方法, 每针对一个虚拟主机就需要一个IP
地址, 实际上用处并不大, 在HTTP/1.1中, 增加了对单IP地址多域名的虚拟主机的支持, 使得虚拟主机的设置具备更大的意义
PidFile logs/httpd.pid #指定的文件将记录httpd守护进程的进程号, 由于httpd能自动复制其自身, 因此系统中有多个httpd进程, 但只有一个进程为最初启动的进程, 它为其他进程的父进程, 对这个进程发送信号将影响所有的httpd进程
PidFile定义的文件中就记录httpd父进程的进程号
Timeout 300 #定义客户程序和服务器连接的超时间隔,超过这个时间间隔(秒)后服务器将断开与客户机的连接。
KeepAlive On #在HTTP/1.0中, 一次连接只能作传输一次HTTP请求, 而KeepAlive参数用于支持HTTP1.1版本的一次连接、多次传输功能, 这样就可以在一次连接中传递多个HTTP请求, 只有较新的浏览器才支持, 但还是打开使用这个选项
MaxKeepAliveRequests 100 #为一次连接可以进行的HTTP请求的最大请求次数, 将其值设为0将支持在一次连接内进行无限次的传输请求, 事实上没有客户程序在一次连接中请求太多的页面, 通常达不到这个上限就完成连接了
KeepAliveTimeout 15 #测试一次连接中的多次请求传输之间的时间, 如果服务器已经完成了一次请求, 但一直没有接收到客户程序的下一次请求, 在间隔超过了这个参数设置的值之后, 服务器就断开连接, 注意与Timeout的区别
#一次请求后, 保持连接需要占用资源, 所以此值不能过大
ThreadsPerChild 50 #设置服务器使用进程的数目 这是以服务器的响应速度为准的, 数目太大则会变慢
MaxRequestsPerChild 30 #使用子进程的方式提供服务的Web服务, 常用的方式是一个子进程为一次连接服务, 这样造成的问题就是每次连接都需要生成、退出子进程的系统操作, 使得这些额外的处理过程
占据了计算机的大量处理能力, 因此最好的方式是一个子进程可以为多次连接请求服务, 这样就不需要这些生成、退出进程的系统消耗, Apache就采用了这样的方式, 一次连接结束
后, 子进程并不退出, 而是停留在系统中等待下一次服务请求, 这样就极大的提高了性能, 但由于在处理过程中子进程要不断的申请和释放内存, 次数多了就会造成一些内存垃圾,
就会影响系统的稳定性, 并且影响系统资源的有效利用, 因此在一个副本处理过一定次数的请求之后, 就可以让这个子进程副本退出, 再从原始的httpd进程中重新复制一个干净的
副本, 这样就能提高系统的稳定性, 这样, 每个子进程处理服务请求次数由MaxRequestPerChild定义, 缺省的设置值为30, 这个值对于具备高稳定性特点的FreeBSD系统来讲是过于
保守的设置, 可以设置为1000甚至更高, 设置为0支持每个副本进行无限次的服务处理, 为了安全,设置为零
ExtendedStatus On #Apache服务器可以通过特殊的HTTP请求, 来报告自身的运行状态, 打开这个ExtendedStatus参数可以让服务器报告更全面的运行状态信息
ServerAdmin suiyong_jie@163.com #这将在HTTP服务出现错误的条件下返回给浏览器, 以便让Web使用者和管理员联系, 报告错误
ServerName localhost #缺省情况下, 并不需要指定这个ServerName参数, 服务器将自动通过名字解析过程来获得自己的名字, 但如果服务器的名字解析有问题(通常为反向解析不正确), 或者没有正式的DNS名字, 也可以在这里指定IP
地址, 当ServerName设置不正确的时候, 服务器不能正常启动, 通常一个Web服务器可以具有多个名字, 客户浏览器可以使用所有这些名字或IP地址来访问这台服务器, 但在没有定义虚拟主机的情况下, 服务器总是以自己的正式名字回应
浏览器, ServerName就定义了Web服务器自己承认的正式名字, 例如一台服务器名字(在DNS中定义了A类型)为 freebsd.exmaple.org.cn, 同时为了方便记忆还定义了一个别名(CNAME记录)为www.exmaple.org.cn, 那么Apache
自动解析得到的名字就为freebsd.example.org.cn, 这样不管客户浏览器使用哪个名字发送请求, 服务器总是告诉客户程序自己为freebsd.example.org.cn, 虽然这一般并不会造成什么问题, 但是考虑到某一天服务器可能迁移到其他
计算机上, 而只想通过更改 DNS中的www别名配置就完成迁移任务, 所以不想让客户在其书签中使用 freebsd记录下这个服务器的地址, 就必须使用ServerName来重新指定服务器的正式名字
TypesConfig /usr/local/apache2/etc/mime.types #用于设置保存有不同的MIME类型数据的文件名 可以用命令查看下其内容
MIMEMagicFile /usr/local/apache2/etc/magic #除了从文件的后缀出发来判断文件的MIME类型之外, Apache还可以进一步分析文件的一些特征, 来判断文件的真实MIME类型, 这个功能是由mod_mime_magic模块实现的, 它需要一个
记录各种MIME类型特征的文件, 以进行分析判断, 上面的设置是一个条件语句, 如果载入了这个模块, 就必须指定相应的标志文件magic的位置
HostnameLookups Off #一般访问日志只会记录客户机IP, 此选项配置是否记录客户机的主机名以进行日志记录和提供给CGI程序使用 每次请求使用DNS反查询 增加系统开销
ServerSignature On #一些情况下, 例如当客户请求的网页并不存在时, 服务器将产生错误文档, 缺省情况下由于打开了ServerSignature选项, 错误文档的最后一行将包含服务器的名字、Apache的版本等信息, 有的管理员更倾向于
不对外显示这些信息, 就可以将这个参数设置为Off, 或者设置为Email, 最后一行将替换为对ServerAdmin 的Email提示 LoadModule deflate_module modules/mod_deflate.so #要使用基于DSO的功能模块, 加载对应的模块 模块载入的顺序很重要 运行"apche -l"将列表显示Apache内建的模块 LoadModule expires_module modules/mod_expires.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule php5_module modules/libphp5.so <IfModule !mpm_netware_module> #IfModule就是如果加载了某个模块就执行其内的配置代码 <IfModule !mpm_winnt_module> User daemon #Apache进程的执行者是daemon Group daemon #Apache进程的执行者所属组为daemon </IfModule> </IfModule>
ServerName localhost ServerAdmin suiyong_jie@163.com #管理员邮箱 DocumentRoot "/htdocs" #网站的根目录, 默认状态下,所有的请求都以这个目录为基础
<Directory /> #设置服务器本身根目录(Linux的/)及其子目录具有基本权限 Options FollowSymLinks #Options指定在此目录中将使用哪些服务器特性, 里面指令都可以在前面加上"+"或者"-"来增加或者删除, None, All, Includes(允许服务器页面内嵌套页面, 比如在一个静态页面中嵌套
<!--#include file="public/header.html"-->), Indexes(如果一个映射到目录的URL被请求, 而此目录中又没有DirectoryIndex(例如: index.html), 那么服务器会返回一个格式化后的目录列表, 如果去掉Indexes
就不会显示目录结构), ExecCGI(允许此目录下执行CGI脚本), MultiViews(服务器执行一个隐含的文件名模式匹配, 并在其结果中选择, 比如在地址栏内输入index.php可以显示页面, 在地址栏内输入index同样可以显示
index.php页面),FollowSymLinks不检查文件是否是符号链接(快捷方式), 如果是符号链接就解析符号链接指向真正的目录或文件(可以使程序访问根目录以外的目录), 开启后会对请求的每个目录或者文件都会进行检查, 速度变慢 AllowOverride None #当为None时.htaccess文件里的指令无效, 即不用查看这个目录下的相应访问控制文件 Order deny,allow #设定拒绝和允许的先后顺序, 如果"deny, allow"表示拒绝所有的访问, 除去明确允许的; "allow, deny"表示允许所有的, 除去明确拒绝的 Deny from all #Deny from、Allow from后可以跟IP地址, 域名, All(所有) </Directory> <Directory "/htdocs"> #/htdocs目录的权限选项设置 Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory>
#以上ServerName, ServerAdmin和, ocumentRoot和Directory为一个域名下访问的情况, 以下介绍多个域名对应一台服务器(虚拟主机)的情况, 只要在hosts文件里把www.a.com和www.b.com与192.168.209.128绑定就OK了
NameVirtualHost 192.168.209.128 <VirtualHost 192.168.209.128> DocumentRoot /htdocs/win ServerName www.a.com </VirtualHost> <VirtualHost 192.168.209.128> DocumentRoot /htdocs/manager CustomLog /htdocs/manager/home-access_log common ServerName www.b.com </VirtualHost>
<Directory "/htdocs/win"> Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> <Directory "/htdocs/manager"> Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory>
#虚拟主机配置结束
<IfModule dir_module> DirectoryIndex index.shtml index.php index.html #设置目录默认首页 </IfModule> <FilesMatch "^\.ht"> #如果请求的文件名符合"^\.ht", 则设置以下权限, 也可以应用为"jpg|gif|png|js|css|swf", 如果要匹配文件夹则需要用DirectoryMatch Order allow,deny Deny from all Satisfy All #暂时不知道 </FilesMatch> ErrorLog "logs/error_log" #指定错误日志存放的文件 也可以通过CustomLog /var/log/httpd-access.log [common|referer|agent|combined]来配置详细的各种日志存放位置 即普通访问|引用页面|客户端记录|联合记录 LogLevel warn #用于调整记于错误日志中的信息的详细程度 <IfModule log_config_module> # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> CustomLog "logs/access_log" common </IfModule>
<IfModule mpm_prefork_module> #Apache有两种工作模式, prefork, worker
ServerLimit 1000 #在Apache1.3的时候加入想增加MaxClients超过256则需要在configure之前修改src/include/httpd.h中的#define HARD_SERVER_LIMIT 256, 将256改为想要的大值, 然后重新编译安装Apache, 而
在Apache2.0中只需要添加ServerLimit列, 无须重新编译就可以增加MaxClients的值超过256 ServerLimit和MaxClients在配置文件中出现的先后顺序是不可以颠倒的
StartServers 5 #服务器启动时建立的子进程数量 在该工作模式下, 服务器启动后起动5个httpd进程(加父进程共6个, 在Linux中通过ps -ax|grep httpd命令可以看到)
MinSpareServers 5 #空闲子进程的最小数量 所谓空闲子进程就是没有正在处理请求的子进程 如果当前空闲子进程烧油MinSpareServers, Apache会以每秒一个翻倍型的速度产生新的子进程(第一秒1个, 第二秒2个, 第三秒4个)
当有用户连接时, apache会使用一个空闲进程为该连接服务, 同时父进程会fork一个子进程, 直到内存中的空闲进程达到MaxSpareServers(那个处理请求的进程处理完后也就变成空闲进程了)
MaxSpareServers 10 #最多空闲子进程, 如果空闲子进程多于此值Apache会kill掉多于的子进程, 且此值比MinSpareServers要大, 如果比MinSpareServers小的话会自动修改为MinSpareServers+1
MaxClients 150 #此项中最重要的一个配置 Apache可以同时处理的请求 这是对Apache性能影响最大的参数 指服务于客户端请求的最大请求数, 即限制同一时间客户端最大接入请求的数量, 默认值为256, 任何超过MaxClients
限制的请求都将进入等候队列, 一旦一个连接被释放, 队列中的请求将得到服务, 在Apache1.3中最大只能设置为256, 但在Apache2.0中, 可以通过在配置开头(必须在MaxClients之前)增加ServerLimit项目来突破256的
限制, 此时必须MaxClients ≤ ServerLimit ≤ 20000
MaxRequestsPerChild 1000 #每个子进程被处理多少次后被kill掉, 设为0泽表示不限制, 与上文的那个MaxRequestsPerChild是相同的, 不要重复, 推荐设为1000
</IfModule>
#上面的工作原理 首先服务启动后会创建以StartServers个数的进程, 然后等待来自客户端的请求, 我们这里先假设从客户端来了大量的请求, 这时Apache服务器会根据自身的负载情况自动创建新进程, 如果服务器一直没有空闲进程那么它
就会一直创建新进程, 直到满足MaxClients和ServerLimit设置的最大值, 如果来自客户端的负载没有那么大, Apache服务器将会根据MinSpareServers、MaxSpareServers和MaxRequestsPerChild设置的值来杀掉多余的
进程, 其中每个进程在某个确定的时间只能维持一个连接
#然后, 在访问量高峰期, 经常会出现的情况是突然之间发生非常多的并发连接, 然后突然之间减少了很多访问, 如果Apache没有准备足够数量的预备进程, 那访问只能等待Apache每秒1个的新增进程, 随后又要将多余的进程删除, 那Apache
只能一直忙于新建和销毁进程, 大大地降低了访问速度, 可以 适当增加StartServers、MinSpareServers、MaxSpareServers来使得Apache不需要一直忙于作无用功
#强烈推荐MaxRequestsPerChild不要设置为0, 设置为非0, 可以保护Apache进程免遭内存泄漏的影响, 因为你不知道运行在Apache上的应用程式在什么时候会出错导致内存泄漏
#可以根据服务器性能进行优化比如
#ServerLimit 1000
#StartServers 30
#MinSpareServers 30
#MaxSpareServers 45
#MaxClients 1000
#MaxRequestsPerChild 4000
#优化
#查看当前连接数
#pgrep httpd|wc -l
#计算httpd占用内存的平均数
#ps aux|grep -v grep|awk '/httpd/{sum+=$6;n++};END{print sum/n}'
#由于基本都是静态页面, CPU消耗很低, 每进程占用内存也不算多, 大约200K
#服务器内存有2G, 除去常规启动的服务大约需要500M(保守估计), 还剩1.5G可用, 那么理论上可以支持1.5*1024*1024*1024/200000 = 8053.06368
#约8K个进程, 支持2W人同时访问应该是没有问题的(能保证其中8K的人访问很快, 其他的可能需要等待1、2秒才能连上, 而一旦连上就会很流畅(可以根据配置细想一下这句话))
#可以配置为如下
#ServerLimit 5500
#MaxClients 5000
<IfModule mpm_worker_module> #内存使用比prefork要少的多 但不完善处在于一个线程崩溃, 其他线程全玩完
ServerLimit 12 #同上
StartServers 2 #与上同 该模式是由线程来监听客户的连接, 当有新客户连接时, 由其中的一个空闲线程接受连接, 服务器在启动时启动两个进程, 每个进程产生的线程数是固定的(ThreadsPerChild决定), 因此启动时
有50个线程(进程数*ThreadsPerChild), 当50个线程不够用时, 服务器自动fork一个进程,再产生25个线程。
MaxClients 150 #最大并发连接数
MinSpareThreads 25 #服务器保持的最小空闲线程数 每一个线程在某个确定的时间只能维持一个连接,
MaxSpareThreads 75 #服务器保持的最大空闲线程数
ThreadLimit 75 #每个子进程可以创建的线程数, 即ThreadPerChild的上限
ThreadsPerChild 25 #每个子进程的产生的线程数
MaxRequestsPerChild 0 #与上同
</IfModule>
<IfModule mpm_perchild_module>
NumServers 5 #服务器启动时启动的子进程数
StartThreads 5 #每个子进程启动时启动的线程数
MinSpareThreads 5 #内存中的最小空闲线程数
MaxSpareThreads 10 #最大空闲线程数
MaxThreadsPerChild 2000 #每个线程最多被请求多少次后退出, 0不受限制
MaxRequestsPerChild 10000 #每个子进程服务多少次后被重新fork, 0表示不受限制
</IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "/usr/local/apache2//cgi-bin/" #它标明此目标目录下只有CGI脚本 使不在DocumentRoot目录下的内容也能成为文档树的一部分 ScriptAlias也是用于URL路径的映射, 但与Alias的
不同在于, ScriptAlias是用于映射CGI程序的路径, 这个路径下的文件都被定义为CGI程序, 通过执行它们来获得结果, 而非由服务器直接返回其内容, 缺省情况下CGI程序使用cgi-bin目录作为虚拟路径 </IfModule> <IfModule cgid_module> </IfModule>
Alias /icons/ "/usr/local/www/icons/" #Alias参数用于将URL与服务器文件系统中的真实位置进行直接映射, 一般的文档将在DocumentRoot 中进行查询, 然而使用Alias定义的路径将直接映射到相应目录下, 而不再到
DocumentRoot下面进行查询, 因此Alias可以用来映射一些公用文件的路径, 例如保存了各种常用图标的icons路径, 这样使得除了使用符号连接之外, 文档根目录(DocumentRoot)外的目录也可以通过使用了Alias映射,
提供给浏览器访问, 定义好映射的路径之后, 应该需要使用Directory语句设置访问限制 <Directory "/usr/local/apache2//cgi-bin"> #配置/usr/local/apache2//cgi-bin的目录权限 AllowOverride None Options None Order allow,deny Allow from all </Directory> DefaultType text/plain #如果Web服务器不能决定一个文档的缺省类型, 这通常表示文档使用了非标准的后缀, 那么服务器就使用DefaultType定义的MIME类型将文档发送给客户浏览器, 这里的设置为text/plain, 这样设置的问题是
如果服务器不能判断出文档的MIME, 那么大部分情况下这个文档为一个二进制文档, 但使用 text/plain格式发送回去, 浏览器将在内部打开它而不会提示保存, 因此建议将这个设置更改为application/octet-stream, 这样浏览器将提示
用户进行保存 <IfModule mime_module> TypesConfig etc//mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz </IfModule> <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> AddType application/x-httpd-php .php .phps