Apache的安装部署及工做模式详解

在LInux服务器上实现web服务,常见无非也就是Apache、Nginx、Tomcat。php

三者之间的区别:html

  • Apache:支持的模块比较多,采用servlet处理模型,同步阻塞模型,工做模式多变,对于高并发的场景处理速度比较慢,运行稳定;
  • Nginx :轻量级web服务器,自身支持模块少,须要借助第三方模块支持(Nginx官网就能够下载),采用epoll处理模式,异步非阻塞型,适合高并发场景,配置简单;
  • Tomcat:apache软件基金会下开源的子项目,也成为容器,主要处理java语言编写的页面,也能够处理html页面,并发链接小;

今天这篇博文主要就是围绕apache-2.4.23版本展开的:java

对apache不太了解的朋友能够参考博文:基于Apache搭建Web服务器详解
这里就不具体介绍apache到底是什么、它的原由什么的了。web

博文大纲:
1、httpd-2.4.23版本特性
2、编译安装httpd-2.4.23
3、apche的三种工做模式
4、进程与线程的区别apache

1、httpd-2.4.23版本特性

新版本的httpd-2.4.23新增模块:vim

  • mod_proxy_fcgi(可提供fcgi代理);
  • mod_ratelimit(限制用户带宽);
  • mod_request(请求模块,对请求进行过滤);
  • mod_remoteip(匹配客户端的IP地址);

对于基于IP的访问控制进行了修改,再也不支持allow、deny、order机制,而是统一使用require进行!centos

新增的特性有:缓存

  • MPM支持在运行时装载;
  • 支持envet工做模式;
  • 支持异步读写功能;
  • 每一个模块均可以指定输出的日志级别;
  • 加强版的表达式分析器;
  • 请求配置:<if>,<elseif>;
  • 毫秒级别的keepalive timeout;
  • 支持FQDN的虚拟主机;
  • 支持自定义变量;

接下来开始安装!安全

2、编译安装httpd-2.4.23

安装环境:bash

(1)首先检查是否安装httpd软件包

[root@localhost ~]# rpm -q httpd
未安装软件包 httpd 
//若是存在,使用“-e”选项进行卸载

(2)安装apr

apr是Apache可移植运行库,是一个对操做系统条用的抽象库,用于实现Apache内部组件对操做系统的使用,提升系统的可移植性。

[root@localhost ~]# tar zxf apr-1.5.2.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/apr-1.5.2/
[root@localhost apr-1.5.2]# ./configure --prefix=/usr/local/apr && make && make install

(3)安装apr-util

[root@localhost ~]# tar zxf apr-util-1.5.4.tar.gz -C /usr/src
 [root@localhost ~]# cd /usr/src/apr-util-1.5.4/
 [root@localhost apr-util-1.5.4]#  ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && make && make install

(4)安装zlib

[root@localhost ~]# tar zxf zlib-1.2.8.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/zlib-1.2.8/
[root@localhost zlib-1.2.8]#  ./configure --prefix=/usr/local/zlib && make && make install

(5)安装pcre

[root@localhost ~]# tar zxf pcre-8.39.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/pcre-8.39/
[root@localhost pcre-8.39]#  ./configure -- prefix=/usr/local/pcre && make && make install

(6)安装openssl

安装apache-2.4.23版本时,会提示openssl自带的版本太低,须要自行手动安装新的版本。

[root@localhost ~]# tar zxf openssl-1.0.1u.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/openssl-1.0.1u/
[root@localhost openssl-1.0.1u]#  ./config -fPIC --prefix=/usr/local/openssl enable-shared && make && make install
//PIC使.so文件的代码段变为真正意义上的共享
//若是不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象须要重定位, 重定位会修改代码段的内容,这就形成每一个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每一个copy都不同,取决于 这个.so文件代码段和数据段内存映射的位置.

(7)安装 httpd-2.4.23

[root@localhost ~]# tar zxf httpd-2.4.23.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/httpd-2.4.23/
[root@localhost httpd-2.4.23]#  ./configure --prefix=/usr/local/http-2.4.23 --enable-so --enable-cgi \
 --enable-cgid --enable-ssl --with-ssl=/usr/local/openssl --enable-rewrite \
 --with-pcre=/usr/local/pcre --with-z=/usr/local/zlib --with-apr=/usr/local/apr \
 --with-apr-util=/usr/local/apr-util --enable-modules=most --enable-mods-shared=most \
 --enable-mpms-shared=all --with-mpm=event --enable-proxy --enable-proxy-fcgi --enable-expires \
 --enable-deflate  && make && make install

各选项含义:

  • --enable-so:支持动态共享模块;
  • --enable-rewrite:支持url重写;
  • --enable-ssl:支持ssl;
  • --with-ssl=/usr/local/openssl:指定ssl安装位置;
  • --enable-cgi:开启cgi通用网管接口;
  • --enable-cgid:开启cig通用网管接口管理程序;
  • --enable-modules=most:编译成二进制是安装经常使用模块;
  • --enable-mpms-shared=all:安装apache的全部工做模式;
  • --with-mpm=event:指定默认的运行方式
  • --with-pcre=/usr/local/pcre:支持 pcre ;
  • --with-z=/usr/local/zlib:使用 zlib 压缩库;
  • --with-apr=/usr/local/apr:指定 apr 的安装路径;
  • --with-apr-util=/usr/local/apr-util:指定 apr-util 的安装路径;
  • --enable-expires:支持缓存;
  • --enable-deflate:支持压缩;

(8)优化http程序的执行路径

[root@localhost httpd-2.4.23]#  ln -s /usr/local/http-2.4.23/bin/* /usr/local/bin/

(9)添加为系统服务

[root@localhost httpd-2.4.23]#  cp /usr/local/http-2.4.23/bin/apachectl /etc/init.d/httpd 
[root@localhost httpd-2.4.23]# vim /etc/init.d/httpd
#!/bin/bash                      //修改
#chkconfig: 35 85 15                   //添加
…………                  //省略如下内容
[root@localhost httpd-2.4.23]#  chkconfig --add httpd 
[root@localhost httpd-2.4.23]# systemctl start httpd
[root@localhost httpd-2.4.23]# netstat -anpt | grep 80
tcp6       0      0 :::80                   :::*                    LISTEN      108903/httpd 
[root@localhost ~]# httpd -M              //能够查看到httpd服务启动加载的模块
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain. Set the 'ServerName' directive globally to suppress this message
//关于启动服务时提示以上的信息,能够省略,也可修改其配置文件(/usr/local/http-2.4.23/conf/httpd.conf)文件找到“ServerName ”一行,根据实际状况进行修改
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 authn_file_module (shared)
 authn_core_module (shared)
 authz_host_module (shared)
 authz_groupfile_module (shared)
 authz_user_module (shared)
 authz_core_module (shared)
 access_compat_module (shared)
 auth_basic_module (shared)
 reqtimeout_module (shared)
 filter_module (shared)
 mime_module (shared)
 log_config_module (shared)
 env_module (shared)
 headers_module (shared)
 setenvif_module (shared)
 version_module (shared)
 mpm_prefork_module (shared)
 unixd_module (shared)
 status_module (shared)
 autoindex_module (shared)
 dir_module (shared)
 alias_module (shared)

至此apache-2.4.23已经安装完成。

3、apche的三种工做模式

(1)Prefork模式

其工做方式:当Apache服务启动后,mpm_prefork模块会预先建立多个子进程(默认为5个),每一个子进程只有一个线程,当接收到客户端请求后,mpm_prefork模块再将请求转交给子进程进行处理,而且每一个子进程同时只能用于单个请求。若是当前的请求数将超过预先建立的子进程数时,mpm_prefork模块就会建立新的子进程来处理额外的请求。
如图:
Apache的安装部署及工做模式详解
Apache老是试图保持一些备用或空闲的子进程用于迎接即将到来的请求。这样客户端的请求就不须要在接收后等待子进程的产生。

因为在 mpm_prefork 模块中,每一个请求对应一个子进程,所以其占用的系统资源相对其余 两种模块而言较多。不过 mpm_prefork 模块的优势在于它的每一个子进程都会独立处理对应 的单个请求,这样,若是其中一个请求出现问题就不会影响到其余请求。Prefork 在效率上 要比 Worker 要高,可是内存使用大得多不擅长处理高并发的场景。

开启prefork模式的方法:

[root@localhost ~]# vim /usr/local/http-2.4.23/conf/httpd.conf
//编写httpd的主配置文件,修改一下内容
Include conf/extra/httpd-mpm.conf                     //默认存在删除“#”号便可
#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
//这三行即是apache的三种工做模式,可根据实际状况进行切换
[root@localhost ~]# systemctl restart httpd      //从新启动httpd服务
[root@localhost ~]# systemctl start httpd     //手动再启动一下
[root@localhost ~]# httpd -V      //查看httpd的工做模式
//找到这一行便可
Server MPM:     prefork                //能够看到如今Apache工做在prefork模式

与prefork模式有关的配置文件以下:

[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-mpm.conf 
//设置prefork模式也就只有这几个参数,具体含义:
<IfModule mpm_prefork_module>            //这就是prefork工做模式的参数-
    StartServers             5                //apache启动时默认开启的子进程数
    MinSpareServers          5                  //最小的闲置子进程数
    MaxSpareServers         10               //最大的闲置子进程数
    MaxRequestWorkers      250        // 设置了容许同时的最大接入请求数量
    MaxConnectionsPerChild   0         //0表示每一个子进程处理完数据后进程永不销毁,设置成非0时,可防止内存泄漏,服务器在负载小时自动减小本身进程数
</IfModule>

关于其配置内容可参考图片:
Apache的安装部署及工做模式详解
//注 1:MaxRequestWorkers 是这些指令中最为重要的一个,设定的是 Apache 能够同时处理 的请求,是对 Apache 性能影响最大的参数。若是请求总数已达到这个值(可经过 ps -ef|grep http|wc -l 来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源 还剩下不少而 HTTP 访问却很慢的主要缘由。虽然理论上这个值越大,能够处理的请求就越 多,建议将初始值设为(以 Mb 为单位的最大物理内存/2),而后根据负载状况进行动态调整。 好比一台 4G 内存的机器,那么初始值就是 4000/2=2000
注 2:prefork 控制进程在最初创建“StartServers”个子进程后,为了知足 MinSpareServers 设置的须要建立一个进程,等待一秒钟,继续建立两个,再等待一秒钟,继续建立四个……如 此按指数级增长建立的进程数,最多达到每秒 32 个,直到知足 MinSpareServers 设置的值为止。这种模式 能够没必要在请求到来时再产生新的进程,从而减少了系统开销以增长性能。 MaxSpareServers 设置了最大的空闲进程数,若是空闲进程数大于这个 值,Apache 会自动 kill 掉一些多余进程。这个值不要设得过大,但若是设的值比 MinSpareServers 小,Apache 会自 动把其调整为 MinSpareServers+1。若是站点负载较大,可考虑同时加大 MinSpareServers 和 MaxSpareServers。
注 3:ServerLimit 和 MaxClients(MaxRequestWorkers)有什么区别呢? 是由于在 apache1 时代,控制最大进程数只有 MaxClients 这个参数,而且这个参数最大值为 256,而且是写死了的,试图设置为超过 256 是无效的,这是因为 apache1 时代的服务器硬 件限制的。可是 apache2 时代因为服务器硬件的升级,硬件已经再也不是限制,因此使用 ServerLimit 这个参数来控制最大进程数,ServerLimit 值>=MaxClient 值才有效。ServerLimit 要放在 MaxClients 以前,值要不小于 MaxClients

优势:成熟,兼容全部新老模块。进程之间彻底独立,使得它很是稳定。同时,不须要担忧线程安全的问题。(咱们经常使用的mod_php,PHP的拓展不须要支持线程安全)

缺点:一个进程相对占用更多的系统资源,消耗更多的内存。并且,它并不擅长处理高并发请求,在这种场景下,它会将请求放进队列中,一直等到有可用进程,请求才会被处理。

(2)Worker工做模式

Worker 模式(多线程多进程): 和 prefork 模式相比,worker 使用了多进程和多线程的混合模式,worker 模式也一样会先预派生一些子进程,而后每一个子进程建立一些线程,同时包括一个监听线程,每一个请求过来会 被分配到一个线程来服务。线程比起进程会更轻量,由于线程是经过共享父进程的内存空间, 所以,内存的占用会减小一些,在高并发的场景下会比 prefork 有更多可用的线程,表现会 更优秀一些;另外,若是一个线程出现了问题也会致使同一进程下的线程出现问题,若是是 多个线程出现问题,也只是影响 Apache 的一部分,而不是所有。因为用到多进程多线程, 须要考虑到线程的安全了,在使用 keep-alive 长链接的时候,某个线程会一直被占用,即便 中间没有请求,须要等待到超时才会被释放(该问题在 prefork 模式下也存在) 总的来讲,prefork 方式速度要稍高于 worker,然而它须要的 cpu 和 memory 资源也稍多于 woker。如图:
Apache的安装部署及工做模式详解

Apache老是试图维持一个备用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的创建便可获得处理。在Unix中,为了可以绑定80端口,父进程通常都是以root身份启动,随后,Apache以较低权限的用户创建子进程和线程。User和Group指令用于配置Apache子进程的权限。虽然子进程必须对其提供的内容拥有读权限,但应该尽量给予他较少的特权。另外,除非使用了suexec(负责处理CGI和SSI程序的请求,确保网页使用者能以该目录或程序的用户ID来执行远程程序。) ,不然,这些指令配置的权限将被CGI脚本所继承。

线程比起进程会更轻量,由于线程一般会共享父进程的内存空间,所以,内存的占用会减小一些,在高并发的场景下,表现得比 prefork模式好。

有些人会以为奇怪,那么这里为何不直接使用多线程呢?主要是须要考虑稳定性,若是一个线程异常挂了,会致使父进程连同其余正常的子线程都挂了(它们都是同一个进程下的)。多进程+多线程模式中,各个进程之间都是独立的,若是某个线程出现异常,受影响的只是Apache的一部分服务,而不是整个服务。其余进程仍然能够工做。

有关work模式的配置:

//自行修改httpd主配置文件,切换模式并重启服务,接下来
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-mpm.conf 
<IfModule mpm_worker_module>       //这是worker工做模式的参数
    StartServers             3                  //apache启动时默认开始的子进程数
    MinSpareThreads         75            //最小空闲数量的工做线程-
    MaxSpareThreads        250          //最大空闲数量的工做线程-
    ThreadsPerChild         25              //每一个子进程产生的线程数量
    MaxRequestWorkers      400        //每一个进程最大接受的请求数量
    MaxConnectionsPerChild   0         //表示永不销毁
</IfModule>

有关work模式的详细介绍请参考图片:
Apache的安装部署及工做模式详解
Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild 值决定的,应该大于等于MaxRequestWorkers。若是负载很大,现有的子进程数不能知足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时 也须要显式声明ServerLimit(最大值是20000)。须要注意的是,若是显式声明了ServerLimit,那么它乘以 ThreadsPerChild的值必须大于等于MaxRequestWorkers,并且MaxRequestWorkers必须是ThreadsPerChild的整数倍,不然 Apache将会自动调节到一个相应值。

优势:占据更少的内存,高并发下表现更优秀。

缺点:必须考虑线程安全的问题,由于多个子线程是共享父进程的内存地址的。若是使用keep-alive的长链接方式,也许中间几乎没有请求,这时就会发生阻塞,线程被挂起,须要一直等待到超时才会被释放。若是过多的线程,被这样占据,也会致使在高并发场景下的无服务线程可用。(该问题在prefork模式下,一样会发生)。

(3)Event MPM

这是Apache最新的工做模式,它和worker模式很像,不一样的是在于它解决了keep-alive长链接的时候占用线程资源被浪费的问题,在event工做模式中,会有一些专门的线程用来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务器的线程,执行完毕后,又容许它释放。这加强了在高并发场景下的请求处理。如图:
Apache的安装部署及工做模式详解

有关Event MPM模式的配置:

//自行修改httpd主配置文件,切换模式并重启服务,接下来
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-mpm.conf 
<IfModule mpm_event_module>
    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0                 
</IfModule>
//其各项配置内容与work模式十分类似,这里就很少说了!

4、进程与线程的区别

线程就是指进程内的一个执行单元,也是进程内的可调度实体。

线程与进程的区别:

  • 地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有本身独立的地址空间;
  • 资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源;
  • 线程是处理器调度的基本单位,但进程不是;
  • 两者都可并发执行;

进程和线程都是由操做系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
进程和线程的区别在于:
简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程
序的运行效率。

———————— 本文至此结束,感谢阅读 ————————

相关文章
相关标签/搜索