Apache调优(二)
(1).Apache运行模式说明
Apache目前一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块)模式:Prefork(进程模式)、Worker(线程模式)、Event(事件模式,2.4版本后开始稳定)。
1)Prefork
Prefork模式实现了一个非线程的、预派生的Web服务器。它在Apache启动之初,就先预派生一些子进程,然后等待连接;可以减少频繁创建和销毁进程的开销,每个子进程只有一个线程,在一个时间点内,一个线程只能处理一个请求。这是一个成熟稳定,可以兼容新老模块,也不需要担心线程安全问题,但是一个进程相对占用资源,消耗大量内存,不擅长处理高并发的场景。
最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。所以现在已经不常用这个模式了。 而且Apache2.4版本以后,默认使用的是worker模式。
优点:可以兼容新老模块;每个进程使用单独的内存空间,较安全,一个进程坏了不会影响其他进程。
缺点:占用较大内存,不擅长处理高并发。
运行原理图如下:
2)Worker
Worker模式和Prefork模式相比,Worker模式使用了多进程和多线程的混合模式,Worker模式也同样会先预派生一些子进程,然后每个子进程创建一些线程,同时包括一个监听线程,每个请求会被分配到一个线程来服务。线程比起进程会更轻量,因为线程是通过共享父进程的内存空间,因此,内存的占用会减少一些,在高并发的场景下会比prefork有更多可用的线程,表现会更优秀一些;另外,如果一个线程出现了问题也会导致同一进程下的线程出现问题,如果是多个线程出现问题,也只是影响Apache的一部分,而不是全部。由于用到多进程多线程,需要考虑到线程的安全了,在使用keep-alive长连接的时候,某个线程会一直被占用,即使中间没有请求,需要等待到超时才会被释放(该问题在prefork模式下也存在)。
优点:可以处理海量请求,而系统资源的开销小。
缺点:不太安全。如果一个线程坏了。 整个进程都要坏了。另外存在keep-alive长连接占用资源时间过长。
运行原理图如下:
不管是Worker模式或是Prefork 模式,Apache总是试图保持一些备用的(spare)或者是空闲的子进程(空闲的服务线程池)用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。这就是预先派生进程或线程。
3)Event
Event模式是在2.4版本中才可以稳定运行。这是Apache最新的工作模式,它和worker模式很像,不同的是在于它解决了keep-alive长连接的时候占用线程资源被浪费的问题,在event工作模式中,会有一些专门的线程用来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务器的线程,执行完毕后,又允许它释放。这增强了在高并发场景下的请求处理。
当某个连接没有请求时,会主动关闭连接,在work模式下,必须等keep-alive超时,才可以释放。
运行原理图如下:
4)总结
在configure配置编译参数的时候,可以使用 --with-mpm=prefork|worker|event 来指定编译为那一种MPM。也可以编译为三种都支持:--enable-mpms-shared=all,这样在编译的时候会在modules目录下自动编译出三个MPM文件的so,然后通过修改httpd.conf配置文件更改MPM(LoadModule mpm_event_module modules/mod_mpm_event.so;LoadModule mpm_prefork_module modules/mod_mpm_prefork.so;LoadModule mpm_worker_module modules/mod_mpm_worker.so启用这三个中的一个,注释其他两个)。
5)查看Apache当前运行模式
方法一:使用httpd -l来确定当前使用的MPM
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -l Compiled in modules: core.c mod_so.c http_core.c event.c //当前运行模式
方法二:使用httpd -V查看当前使用的MPM
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: IIS/7.0.0 (Unix) Server built: Aug 8 2019 17:04:07 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event //当前运行模式 threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
6)切换Apache的运行模式
如果是yum安装的httpd,想要切换运行模式,这个网上有很多了,可以查看Apache工作模式切换。
我这里重点介绍源码安装的Apache切换运行模式。
首先使用命令查看安装的MPM模块,static表示是编译安装时一起安装的,shared则是DSO方式安装的。并查看编译设置
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/apachectl -M | grep mpm mpm_event_module (static) [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: IIS/7.0.0 (Unix) Server built: Aug 8 2019 17:04:07 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
接着重现编译生成httpd二进制文件
[root@youxi1 httpd-2.4.39]# cd /usr/local/src/httpd-2.4.39/ //再原有的./configure配置上重新执行预编译,以及make。我这里改为worker作为演示 [root@youxi1 httpd-2.4.39]# ./configure --prefix=/usr/local/apache2.4.39 --enable-so --enable-rewrite --enable-ssl --enable-deflate --enable-expires --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-mpm=worker [root@youxi1 httpd-2.4.39]# make [root@youxi1 httpd-2.4.39]# mv /usr/local/apache2.4.39/bin/httpd{,.bak} //备份已有的httpd [root@youxi1 httpd-2.4.39]# cp httpd /usr/local/apache2.4.39/bin/ //拷贝新生成的httpd [root@youxi1 bin]# /etc/init.d/httpd graceful //重新加载,也可以restart [root@youxi1 httpd-2.4.39]# /usr/local/apache2.4.39/bin/httpd -V Server version: IIS/7.0.0 (Unix) Server built: Aug 8 2019 17:13:33 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.4.8, APR-UTIL 1.5.2 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: worker threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
切换我已经自己试过了,但不知道会不会有其他漏洞。注意:这只是指定单个mpm时,这样使用。如果实在编译时使用--enable-mpms-shared=all安装所有运行模式,这个需要到Apache主目录下的conf/目录下修改httpd.conf,找到里面的LoadModule中的相应模块(LoadModule mpm_event_module modules/mod_mpm_event.so;LoadModule mpm_prefork_module modules/mod_mpm_prefork.so;LoadModule mpm_worker_module modules/mod_mpm_worker.so启用这三个中的一个,注释其他两个)。
(2).Apache运行模式调优
1)prefork(Apache2.4以后已经很少用到,简单了解)
查看是否启用MPM的配置文件
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf Include conf/extra/httpd-mpm.conf //启用mpm的配置文件 //如果是使用--enable-mpms-shared=all安装了所有运行模式,确保prefork模式是启用状态,worker和event是注释状态 #LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule mpm_prefork_module modules/mod_mpm_prefork.so #LoadModule mpm_worker_module modules/mod_mpm_worker.so
查看prefork的配置参数,根据需求修改
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/extra/httpd-mpm.conf <IfModule mpm_prefork_module> StartServers 5 //启动Apache时创建的服务进程数量(子进程) MinSpareServers 5 //最小空闲进程数 MaxSpareServers 10 //最大空闲进程数 MaxRequestWorkers 250 //最大并发数,这里指进程的总数 MaxConnectionsPerChild 0 //最大连接数量 </IfModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加载 [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: Apache/2.4.39 (Unix) Server built: Aug 9 2019 09:20:58 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: prefork //当前运行状态 threaded: no forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" [root@youxi1 ~]# ps aux | grep httpd root 34123 0.0 0.2 72808 2624 ? Ss 09:58 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34133 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34134 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34135 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34136 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34137 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd root 34158 0.0 0.0 112724 988 pts/0 R+ 10:09 0:00 grep --color=auto httpd
配置参数详细说明:
MinSpareServers参数设置空闲子进程的最小数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以第一秒一个,第二秒两个,第三秒四个,按指数递增个数的速度产生新的子进程。如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止;这就是预派生(prefork)的由来;这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。
MaxSpareServers参数设置空闲子进程的最大数量。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。
可以调整MinSpareServers 和MaxSpareServers这两个参数,但是这两个参数的值不能设得太大,否则Apache进程太多,会导致内存占用太多。例如:在一台压力大(并发访问2000)的服务器上,MaxSpareServers这个值设置的是200。保留最大并发数的10分之一。设置了这个值的好处是不会有太多的空闲的进程在消耗资源,关闭空闲Apache进程的同时,会释放内存,进而减少系统资源消耗。
MaxRequestWorkers参数设置最大同时处理请求的进程数量,也是最大的同时连接数,表示了Apache的最大请求并发能力,超过该数目后的请求,将排队。
MaxConnectionsPerChild参数设置进程生命周期内,处理的最大请求数目。达到该数目后,进程将死掉。如果设置为0,表示没有限制。该参数的意义在于,避免了可能存在的内存泄露带来的系统问题。将MaxRequestsPerChild设置成非零值有两个好处:可以防止(偶然的)内存泄漏无限进行,从而耗尽内存;给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。注:当KeepAlive为On, 即开启长链接时,发送的请求在MaxRequestsPerChild里面只算一个,不管这个连接发送了多少个请求。
2)worker
查看是否启用MPM的配置文件
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf Include conf/extra/httpd-mpm.conf //启用MPM的配置文件 //如果是使用--enable-mpms-shared=all安装了所有运行模式,确保worker模式是启用状态,prefork和event是注释状态 #LoadModule mpm_event_module modules/mod_mpm_event.so #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so LoadModule mpm_worker_module modules/mod_mpm_worker.so
查看worker的配置参数,根据需求修改
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/extra/httpd-mpm.conf <IfModule mpm_worker_module> StartServers 3 //启动时子进程数 MinSpareThreads 75 //最小空闲线程数 MaxSpareThreads 250 //最大空闲线程数 ThreadsPerChild 25 //每个进程可以启动的线程数 MaxRequestWorkers 400 //最大并发数,这里指线程的总数 MaxConnectionsPerChild 0 //最大连接数 </IfModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加载,有时候可能会关闭需要重新启动httpd [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: Apache/2.4.39 (Unix) Server built: Aug 9 2019 09:20:58 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: worker //当前运行状态 threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" [root@youxi1 ~]# ps aux | grep httpd root 37283 0.0 0.2 73064 2392 ? Ss 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart daemon 37284 0.0 0.4 362028 4200 ? Sl 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart daemon 37285 0.0 0.4 362028 4200 ? Sl 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart daemon 37286 0.0 0.4 362028 4200 ? Sl 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart root 37369 0.0 0.0 112724 988 pts/0 R+ 11:19 0:00 grep --color=auto httpd
配置参数详细说明:
StartServers参数设置启动时进程数。一般设同cpu核心数一样或是cpu核心数的2倍。
MinSpareThreads参数设置基于整个服务器监视的最小空闲线程数,如果空闲的线程小于设定值,Apache会自动建立线程。假设一个网站每天正常被用户使用的时间为早上7:00到晚上2:00。那么MinSpareThreads应该配置为,这一时间段内最小并发访问量的3倍。比如7:00最少并发为25,那就配置成75。
MaxSpareThreads参数设置基于整个服务器监视的最大空闲线程数,如果空闲的线程大于设定值,Apache会自动kill掉多余的线程。一般配置为一天中最大并发量的一半。如这台服务器能处理的最大并量为2500。那么此值应该为1250。因为内存闲着也是闲着,可以按linux下尽可能使用内存的原则,配置成1250.这样在突然到来更多访问量时,响应会更及时。
ThreadsPerChild参数设置每个子进程包含的线程数,如果是并发量比较大,可以考虑加大这个值。此参数在worker模式中,是影响最大的参数。生产环境中,在带宽和硬盘性能充足的情况下,希望这个这台可以完成2000左右的并发。那么此值应该为:2000/ StartServers的值(我这里是16)=125 。但是一个进程不可能包括无数的线程,包括太多,会导致进程不稳定,容易崩溃。所以我们认为一个进程最多包括125线程就很好了。所以如果还想处理更多的请求,可以把StartServers的值增加,而不是增大ThreadsPerChild的值。 因为ThreadsPerChild值过大,会导致Apache运行不稳定。系统调优,稳定是一切的前提。
MaxRequestWorkers参数设置所有线程数量的最大值,通常表示了一个web服务的最大并发值。MaxRequestWorkers必须是ThreadsPerChild的整数倍,否则Apache会提示调整到一个相近的值。一般设置时为MaxRequestWorkers=StartServers* ThreadsPerChild。
MaxConnectionsPerChild参数设置每个子进程可以处理的最大请求数。达到该数目后,进程将死掉。如果设置为0,表示没有限制。MaxConnectionsPerChild/ThreadsPerChild的值作为一个判断标准。一个线程处理太多的请求,也会出现内存溢出,导致进程崩溃。
A.一台服务器最大可以设置多少个子进程?
首选进行压测,计算子进程的平均使用内存大小。
其次服务器可以使用的内存大小(只考虑分布式)。一般来说,一台8G内存服务器,留2G内存给系统使用;一台16G内存服务器,留4G内存给系统使用;一台32G内存服务器,留8G给系统使用;一台64G内存服务器,留8G内存给系统使用。(最多8G就足够了)
最后,(总内存-系统内存)/子进程的平均内存=最大可以设置的子进程。
B.扩展:选择服务器时,CPU与内存的搭配比例
通用型服务器选择标准:CPU与内存比例1:4;计算型服务器选择标准:CPU与内存比例1:2;内存型服务器选择标准:CPU与内存比例1:8。
3)event
查看是否启用MPM的配置文件
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf Include conf/extra/httpd-mpm.conf //启用MPM的配置文件 //如果是使用--enable-mpms-shared=all安装了所有运行模式,确保event模式是启用状态,prefork和worker是注释状态 LoadModule mpm_event_module modules/mod_mpm_event.so #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so #LoadModule mpm_worker_module modules/mod_mpm_worker.so
查看worker的配置参数,根据需求修改
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/extra/httpd-mpm.conf <IfModule mpm_event_module> StartServers 3 //启动时子进程数 MinSpareThreads 75 //最小空闲线程数 MaxSpareThreads 250 //最大空闲线程数 ThreadsPerChild 25 //每个进程可以启动的线程数 MaxRequestWorkers 400 //最大并发数,这里指线程的总数 MaxConnectionsPerChild 0 //最大连接数 </IfModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加载,有时候可能会关闭,需要重新启动htpd [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: Apache/2.4.39 (Unix) Server built: Aug 9 2019 09:20:58 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event //当前运行状态 threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" [root@youxi1 ~]# ps aux | grep httpd root 39648 0.0 0.2 73080 2400 ? Ss 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful daemon 39649 0.0 0.4 362044 4212 ? Sl 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful daemon 39650 0.0 0.4 362044 4212 ? Sl 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful daemon 39651 0.0 0.4 362044 4212 ? Sl 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful root 39734 0.0 0.0 112724 992 pts/0 R+ 14:55 0:00 grep --color=auto httpd
event模式调优和worker模式一样的,不同的是在于它解决了keep-alive长连接的时候占用线程资源被浪费的问题。所以理伦上event模式比worker模式好。
4)总结
生产环境下对于要求更高伸缩性的站点可以选择使用worker 或 event模式; 需要可靠性或者与旧软件兼容的站点可以使用 prefork模式。现在网站使用worker模式比较多。worker也比较成熟。event模式从Apache2.4版本才开始有。
(3).Rewirte规则使用
Rewirte主要的功能就是实现URL的跳转,它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的 (.htaccess)两种方式。如果要想用到rewrite模块,必须先安装或加载rewrite模块。而基于服务器级的方式又分为全局和局部,都是利用RewriteEngine on来打开rewrite功能,配合一些其他的rewrite参数具体设置。
使用命令查看是否安装了rewrite模块,如果返回rewrite_module(static)则是编译安装时一起安装的,如果返回rewrite_module(shared)则是DSO方式安装的(编译时使用--enable-rewrite也是这个,估计我的判断标准有问题)。
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/apachectl -M | grep rewrite [root@youxi1 ~]# ls /usr/local/apache2.4.39/modules/mod_rewrite.so /usr/local/apache2.4.39/modules/mod_rewrite.so //说明存在,但没有启用
安装Rewirte模块两种方式:1.编译Apache时使用了--enable-rewrite;2.在安装完成后使用Apache主目录下的bin/apxs扩展工具编译并增加。
1)rewrite规则重写的标志参数说明(最后的中括号内的参数)
R[=code](force redirect) 强制外部重定向。强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定,将用缺省的302 HTTP状态码。
F(force URL to be forbidden)禁用URL,返回403HTTP状态码。
G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。
P(force proxy) 强制使用代理转发。
L(last rule) 表明当前规则是最后一条规则,停止分析以后规则的重写。
N(next round) 重新从第一条规则开始运行重写过程。
C(chained with next rule) 与下一条规则关联。如果规则匹配则正常处理,该标志无效,如果不匹配,那么下面所有关联的规则都跳过。
T=MIME-type(force MIME type) 强制MIME类型。
NS (used only if no internal sub-request) 只用于不是内部子请求。
NC(no case) 不区分大小写
QSA(query string append) 追加请求字符串。
NE(no URI escaping of output) 不在输出转义特殊字符。例如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 将能正确的将/foo/zoo转换成/bar?arg=P1=zed
PT(pass through to next handler) 传递给下一个处理。
S=num(skip next rule(s)) 跳过num条规则。
E=VAR:VAL(set environment variable) 设置环境变量。
2)使用apxs扩展工具安装rewrite模块
[root@youxi1 ~]# ls /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.* /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.c /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.dep /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.dsp /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.exp /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.h /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.la /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.lo /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.mak /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.o /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.slo [root@youxi1 ~]# /usr/local/apache2.4.39/bin/apxs -cia /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.c [root@youxi1 ~]# echo $? 0 [root@youxi1 ~]# ls /usr/local/apache2.4.39/modules/mod_rewrite.so /usr/local/apache2.4.39/modules/mod_rewrite.so [root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf LoadModule rewrite_module modules/mod_rewrite.so //确保启用 [root@youxi1 ~]# /usr/local/apache2.4.39/bin/apachectl -M | grep rewrite rewrite_module (shared) //这个就是已经安装成功了
3)重写实例
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf LoadModule rewrite_module modules/mod_rewrite.so //启用rewrite模块 //也可以使用<IfModule rewrite_module></IfModule>将以下内容包裹 RewriteEngine on //打开rewrite重写功能 RewriteCond %{HTTP_HOST} !^www.youxi1.com [NC] RewriteCond %{HTTP_HOST} !^192.168.1.6 [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*) http://www.youxi1.com/$1 [L] [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加载
配置说明:
RewriteCond %{HTTP_HOST} !^www.you.com [NC]表示当客户端请求的主机前缀不是www.you.com时,[NC]表示忽略大小写
RewriteCond %{HTTP_HOST} !^192.168.1.6 [NC]表示当客户端请求的主机前缀不是192.168.1.6时,[NC]表示忽略大小写
RewriteCond %{HTTP_HOST} !^$表示当客户端请求的主机不为空时。
RewriteRule ^/(.*) http://www.you.com/$1 [L]表示如果客户端请求的主机中的前缀符合上述条件(这里匹配的条件是)则直接进行跳转到http://www.you.com,[L]表示立即停止重写操作并不再应用其他重写规则。这里的.表示换行符意外的所有字符,*表示匹配0次或更多次,合起来的.*就是匹配换行符以外的所有字符。小括号()的功能是把内部的所有字符做一个标记,以便后面引用。这里的$1就是调用(.*)。
官方文档地址:http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond
做一个测试界面
[root@youxi1 ~]# echo www.youxi1.com > /usr/local/apache2.4.39/htdocs/test.html
然后Windows下修改hosts文件,添加如下两行
192.168.1.6 bbs.xi1.cn 192.168.1.6 www.youxi1.com
之后使用浏览器查看
----------->
----------->
4)防盗链
一些小网站为了盈利,通过盗链来实现对自己网站内容的丰富,这无疑加大了企业的空间和流量的成本,因此我们需要对Apache进行防盗链的配置。
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf <IfModule rewrite_module> RewriteEngine on RewriteCond %{HTTP_REFERER} !^http://sunsky.pw/.*$ [NC] RewriteCond %{HTTP_REFERER} !^http://sunsky.pw$ [NC] RewriteCond %{HTTP_REFERER} !^http://www.sunsky.pw/.*$ [NC] RewriteCond %{HTTP_REFERER} !^http://www.sunsky.pw$ [NC] RewriteRule .*\.(gif|jpg|swf)$ http://www.sunsky.pw [R,NC] </IFModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加载
HTTP_REFERER是header的一部分,当浏览器向Web服务器发送请求时,会带上Referer来告诉服务器该网页从哪个链接过来的。
(4).禁止浏览目录
由于开启目录浏览会让我们整个目录下的内容全部都暴露到外面,因此我们必须要禁止目录浏览功能。当然一些目录开放给客户做下载的,可以忽略此项优化。
做一个测试环境
[root@youxi1 ~]# mkdir /usr/local/apache2.4.39/htdocs/testdir [root@youxi1 ~]# touch /usr/local/apache2.4.39/htdocs/testdir/file{1,2,3}
修改配置文件禁止访问目录
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf <Directory "/usr/local/apache2.4.39/htdocs"> ... Options FollowSymLinks //修改,原本是Options Indexes FollowSymLinks ... </Directory>
[root@youxi1 ~]# /etc/init.d/httpd graceful //重新加载
再次查看
(5).禁止php文件被解析
企业的站点有时会提供用户进行上传操作,比如让用户上传一个文件或头像图片,而用户上传文件的存放目录,我们是不能给php的解析权限的,否则会对Apache服务和系统造成危害。
设置主目录下的htdocs/data目录里的php结尾的文件不运行。
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf //加到已有的<Directory></Directory>标签对下面 <Directory "/usr/local/apache2.4.39/htdocs/data" > <Files ~ ".php"> //以.php结尾的文件 Order allow,deny Deny from all </Files> </Directory> [root@youxi1 ~]# /etc/init.d/httpd restart
然后创建测试页面
[root@youxi1 ~]# mkdir /usr/local/apache2.4.39/htdocs/data [root@youxi1 ~]# vim /usr/local/apache2.4.39/htdocs/data/index.php <?php phpinfo(); ?>
然后使用浏览器访问
(6).使用CDN做网络加速
简单地说,就是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的缓存服务器内。通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,杭州的用户访问接近杭州服务器上的内容,北京访问接近北京服务器上的内容。这样可以有效减少数据在网络上传输的事件,提高速度。把静态内容发布到CDN减少了用户的响应时间20%或更多。
国内有名的CND公司:网宿,蓝汛(chinacache),快网
(7).Apache网站架构优化
好的网站架构是网站性能强大关键,更是网站安全的关键。在生产环境中建议将程序页面服务器、图片附件服务器和上传服务器三者的功能尽量分离。
分离方法:1、分离最佳方式是分别使用独立的服务器(需要程序支持);2、次选方案在前端负载均衡器通过haproxy/nginx来根据用户请求的目录或扩展名来对后端的服务器发出请求。
例如:请求http://www.xxxxxx.cn/a/b.jpg就抛给图片服务器(CDN最好),这里是根据扩展名.jpg分发
请求http:// /www.xxxxxx.cn /upload/login.php就抛给Apache服务器,这里是根据URL路径分发。
均不符合上面两个要求的,默认就都是抛给主web服务器。