Apache学习-Apache入门
Apache介绍
Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一。它快速、可靠并且可通过简单的API扩充,将Perl/Python等解释器编译到服务器中。
特点:
- Apache模块分为静态模块与动态模块,静态模块是Apache最基本的模块,是无法随时添加与卸载的模块,静态模块在编译软件时设定的。动态模块是可以随时添加和删除的模块。
- Apache模块将被编译为动态共享对象(DSO),这些动态共享对象独立于httpd程序,DSO模块可以在编译Apache时添加,也可以在后期随时通过Apache extension Tool(apxs)工具编译添加模块。
- 使用HTTP -M 命令查看模块加载清单。
应用场合:
- 使用Apache运行静态html网页、图片、处理静态小文件能力不及nginx。
- 使用Apache结合php引擎运行PHP、Perl、Python等程序,LAMP被称为经典组合。
- 使用Apache结合tomcat、resin运行jsp、java等程序,成为中小企业的首选。
- 使用Apache做代理、负载均衡、rewrite规则过滤等等。
实战
安装依赖包
1 | yum install zlib-devel zlib apr-devel apr-util -y |
安装Apache软件
1 | cd /usr/local/src |
编译参数解释
1 | ./configure --prefix=/application/apache-2.4.25 \ |
启动Apache服务:
1 | /data/app/apache/bin/apachectl -t |
常见的启动命令
- start 启动httpd程序
- stop 停止httpd程序
- restart 重启httpd程序
- graceful 优雅重启,不中断现有的HTTP连接请求。
- graceful-stop 优雅停止,不中断现有的http连接请求。
- status 查看httpd当前的状态。
- configtest 检查httpd主配置文件语法。
查看结果:
1 | [root@nfs-client apache]# lsof -i :80 |
1 | [root@nfs-client apache]# ps -ef |grep httpd |
在客户端使用浏览器访问该web站点,出现IT works 。表示成功。
bin目录下命令介绍
ab
: Apache 服务器性能测试工具,同类软件还有jmeter
、loadrunner
、webbench
等。apachectl
: 这是Apache的启动脚本。apxs
: apxs是一个为Apache服务器编译和安装扩展模块的工具,在进行dso方式编译模块时会用到。htcacheclean
: 这是清理磁盘缓存去的命令,需要在编译时指定相关参数才可使用。htpasswd
: 建立和更新基本认证文件。httpd
: httpd 为Apache的控制命令程序,apachectl 执行时会调用httpd。rotatelogs
: Apache 自带的日志轮询明白,工作中习惯用由cronolog 代替。
配置文件解析
Apache主要配置文件主要有指令及容器组成,容器使用<容器名称>开始,以</容器名称>结尾,容器的指令一般仅在容器内有效。
/data/app/apache/conf/extra
#这是额外的Apache配置文件目录,这个目录里的文件我们会经常访问修改。
/data/app/apache/conf/httpd.conf
#Apache的主配置文件,这个文件我们会经常访问修改,其中的每一行的参数做用都应该弄清楚明白。
1 | ServerRoot "/data/app/apache-2.4.25" |
ServerRoot "/data/app/apache-2.4.25"
:指定Apache软件的安装主目录Listen 80
:指定服务器监听的ip和端口号,格式:Listien [ip地址:]端口 [协议]。一个配置文件中多次使用Listen指令开启多个端口。LoadModule alias_module modules/mod_alias.so
:加载动态模块,模块文件一般都位于modules目录中。ifModule容器可以封装仅在条件满足时才会出来的指令,语法格式:<IfModule [!] 模块>指令
1 | <IfModule unixd_module> |
上面的配置文件解释:仅在Apache加载了unixd_module模块后,User daemon和Group daemon才会被处理。
ServerAdmin you@example.com
:提供一个管理员邮箱。DocumentRoot "/data/app/apache-2.4.25/htdocs"
:该指令设置web服务器对客户端开发可见的文档根目录,即客户端访问的根目录。Directory
容器内的指令仅应用于特定的文件系统目录、子目录已经目录下的内容。路径可以使用~匹配正则表达式。
1 | <Directory "/data/app/apache-2.4.25/htdocs"> |
DirectoryIndex index.html
:指定当前目录下默认访问的HTML是什么。Files
:该容器类似于Directory容器,但Files容器内的指令仅应用于特定的文件。
1 | <Files ".ht*"> |
ErrorLog "logs/error_log"
: 指定服务器错误日志的位置。LogLevel warn
: 指定日志级别。LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
: 用户日志文件格式。使用LogFormat 指令设置日志格式创建别名,通过CustomLog 指令调用该日志格式别名。CustomLog "logs/access_log" common
:该指令设置客户端访问日志文件名及日志格式。ScriptAlias /cgi-bin/ "/data/app/apache-2.4.25/cgi-bin/"
: 设置脚本的别名。AllowOverride None
:在 AllowOverride 设置为 None 时, .htaccess 文件将被完全忽略。当此指令设置为 All 时,所有具有 “.htaccess” 作用域的指令都允许出现在 .htaccess 文件中。
通常利用Apache的rewrite模块对 URL 进行重写的时候, rewrite规则会写在 .htaccess 文件里。但要使 apache 能够正常的读取.htaccess 文件的内容,就必须对.htaccess 所在目录进行配置。从安全性考虑,根目录的AllowOverride属性一般都配置成不允许任何Override 。
Options None
:为特定目录设置选项。None表示不启用额外选项。
- All:开启除MultiViews之外的所有选项。
- ExecCGI:允许执行Options指定目录下的所有CGI脚本。
- FollowSymlinks:允许Options指定目录下的文件链接到目录外的文件或目录。
- Indexes:如果与URL对应的Options 目录下找不到DirectoryIndex指定的首页文档,则Apache会将当前目录下的所有文件索引出来。
RequestHeader unset Proxy early
:Include conf/extra/proxy-html.conf
:
Order 指令
控制默认访问状态已经Allow与Deny的次序。
如果使用 Order Deny,Allow ,则先检查拒绝,在检查允许,当拒绝与允许有冲突是,允许优先,默认规则为允许。
如果使用 Order Allow,Deny ,则先检查允许,在检查拒绝,当允许与拒绝有冲突是,拒绝优先,默认规则为拒绝。
实例
1 | order deny,allow |
先检查拒绝规则,在检查允许规则,默认为允许,deny拒绝所有,所有最终结果为拒绝所有。
1 | order allow,deny |
先检查允许规则,在检查拒绝规则,默认为拒绝,allow允许所有,所有最终结果为允许所有。
1 | order allow,deny |
先检查allow 规则,允许192.168.56.1,其余为默认,默认为拒绝所有,最终除192.168.56.1外拒绝所有。
1 | order allow,deny |
先检查允许规则允许192.168.56.1访问,在检查拒绝规则为拒绝所有,而192.168.56.1也包含在all中。当allow 与 deny 有冲突时,以order最后的规则覆盖其他规则,本例将使用deny规则覆盖allow规则,最终效果为拒绝所有人访问。
1 | order deny,allow |
先检查拒绝规则,在检查允许规则,拒绝规则为拒绝所有,允许规则为允许192.168.56.1,拒绝与允许规则有冲突的部分,以order最后的规则覆盖其他规则,最终实现仅允许192.168.56.1访问,其他任何主机均无法访问Apache服务。
Require指令
Apache 2.2 使用order命令限制访问,Apache 2.4 使用require命令限制访问。
Some of the allowed syntaxes provided by mod_authz_user, mod_authz_host, and mod_authz_groupfile are:
Require valid-user
All valid users can access the resource.
Require ip 10 172.20 192.168.2
Clients in the specified IP address ranges can access the resource.
Other authorization modules that implement require options include mod_authnz_ldap, mod_authz_dbm, mod_authz_dbd, mod_authz_owner and mod_ssl.
1 | Require all denied # 拒绝所有请求 |
TypesConfig 指定mime type的配置文件。
AddType 添加服务器支持的的mime type 类型。
1 | <IfModule mime_module> |
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
apache2.4开始SSLCertificateChainFile指令以不存在,把服务器证明书和中继证明书的内容保存到一个文件,并在SSLCertificateFile指令里指定该文件。
补充说明
支持CGI的配置,现在基本已经淘汰了。
1 | <IfModule alias_module> |
httpd-vhosts.conf 虚拟机主机配置
虚拟主机:部署多个站点,每个站点,希望用不同的域名和站点目录,或者是不同的端口,不同的IP。需要虚拟主机功能。
虚拟主机分类:
- 基于域名。
- 基于端口。
- 基于IP。
1 | NameVirtualHost *:80 #虚拟主机 * 表示所有的IP地址。 |
MPM 多路处理模块
查看当前使用的是那种MPM模块
1 | ./bin/httpd -l |
如果你看到perfork.c 则表示当前为perfork MPM模式。worker.c 则表示为 worker MPM模式。
如何指定MPM
指定./configure –with-mpm=worker/prefork
选项指定MPM,NAME就是你想使用的MPM的名称。--with-mpm=worker
指定worker模式。
使用event模块时,编译安装的时候加上以下参数:
--enable-nonportable-atomics=yes
需要注意的是Event MPM对于老的CPU可能是不支持的。
MPM配置解释
1 | <IfModule !mpm_netware_module> |
指定pidfile的位置。
prefork模块
1 | <IfModule mpm_prefork_module> |
StartServers:
:设置程序启动时,会创建多少个进程。MinSpareServers:
:设置最小空闲数,Apache会一直保持这个空闲的数量,不会销毁。*MaxSpareServers:
:设置最大空闲数,另外当max<min时,Apache会自动将maxMinSpareServers+1。MaxRequestWorkers:
:一个进程可以同时处理多少个请求。MaxConnectionsPerChild:
:进程处理多少个请求后将自动销毁,0意味着无限,即永不销毁。负载较高时,为使每个进程处理更多的请求,避免销毁、创建线程的开销,一般建议设定这个值为0或较大的数字。但是要注意即使负载降低后,MaxRequestsPerChild也会造成进程占用的内存无法释放,造成”负载降低,但是系统开销居高不下的局面”。
perfork创建进程的过程:perfork先创建一个进程,并在等待一秒后再创建两个进程,下一秒4个、再下一秒16个、最后32个(指数级)。并以后一直保持每秒创建32个进程的速度,直到满足MinSpareServers为止。
apache2.3.13以前的版本MaxRequestWorkers被称为MaxClients 。
MaxRequestWorkers是这些指令中最为重要的一个,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep http|wc -l来确认),那么后面的请求就要排队,直到前面的请求处理完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。幸好Apche也意识到这个问题,提供了一个ServerLimit指令来加大MaxClients。
prefork 线程优化设置
Prefork优化的关键在于MaxClients与MaxRequestsPerChild。
MaxRequestWorkers 优化
最佳的值:
1 | apache_max_process_with_good_perfermance < (total_hardware_memory / |
第一步:计算httpd平均占用内存
1 | ps aux|grep -v grep|awk '/httpd/{sum+=$6;n++};END{print sum/n}' |
显示每个进程占用了大约100M的内存,假设机器内存为32G,可拿出16G用于Apache。代入公式,得出
1 | apache_max_process_with_good_perfermance = 16 * 1024 * 1024 / |
所以MaxClients可以设置为464
MaxRequestsPerChild 优化
这个值大了影响资源的释放,小了apache不断的fork新的进程,增加CPU资源的开销。有时其影响不限于apache本身的资源,还有相关外部资源的释放。比如网站大多采用apache pool管理数据库连接,MaxRequestsPerChild过大就会造成数据库连接的资源迟迟不释放,给数据库带来不寻常的压力。
关于这一点,最典型的就是数据库出现tomieout等超时连接错误,重启Apache以后,即使访问量恢复到峰值,数据库仍然表现毫无压力,但是持续较长时间后,又出现同样的超时异常。
我采取一分钟pv/MaxRequestWorkers得到这个值。
worker模块
1 | <IfModule mpm_worker_module> |
StartServers 3
: 控制启动的时候生成的进程数。MinSpareThreads 75
: 最小空闲线程数。MaxSpareThreads 250
: 最大空闲线程数。ThreadsPerChild 25
: 每个子进程包含多少个线程数。MaxRequestWorkers 400
: 一个进程可以同时处理多少个请求。MaxConnectionsPerChild 0
: 进程处理多少个请求后将自动销毁,0意味着无限,即永不销毁。
MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。
ThreadsPerChild是worker MPM中与性能相关最密切的指令。
ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000。
上述两个值位于源码树server/mpm/worker/worker.c中的以下两行:
1 | #define DEFAULT_THREAD_LIMIT 64 |
这两行对应着ThreadsPerChild和ThreadLimit的限制数。最好在configure之前就把64改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因Apache不起动使系统很不稳定。
Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。这两个值位于源码树server/mpm/worker/worker.c中的以下两行:
1 | #define DEFAULT_SERVER_LIMIT 16 |
需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非期望值)。
1 | <IfModule worker.c>; |
通过上面的叙述,可以了解到Apache 2.0中prefork和worker这两个重要MPM的工作原理,并可根据实际情况来配置Apache相关的核心参数,以获得最大的性能和稳定性。
补充知识
httpd并发连接情况查看
查看当前的连接数
1 | #ps aux|grep httpd|wc -l |
实时检测httpd连接数
1 | #watch -n 1 -d "pgrep httpd|wc -l" |
计算httpd进程占用内在的平均数
1 | #ps aux|grep -v grep|awk '/httpd/{sum+=$6}; END{print sum/n}' |
查看Apache的并发请求数及期TCP连接状态
1 | #netstat -n | awk '/^tcp/{++S[$NF]}END{for(a in S) print a, S[a]}' |
apache 网络状态描述
CLOSED
:无连接是活动的或正在进行LISTEN
:服务器在等待进入呼叫SYN_RECV
:一个连接请求已经到达,等待确认SYN_SENT
:应用已经开始,打开一个连接ESTABLISHED
:正常数据传输状态FIN_WAIT1
:应用说它已经完成FIN_WAIT2
:另一边已同意释放ITMED_WAIT
:等待所有分组死掉CLOSING
:两边同时尝试关闭TIME_WAIT
:另一边已初始化一个释放LAST_ACK
:等待所有分组死掉
1 | <IfModule mpm_event_module> |
2:curl 查看
[root@nfs-client apache]# curl 192.168.1.106
It works!
[root@nfs-client apache]# bin/apachectl -l |egrep “_so|_rewrite|header|expire|deflate”
mod_deflate.c
mod_expires.c
mod_headers.c
mod_rewrite.c
mod_so.c
定时任务-日志轮询:
cd /application/apache/logs
mv www-access_log www-access_$(date +%F).log
/application/apache/bin/apachectl graceful
Apache 优化:
1:不对外展示目录结构
<Directory “/application/apache2.2.27/htdocs”> #自己的站点目录
Options -Indexes FollowSymLinks #indexes 不对外展示目录结构
或
<Directory “/application/apache2.2.27/htdocs”> #自己的站点目录
Options FollowSymLinks #indexes 不对外展示目录结构
扩展阅读
Apache并行处理模块介绍
Apache 2.X 支持插入式并行处理模块,称为多路处理模块(MPM)。在编译apache时必须选择也只能选择一个MPM,对类UNIX系统,有几个不同的MPM可供选择,它们会影响到apache的速度和可伸缩性。
prefork模块
Prefork MPM : 这个多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器,它的工作方式类似于Apache 1.3。它适合于没有线程安全库,需要避免线程兼容性问题的系统。它是要求将每个请求相互独立的情况下最好的MPM,这样若一个请求出现问题就不会影响到其他请求。
这个MPM具有很强的自我调节能力,只需要很少的配置指令调整。最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。
worker 模块
Worker MPM : 此多路处理模块(MPM)使网络服务器支持混合的多线程多进程。由于使用线程来处理请求,所以可以处理海量请求,而系统资源的开销小于基于进程的MPM。但是,它也使用了多进程,每个进程又有多个线程,以获得基于进程的MPM的稳定性。
每个进程可以拥有的线程数量是固定的。服务器会根据负载情况增加或减少进程数量。一个单独的控制进程(父进程)负责子进程的建立。每个子进程可以建立ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。
不管是Worker模式或是Prefork 模式,Apache总是试图保持一些备用的(spare)或者是空闲的子进程(空闲的服务线程池)用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。
Event 模块
Event MPM:以上两种稳定的MPM方式在非常繁忙的服务器应用下都有些不足。尽管HTTP的Keepalive方式能减少TCP连接数量和网络负载,但是 Keepalive需要和服务进程或者线程绑定,这就导致一个繁忙的服务器会耗光所有的线程。 Event MPM是解决这个问题的一种新模型,它把服务进程从连接中分离出来。在服务器处理速度很快,同时具有非常高的点击率时,可用的线程数量就是关键的资源限 制,此时Event MPM方式是最有效的。一个以Worker MPM方式工作的繁忙服务器能够承受每秒好几万次的访问量(例如在大型新闻服务站点的高峰时),而Event MPM可以用来处理更高负载。值得注意的是,Event MPM不能在安全HTTP(HTTPS)访问下工作。
对于Event 模式,apache给出了以下警告:
This MPM is experimental, so it may or may not work as expected .
这种MPM目前处于试验状态,他可能不能按照预期的那样工作。
mime type 类型
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
MIME参考
参考资料
Apache Prefork、Worker和Event三种MPM分析
一次Apache性能优化
apache2.4废除SSLCertificateChainFile指令
报错汇总
报错一:编译报错
1 | Centos 6.5 ./configure 报错: |
解决办法:
1 | [root@nfs-client httpd-2.2.27]# yum install zlib-devel zlib -y |
报错二:编译报错
1 | 编译报错 |
解决办法:
1 | yum install apr-devel apr-util -y |