linux云计算架构-Apache高级调优【运行模式、rewrite模块】

linux云计算架构-Apache高级调优【运行模式、rewrite模块】

1. Apache运行模式介绍

web服务器apache共有3种稳定的MPM(multi-processing module,多进程处理模块)。prefork(进程模式)worker(线程模式)event(事件模式)

在configure配置编译参数时,可以使用--with-mpm=prefork|worker|event或者--enable-mpms-shared=all配置支持MPM。

可以通过以下两种方式查看主机的apache是配置的哪种运行模式,源码安装的apache2.4.46自带的是workeryum安装的apache自带的是prefork
源码查看:
在这里插入图片描述
在这里插入图片描述
yum安装查看:
在这里插入图片描述
在这里插入图片描述

①prefork:实现了一个非线程的、多进程的、预派生的web服务器。在apache启动时,会预派生一些子进程,然后等待连接,可以减少频繁创建和销毁进程带来的开销。每个子进程只有一个线程,在某个时刻,只能处理一个请求。由于进程相对占用资源,消耗大量内存,不适用于高并发场景。将maxClients设置为一个足够大的数值以处理潜在请求高峰,但不能设置太大,导致需要使用的内存超过物理内存。在apache2.4版本以后,默认的MPM为worker。
优点:每个进程使用独立的内存空间,当某个进程坏了,不影响其他进程,较安全。
缺点:占用内存较大
在这里插入图片描述

②worker:使用了多进程多线程混合模式,当apache启动时,主进程会预派生一些子进程,每个子进程又创建一些线程,其中包括一个监听线程一个线程处理一个请求。由于线程是共享父进程的内存空间,所以比起进程更轻量。当一个线程出了问题,只会影响同一父进程下的其他线程,而不会影响到其他进程下的线程,即影响到的仅仅是部分。当使用keepalive长连接时,线程会被占用一定时间,即使中间没有请求,也需要等待到超时才会被释放。
优点:可以处理海量请求,系统资源开销小。
缺点:当一个线程故障,整个进程都会故障。存在keepalive长连接占用资源时间过长的问题。

在这里插入图片描述

当一个进程中所有线程完成一定数量的请求后,自动关闭线程,再重新打开线程。【如一个线程完成10000个请求后,线程自动关闭再重新打开。】

prefork和worker运行模式的共同点:都会提前派生子进程用来处理即将到来的请求,这样当客户端发起请求时,就不需要等待子进程的产生。

③event:该运行模式在2.4版本后稳定运行,是目前apache最新的工作模式。该工作模式相较于worker,解决了keepalive长连接占用线程资源导致资源浪费的问题。在event模式下,有一些专门的线程用来管理keepalive类型的线程,当有请求时,会将请求传递给服务器的线程,执行完毕后,当该连接没有新的请求时,会主动关闭连接
在这里插入图片描述
综上,在生产中,若要求有更高伸缩性和支持高并发,可以使用worker或event模式。若需要可靠安全或与旧软件兼容的站点,可以使用prefork。

2. prefork模式优化

# 将apache运行模式切换为prefork
[root@server ~]# vim /usr/local/apache/conf/httpd.conf 
 66 LoadModule mpm_prefork_module modules/mod_mpm_prefork.so   # 去除注释
 67 #LoadModule mpm_worker_module modules/mod_mpm_worker.so    # 加上注释
[root@server ~]# /etc/init.d/apache restart
[root@server ~]# /usr/local/apache/bin/httpd -M | grep mpm
 mpm_prefork_module (shared)

prefork模式优化:

# 启用httpd-mpm.conf配置
[root@server ~]# vim /usr/local/apache/conf/httpd.conf 
464 # Server-pool management (MPM specific)
465 Include conf/extra/httpd-mpm.conf
# mpm具体配置
[root@server ~]# vim /usr/local/apache/conf/extra/httpd-mpm.conf
 28 <IfModule mpm_prefork_module>
 29     StartServers             5  # 启动apache时创建的服务进程数
 30     MinSpareServers          5  # 最小空闲进程数
 31     MaxSpareServers         10  # 最大空闲进程数
 32     MaxRequestWorkers      250  # 最大并发进程数
 33     MaxConnectionsPerChild   0  # 最大连接限制数,0为不限制。
 34 </IfModule>

prefork调优的几点解读:
①MinSpareServers:若当前空闲子进程数(没有正在处理请求的子进程)少于MinSpareServers,apache会以每秒2的n-1次方诞生子进程,直到MinSpareServers的值大于等于5,这些空闲的子进程用来应对即将到来的请求。
②MaxSpareServers:若当前空闲的子进程数多余MaxSpareServers,apache会杀死多余的子进程,使得当前空闲子进程小于等于MaxSpareServers。
③一般MinSpareServers和MaxSpareServers的值不宜设置过大,较多的空闲子进程会占用内存资源,一般设置为最大并发的十分之一。
④MaxRequestWorkers:最大同时处理请求的进程数,也是最大同时连接数,表示最大请求并发能力,超过该值的请求,将进行排队。
⑤MaxConnectionsPerChild:在一个进程的生命周期内,处理的最大请求数,处理的请求达到这个数值后,会终止进程,当进程处理完最后的请求,进程将自动被杀死。【若开启keepalive长连接,在一次连接中即使有多个请求,也只算一次请求。】
⑥将MaxConnectionsPerChild值设置非0,可以防止内存泄露无限进行,从而耗尽内存。给进程一个有限寿命,有助于当服务器负载减轻时减少活动进程的数量。

3. worker模式优化

 44 <IfModule mpm_worker_module>
 45     StartServers             3  # 启动时apache产生的进程数
 46     MinSpareThreads         75  # 最小空闲线程数
 47     MaxSpareThreads        250  # 最大空闲线程数
 48     ThreadsPerChild         25  # 每个进程可以启动的线程数
 49     MaxRequestWorkers      400  # 所有线程数量的的最大值,通常表示可以同时处理的请求数。
 50     MaxConnectionsPerChild   0   # 最大连接数限制
 51 </IfModule>

worker调优几点解读:
①MinSpareThreads:基于整个服务器监视的最小空闲线程数,若空闲线程小于设定值,apache会自动创建线程,若服务器负载较大,可以加大该值。
②MaxSpareThreads:基于整个服务器监视的最大空闲进程数,若空闲进程大于设定值,apache会自动杀死多余的进程,若服务器负载较大,可以加大改值。
③ThreadsPerChild:每个进程包含的线程数,若并发量较大,可以加大此值。影响较大,慎重使用。
④MaxRequestWorkers:所有线程数量的最大值,一般为web服务器的最大并发值,必须是ThreadsPerChild的整数倍。【MaxRequestWorkers = StartServers * ThreadsPerChild

# event模式配置与worker模式配置一致。
# event模式解决了keepalive长连接导致空闲进程过多,占用内存资源过多的问题
 61 <IfModule mpm_event_module>
 62     StartServers             3
 63     MinSpareThreads         75
 64     MaxSpareThreads        250
 65     ThreadsPerChild         25
 66     MaxRequestWorkers      400
 67     MaxConnectionsPerChild   0
 68 </IfModule>

4. 常见worker模式配置实战:

①子进程数由StartServers的值决定
在这里插入图片描述
②查看每个apache子进程占用的内存数

# apache所有进程占用的内存数
[root@server ~]# ps aux | grep httpd | awk '{print $6}'
2936
4204
4208
4192
984

# apache子进程占用的内存数
[root@server ~]# ps aux | grep httpd | grep daemon | awk '{print $6}'
4204
4208
4192

# apache进程占用的总内存
[root@server ~]# ps aux | grep httpd | awk '{sum += $6;n++};END{print sum}'
16524

# apache子进程占用的总内存 
[root@server ~]# ps aux | grep httpd | grep daemon | awk '{sum += $6;n++};END{print sum}'
12604

# apache进程占用的平均内存
[root@server ~]# ps aux | grep httpd | awk '{sum += $6;n++};END{print sum/n}'
3304

# apache子进程占用的平均内存
[root@server ~]# ps aux | grep httpd | grep daemon | awk '{sum += $6;n++};END{print sum/n}'
4201.33

子进程使用的总内存大概12.31M。这是apache子进程占用的初始内存大小。随着服务器上线,apache进程处理的web请求的增加,每个进程使用的内存也会增加,建议上线一天后查看apache进程占用的内存数。
通过apache每个进程所需内存大小,可以计算apache需要的总内存。

③cpu核心数和内存比例配置

服务器类型 cpu核心数 内存大小 cpu核心数:内存大小
通用型服务器 8核 32G 1:4
计算型服务器 8核 16G 1:2
内存型服务器 8核 64G 1:8

了解了以上内容,下面来看两个实战:
生产场景1:一台服务器,16核心cpu,64G内存,apache最大可以设置多少个work子进程,即多少个子进程,或者说StartServers的值最大是多少?
关于内存分配,系统使用和apache使用占比如下:

内存总量 系统使用 apache使用 系统使用占比
8G 2G 6G 1/4
16G 4G 12G 1/4
32G 8G 24G 1/4
64G 8G 56G 1/8

一般来说,系统使用8G内存就足够了。
在本案例中,64G内存,可以提供给apache使用的应该是56G。为了方便计算,不妨假设当服务器上线后,每个work子进程需要使用内存56M,故最大work子进程数为:56*1024/56=1024个。即StartServers的值最大是1024。

# 修改worker mpm配置
[root@server ~]# vim /usr/local/apache/conf/extra/httpd-mpm.conf
<IfModule mpm_worker_module>
    StartServers          1024
    MinSpareThreads        750
    MaxSpareThreads       2500
    ThreadsPerChild        250
    MaxRequestWorkers      25000
    MaxConnectionsPerChild   250000
</IfModule>

==========================以下检测还是使用worker运行模式默认值=====================
==========================修改了worker运行模式的参数值,也可以使用以下方法监控=======
<IfModule mpm_worker_module>
    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0
</IfModule>

# 重启服务后,持续监控
# pgrep = ps + grep
[root@server ~]# pgrep httpd | wc -l
4
# 查看apaceh最大连接数,每1秒刷新一次
[root@server ~]# watch -n 1 "pgrep httpd | wc -l"

# ab压测
[root@server ~]# ab -n 10000 -c 100 http://192.168.8.138/index.html

# 可以看到进程数为7,子进程数由3变为了6。
# 这说明要处理10000个请求,预派生的3个子进程已经不够用了,第1秒1个子进程,第二秒1个子进程。故总共有3+1+2=6个子进程。
# 第1秒产生多一个子进程,此时为4个,每个子进程最大产生25个线程,故总共有100个线程,此时的最大并发请求应该是100。
# 而压测的并发请求就是100,故4个子进程无法稳定处理100个并发请求。
# 故需要第2秒产生多2个子进程,此时为6个子进程,总共有150个线程,才能稳定的处理100个并发请求。
[root@server extra]# ps aux | grep httpd
root       6894  0.0  0.1  76996  2964 ?        Ss   07:33   0:00 /usr/local/apache/bin/httpd -k start
daemon     8148  0.0  0.3 1547692 6100 ?        Sl   07:45   0:01 /usr/local/apache/bin/httpd -k start
daemon     8149  0.0  0.3 1744300 6096 ?        Sl   07:45   0:01 /usr/local/apache/bin/httpd -k start
daemon     8150  0.0  0.3 1678764 6128 ?        Sl   07:45   0:01 /usr/local/apache/bin/httpd -k start
daemon     9350  0.5  0.3 1678764 6132 ?        Sl   08:30   0:00 /usr/local/apache/bin/httpd -k start
daemon     9382  0.0  0.3 1547692 6060 ?        Sl   08:30   0:00 /usr/local/apache/bin/httpd -k start
daemon     9383  0.0  0.3 1613228 6072 ?        Sl   08:30   0:00 /usr/local/apache/bin/httpd -k start
root       9609  0.0  0.0 112728   988 pts/0    S+   08:32   0:00 grep --color=auto httpd
[root@server extra]# pgrep httpd | wc -l
7

生产场景2:一台服务器,8核心cpu,32G物理内存,apache要达到2000并发,worker模式的参数应该怎么配置?

# 根据内存分配,apache可以使用的内存应该24G。
# StartServers一般可以设置为CPU核心数或者2倍CPU核心数。
<IfModule mpm_worker_module>
    StartServers            16
    MinSpareThreads         75  # 假设最小并发是25,该值为最小并发的3倍。
    MaxSpareThreads       1250  # 假设最大并发为2500,该值为最大并发的一半
    ThreadsPerChild        125  # 子进程数为16,要完成2000的并发,每个子进程应该产生2000/16=125个线程。可以通过调大子进程数来增加并发值。
    MaxRequestWorkers     2000  # 所有线程数量的最大值,也称最大并发值。
    MaxConnectionsPerChild   12500 # 最大连接数限制。每个子进程处理12500个请求,平均下来每个线程处理100个请求,处理完12500个请求,该进程自动终止并关闭。这么做是为了预防线程处理太多的请求,出现内存溢出,导致进程崩溃。
</IfModule>

5. Rewrite 规则使用

rewrite的功能是为了实现URL的跳转,也称为重定向,其正则表达式是基于perl语言的。

为了使用该模块,可以在configure编译时增加参数--enable-rewrite安装该模块。也可以通过DSO模式安装动态安装。

在rewrite模块使用方面,可以基于服务器设置(httpd.conf) 也可以基于目录设置(.htaccess) 重定向的范围。

若基于服务器的设置,需要修改httpd.conf文件,在全局或者局部,或者每个virtualhost虚拟主机下,添加RewriteEngine on开启重定向rewrite功能

# 在configure编译时加入了rewrite模块,但是还是没有安装上去。需要修改配置httpd.conf
[root@server ~]# /usr/local/apache/bin/apachectl -M | grep rewrite
[root@server ~]# vim /usr/local/apache/conf/httpd.conf 
158 LoadModule rewrite_module modules/mod_rewrite.so
[root@server ~]# /etc/init.d/apache restart
[root@server ~]# /usr/local/apache/bin/apachectl -M | grep rewrite
 rewrite_module (shared)

以下介绍两个使用rewrite模块的案例:
案例1:当访问的主机名不是以www.abong.com或192.168.8.138为前缀的,都跳转到www.abong.com。

[root@server ~]# vim /usr/local/apache/conf/httpd.conf
RewriteEngine on   # 开启rewrite重定向功能
RewriteCond %{
    
    HTTP_HOST} !^www.abong.com [NC]  # 访问的主机不是以www.abong.com前缀的
RewriteCond %{
    
    HTTP_HOST} !^192.168.8.138 [NC]  # 访问的主机不是以192.168.8.138前缀的
RewriteCond %{
    
    HTTP_HOST} !^$ # 访问的主机不是空地址
RewriteRule ^/(.*) http://www.abong.com/ [L]   # 满足以上RewriteCond条件的请求,都直接跳转到http://www.abong.com/
[root@server ~]# /etc/init.d/apache graceful   # 重新加载apache配置文件,不停服务。
[root@server ~]# vim /etc/hosts    # 配置本地域名解析
192.168.8.138 www.abong.com
192.168.8.138 bbs.abong.com
192.168.8.138 www.abong.cn
192.168.8.138 bbs.abong.cn

打开本地浏览器进行测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过以上测试结果,可以看到192.168.8.138虽然对应了4个域名,但访问不是www.abong.com的域名,都会被重定向到www.abong.com

案例2:当访问www.abong.com时,自动跳转到www.jd.com

[root@server ~]# vim /usr/local/apache/conf/httpd.conf
RewriteEngine on
RewriteCond %{
    
    HTTP_HOST} ^www.abong.com [NC]
RewriteRule ^/(.*) http://www.jd.com/ [L]
[root@server ~]# /etc/init.d/apache graceful
[root@server ~]# vim /etc/hosts
192.168.8.138 www.abong.com
192.168.8.138 www.jd.com

在这里插入图片描述
经过以上两个案例,可以看出,rewrite模块的主要功能是实现URL的跳转。
想要了解更多apache rewrite模块的内容,可以查看官网信息。
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

6. apache防盗链配置

apache防盗链设置,实际上即是使用rewrite模块,当请求主机名不是限定的部分时,会跳转到指定内容。

RewriteEngine on
RewriteCond %{
    
    HTTP_REFERER} !^http://www.abong.com/data$
RewriteCond %{
    
    HTTP_REFERER} !^http://www.abong.com/data/.*$
RewriteCond %{
    
    HTTP_REFERER} !^http://www.abong.com/data2$
RewriteCond %{
    
    HTTP_REFERER} !^http://www.abong.com/data2/.*$
RewriteRule .*\.(gif|jpg|swf|png)$ http://www.abong.com/

从以上配置可以看出,当请求的地址是以.gif .jpg .swf .png结尾的,都会跳转到http://www.abong.com/,这样别人就无法引用自身服务器上的图片了,就不会被盗了。
在本文中的rewrite模块的使用,仅仅是介绍基本的使用,在生产环境中,需要根据实际需求进行配置。

7. 禁止解析某个目录下的php文件

# 禁止访问网站数据目录下的data目录下的php文件
[root@server ~]# vim /usr/local/apache/conf/httpd.conf 
# DocumentRoot "/usr/local/apache/htdocs"
# <Directory "/usr/local/apache/htdocs">
# ...
# </Directory>

<Directory "/usr/local/apache/htdocs/data/">
<Files ~ ".php">
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all denied
</Files>
</Directory>

apache调优总结:有关于apache调优的内容,记录了两篇博客。在实际生产环境中,可以根据其中介绍的各点排查服务器中的apache运行情况。生产环境的情况比测试环境复杂很多,需要根据实际需求,结合这两篇博客以及官方介绍进行配置。

猜你喜欢

转载自blog.csdn.net/weixin_36522099/article/details/109712703