请你告诉我Apache怎么就比Nginx慢了?

1. 常见 http 服务器程序

  • httpd apache,存在C10K(10K connections)问题

  • nginx 解决C10K问题(官方:3-5w并发)

  • lighttpd

  • IIS .asp 应用程序服务器

  • tomcat .jsp 应用程序服务器

  • jetty 开源的servlet容器,基于Java的web容器

  • Resin CAUCHO公司,支持servlets和jsp的引擎

  • webshpere:IBM公司

  • weblogic:BEA,Oracle

  • jboss:RedHat,IBM

  • oc4j:Oracle

HTTP服务器市场占有率统计: http://www.netcraft.com

2. apache介绍和特点

2.1 apache 介绍

apache官网: www.apache.org

软件基金会

  • ASF:apache software foundation

  • FSF:Free Software Foundation

apache 功能

  • 提供http协议服务

  • 多个虚拟主机:IP、Port、FQDN

  • CGI:Common Gateway Interface,通用网关接口,支持动态程序

  • 反向代理

  • 负载均衡

  • 路径别名

  • 丰富的用户认证机制:basic,digest

  • 支持第三方模块

httpd2.4新特性

  • MPM支持运行为DSO机制;以模块形式按需加载(支持在运行时加载),需要启用以下两项
--enable-mpms-shared=all 
--with-mpm=event        # 启用默认的event
  • event MPM生产环境可用

  • 异步读写机制

  • 支持每模块及每目录的单独日志级别定义

  • 每请求相关的专用配置:

  • 增强版的表达式分析式

  • 毫秒级持久连接时长定义(keepalive timeout)

  • 基于主机名(FQDN)的虚拟主机不再需要NameVirtualHost指令

  • 支持用户自定义变量

  • 新增一些模块:mod_proxy_fcgi,mod_ratelimit,mod_request,mod_remoteip

  • 对于基于IP的访问控制做了修改,不再使用order,allow,deny这些机制;而是统一使用require进行

  • 更低的内存消耗

apache特性:

  • 高度模块化:core + modules

  • DSO:Dynamic Shared Object 动态加载/卸载

  • MPM:multi-processing module 多路处理模块

httpd 官方链接: http://httpd.apache.org/

2.2 MPM multi-processing module 工作模式

  • prefork:多进程I/O模型,每个进程响应一个请求,CentOS 7 httpd默认模型

  • 一个主进程:生成和回收n个子进程,创建套接字,不响应请求

  • 多个子进程:工作 work进程,每个子进程处理一个请求;系统初始时,预先生成多个空闲进程,等待请求

Prefork MPM预派生模式,有一个主控制进程,然后生成多个子进程,每个子进程有一个独立的线程响应用户请求,相对比较占用内存,但是比较稳定,可以设置最大和最小进程数,是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景

优点:稳定

缺点:慢,占用资源,不适用于高并发场景

worker:复用的多进程I/O模型,多进程多线程,IIS使用此模型

  • 一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应
    请求:m*n

worker MPM是一种多进程和多线程混合的模型,有一个控制进程,启动多个子进程,每个子进程里面包含固定的线程,使用线程程来处理请求,当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,由于其使用了线程处理请求,因此可以承受更高的并发。

优点:相比prefork占用的内存较少,可以同时处理更多的请求

缺点:使用keep-alive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到
超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问
题在prefork模式下,同样会发生)

event:事件驱动模型(worker模型的变种),CentOS8 默认模型

监听进程用于向工作进程分配任务并和客户端保持会话连接,超时之后监听线程会删除该socket,工作线程只处理用户请求,处理完之后将会话保持交于监听线程,自己去处理新的请求,不再负责新的请求,不再负责会话保持

一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n,有专门的监控线程来管理这些keep-alive类型的线程,当有真实请求时,将请求传递给服务线程,执行完毕后,又允许释放。这样增强了高并发场景下的请求处理能力

event MPM是Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型. 属于事件驱动模型(epoll),每个进程响应多个请求,在现在版本里的已经是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。event MPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力

event只在有数据发送的时候才开始建立连接,连接请求才会触发工作线程,即使用了TCP的一个选项,叫做延迟接受连接TCP_DEFER_ACCEPT,加了这个选项后,若客户端只进行TCP连接,不发送请求,则不会触发Accept操作,也就不会触发工作线程去干活,进行了简单的防攻击(TCP连接)

优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放

缺点:没有线程安全控制

httpd-2.4:event 稳定版,centos7 以后默认

httpd-2.2:event 测试版,centos6 默认

2.3 传统服务与Nginx服务请求切换的区别

总结:

Apache

  • 一个连接对应一个进程(在apache的架构模型里一个进程同一时间只会处理一个连接,一个请求,只有在这个请求处理完之后才会去处理下一个请求)

Nginx

  • Nginx 基于 IO 多路复用,IO 复用解决的是并发性问题,Socket 作为复用

    • 多个描述符的I/O操作都能在一个线程内并发交替地顺序完成,这就叫IO多路复用,这里的“复用”指的是复用同一个线程

    • I/O多路复用的实现方式有select、poll、Epool

  • cpu亲和(affinity)

    • 将 cpu 核心和 Nginx 工作进程绑定方式,把每个 worker 进程固定在一个 cpu 上执行,将减少 cpu 的 cache miss,获得更好的性能
  • sendfile

    • sendfile 的目的就是提高本地文件通过 socket 发送的效率,也叫做零拷贝,sendfile 的主要出发点,就是要减少数据的 copy 以提高发送效率,sendfile 是 linux 系统级的调用,socket 可以通过DMA(直接内存访问)方式直接访问文件数据,并通过传输协议发送,减少了 2 次数据copy(磁盘到内核,内核到工作区)

3 Httpd 安装和相关文件

3.1 包安装httpd并启动httpd服务

版本说明:

CentOS 7 以上,默认系统是httpd 2.4,CentOS 6 版默认为httpd 2.2

Ubuntu 18.04 默认 Apache/2.4.29

安装方式:

  • 包安装: centos发行版,稳定,建议使用

  • 编译:定制或特殊需求

示例:安装httpd 2.4

[root@centos8 ~]#dnf -y install httpd
[root@centos8 ~]#httpd -v
[root@centos8 ~]#systemctl enable --now httpd
[root@centos8 ~]#ss -ntl|grep :80

示例:ubuntu 安装 httpd 2.4

[root@ubuntu1804 ~]#apt install apache2 -y
[root@ubuntu1804 ~]#apache2 -v
[root@ubuntu1804 ~]#systemctl status apache2

示例:yum安装

[root@centos8 ~]#hostname -I
[root@centos8 ~]#hostnamectl set-hostname  web01.test.com
[root@centos8 ~]#yum -y install httpd;hostname > /var/www/html/index.html;systemctl enable --now httpd

3.2 httpd-2.4 相关文件

配置文件:

  • /etc/httpd/conf/httpd.conf 主配置文件

  • /etc/httpd/conf.d/*.conf 子配置文件

  • /etc/httpd/conf.d/conf.modules.d/ 模块加载的配置文件

检查配置语法:httpd -t 或 apache2 -t

服务单元文件:

  • /usr/lib/systemd/system/httpd.service
  • 配置文件:/etc/sysconfig/httpd

服务控制和启动

systemctl enable|disable httpd.service

systemctl {start|stop|restart|status|reload} httpd.service

apachectl start|stop|restart|configtest

service httpd start|stop|restart|configtest

站点网页文档根目录:/var/www/html

模块文件路径:

  • /etc/httpd/modules

  • /usr/lib64/httpd/modules

主服务器程序文件:/usr/sbin/httpd

主进程文件: /etc/httpd/run/httpd.pid

日志文件目录:/var/log/httpd

  • access_log: 访问日志
  • error_log:错误日志

帮助文档包:httpd-manual

http://apache-server/manual/

3.3 httpd 配置文件的组成

主要组成

Global Environment
Main server configuration
virtual host

配置文件格式

directive value

格式说明:

  • directive 不区分字符大小写

  • value 为路径时,是否区分大小写,取决于文件系统

配置文件语法检查:

apachectl configtest
apachectl -t
httpd -t

配置官方帮助: ttp://httpd.apache.org/docs/2.4/

4 编译安装前说明和准备

APR:Apache portable Run-time libraries,Apache可移植运行库,主要为上层的应用程序提供一个可以跨越多操作系统平台使用的底层支持接口库。在早期的Apache版本中,应用程序本身必须能够处理各种具体操作系统平台的细节,并针对不同的平台调用不同的处理函数随着Apache的进一步开发,Apache组织决定将这些通用的函数独立出来并发展成为一个新的项目。

这样,APR的开发就从Apache中独立出来,Apache仅仅是使用 APR而已。目前APR主要还是由Apache使用,由于APR的较好的移植性,因此一些需要进行移植的C程序也开始使用APR,开源项目:比如用于服务器压力测试的Flood
loader tester,项目站点:http://httpd.apache.org/test/flood

APR官网:http://apr.apache.org

说明:安装httpd-2.4,依赖于apr-1.4+, apr-util-1.4+

4.1 编译安装httpd-2.4准备
# Ubuntu 安装相关包
apt -y install build-essential libpcre3 libpcre3-dev openssl libssl-dev libapr1-dev libexpat1-dev libaprutil1-dev wget gcc make 


# Centos 安装相关包
[root@centos7 ~]#yum -y install wget gcc make pcre-devel openssl-devel expat-devel

# 下载源代码并解压缩:
[root@centos7 ~]#wget https://downloads.apache.org/apr/apr-1.7.0.tar.bz2 -P /usr/local/src/
[root@centos7 ~]#wget https://downloads.apache.org//apr/apr-util-1.6.1.tar.bz2 -P /usr/local/src/
[root@centos7 ~]#wget https://downloads.apache.org//httpd/httpd-2.4.46.tar.bz2 -P /usr/local/src/
[root@centos7 ~]#ls
httpd-2.4.46.tar.bz2,apr-1.7.0.tar.bz2,apr-util-1.6.1.tar.bz2
[root@centos7 ~]#tar xvf apr-1.7.0.tar.bz2
[root@centos7 ~]#tar xvf apr-util-1.6.1.tar.bz2
[root@centos7 ~]#tar xvf httpd-2.4.46.tar.bz2
4.2 编译安装httpd-2.4 方法一

(1)编译安装apr

cd apr-1.7.0
./configure --prefix=/apps/apr
make -j`lscpu | grep "^CPU(s)" | awk '{print $NF}'` && make install

(2)编译安装apr-util

apr-util是apr的工具库,其可以让程序员更好的使用apr的功能

cd ./apr-util-1.6.1
./configure --prefix=/apps/apr-util --with-apr=/apps/apr/
make -j`lscpu | grep "^CPU(s)" | awk '{print $NF}'` && make install

(3)编译安装 httpd-2.4

httpd目前最新的2.4系列版本中引入了event MPM,其在性能上较之其它MPM有了较大的提升

cd httpd-2.4.46
./configure \
--prefix=/apps/httpd24 \
--sysconfdir=/etc/httpd24 \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-apr=/apps/apr/ \
--with-apr-util=/apps/apr-util/ \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=event \
--enable-proxy \
--enable-proxy-http \
--enable-proxy-ajp \
--enable-proxy-balancer \
--enable-lbmethod-heartbeat \
--enable-heartbeat \
--enable-slotmem-shm  \
--enable-slotmem-plain \
--enable-watchdog
make -j`lscpu | grep "^CPU(s)" | awk '{print $NF}'` && make install
4.3 编译安装httpd-2.4方法二

(1)将apr 和apr-util源码与httpd 源码合并

tar xf apr-1.7.0.tar.bz2
tar xf apr-util-1.6.1.tar.bz2
tar xf httpd-2.4.46.tar.bz2

mv apr-1.7.0 httpd-2.4.46/srclib/apr
mv apr-util-1.6.1 httpd-2.4.46/srclib/apr-util

ls httpd-2.4.46/srclib/
apr apr-util Makefile.in

(2)将三者一并编译并安装

cd httpd-2.4.46
./configure \
--prefix=/apps/httpd24 \
--sysconfdir=/etc/httpd24 \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-included-apr \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=event \
--enable-proxy \
--enable-proxy-http \
--enable-proxy-ajp \
--enable-proxy-balancer \
--enable-lbmethod-heartbeat \
--enable-heartbeat \
--enable-slotmem-shm  \
--enable-slotmem-plain \
--enable-watchdog
make -j`lscpu | grep "^CPU(s)" | awk '{print $NF}'` && make install

4.4 编译安装后配置

Httpd编译过程:/apps/httpd24/build/config.nice

自带的服务控制脚本:/apps/httpd24/bin/apachectl

创建专用用户

id apache &> /dev/null || useradd -r -u 80 -d /var/www -s /sbin/nologin apache

指定运行httpd的用户

sed -ri 's#(User )daemon#\1apache#' /apps/httpd/conf/httpd.conf
sed -ri 's#(Group )daemon#\1apache#' /apps/httpd/conf/httpd.conf

配置环境变量

echo 'PATH=/apps/httpd24/bin:$PATH' > /etc/profile.d/httpd.sh
source /etc/profile.d/httpd.sh

[root@centos7 httpd-2.4.46]#httpd -v

配置帮助

echo 'MANDATORY_MANPATH /apps/httpd/man' >> /etc/man_db.conf

设置开机自动启动

vim /etc/rc.d/rc.local
/apps/httpd24/bin/apachectl start
chmod +x /etc/rc.d/rc.local

创建service unit文件(CentOS 7 以上版本)

cat > /lib/systemd/system/httpd.service << EOF
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=forking
ExecStart=/apps/httpd24/bin/apachectl start
ExecReload=/apps/httpd24/bin/apachectl graceful
ExecStop=/apps/httpd24/bin/apachectl stop
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now httpd.service

创建启动脚本(CentOS 6 以前版本)

#自定义启动脚本(参考httpd-2.2的服务脚本)
cp /etc/rc.d/init.d/httpd /etc/rc.d/init.d/httpd24
vim /etc/rc.d/init.d/httpd24
apachectl=/apps/httpd24/bin/apachectl
httpd=${HTTPD-/apps/httpd24/bin/httpd}
pidfile=${PIDFILE-/apps/httpd24/logs/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd24}

chkconfig -add httpd24 
chkconfig -list httpd24

查看版本

[root@centos7 ~]#httpd -v

示例:线上配置

[@yf_20_172 conf]#  grep -Ev "#|^$" httpd.conf
ServerTokens Prod
ServerRoot "/etc/httpd"
PidFile run/httpd.pid
Timeout 120
KeepAlive Off
MaxKeepAliveRequests 100
ProxyTimeout  1
KeepAliveTimeout 15
<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
</IfModule>
<IfModule worker.c>
ThreadLimit        600
ServerLimit         10
StartServers         6
MaxClients         600
MinSpareThreads    200
MaxSpareThreads    600
ThreadsPerChild    150
MaxRequestsPerChild  500000
</IfModule>
Listen 80
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
LoadModule ext_filter_module modules/mod_ext_filter.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule info_module modules/mod_info.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule suv2_module modules/mod_suv2.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule uuid_module modules/mod_uuid.so
Include conf.d/*.conf
User apache
Group apache
ServerAdmin root@localhost
UseCanonicalName Off
DocumentRoot "/search/apache/htdocs"
<Location /resourceforad4test/js/data.js>
        Header unset Last-Modified
        Header unset Expires
        Header unset Date
        RequestHeader unset If-Modified-Since
        Header set Cache-Control no-cache
</Location>
<Location /resourceforad4test/js/filldiv.js>
        Header unset Last-Modified
        Header unset Expires
        Header unset Date
        RequestHeader unset If-Modified-Since
        Header set Cache-Control no-cache
</Location>
<Location /resourceforad4test/js/data4test.js>
        Header unset Last-Modified
        Header unset Expires
        Header unset Date
        RequestHeader unset If-Modified-Since
        Header set Cache-Control no-cache
</Location>
<Location /resourceforad4test/js/filldiv4test.js>
        Header unset Last-Modified
        Header unset Expires
        Header unset Date
        RequestHeader unset If-Modified-Since
        Header set Cache-Control no-cache
</Location>
<Directory />
    Options +Indexes FollowSymLinks
    IndexOptions FancyIndexing
    IndexOrderDefault Descending Date
    AllowOverride None
</Directory>
<IfModule mod_userdir.c>
    UserDir disable
</IfModule>
DirectoryIndex index.html index.htm
AccessFileName .htaccess
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
</Files>
TypesConfig /etc/mime.types
DefaultType text/plain
<IfModule mod_mime_magic.c>
    MIMEMagicFile conf/magic
</IfModule>
HostnameLookups Off
ErrorLog "|/usr/sbin/cronolog -S /search/apache/logs/error_log /search/apache/logs/error_log.%Y%m%d"
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%v %h %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{SUID}C %D %{SSUID}C %{X-Forwarded-For}i %I %{YYID}C %{uuid}C %{IPLOC}C \"%{caucho_host}n|%{caucho_tries}n\"" soglog
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog "|/usr/sbin/cronolog -p 5minitus -S /search/apache/logs/access_log /search/apache/logs/access_log.%Y%m%d%H%M" soglog env=!nlog
ServerSignature Off
Alias /icons/ "/var/www/icons/"
<Directory "/var/www/icons">
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
<IfModule mod_dav_fs.c>
    DAVLockDB /var/lib/dav/lockdb
</IfModule>
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>
AddLanguage ca .ca
AddLanguage cs .cz .cs
AddLanguage da .dk
AddLanguage de .de
AddLanguage el .el
AddLanguage en .en
AddLanguage eo .eo
AddLanguage es .es
AddLanguage et .et
AddLanguage fr .fr
AddLanguage he .he
AddLanguage hr .hr
AddLanguage it .it
AddLanguage ja .ja
AddLanguage ko .ko
AddLanguage ltz .ltz
AddLanguage nl .nl
AddLanguage nn .nn
AddLanguage no .no
AddLanguage pl .po
AddLanguage pt .pt
AddLanguage pt-BR .pt-br
AddLanguage ru .ru
AddLanguage sv .sv
AddLanguage zh-CN .zh-cn
AddLanguage zh-TW .zh-tw
LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW
ForceLanguagePriority Prefer Fallback
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddHandler type-map var
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0
BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
BrowserMatch "MS FrontPage" redirect-carefully
BrowserMatch "^WebDrive" redirect-carefully
BrowserMatch "^WebDAVFS/1.[0123]" redirect-carefully
BrowserMatch "^gnome-vfs/1.0" redirect-carefully
BrowserMatch "^XML Spy" redirect-carefully
BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
NameVirtualHost *
[@yf_20_172 conf]# 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值