当前位置 : 首页 » 文章分类 :  开发  »  Apache-httpd

Apache-httpd

httpd 使用笔记


概述

Apache httpd的多进程工作模式(MPM)

Apache httpd 2.4中,一共有三种稳定的MPM(Multi-Processing Module,多进程处理模块)模式。它们分别是prefork,worker和event,它们同时也代表这Apache的演变和发展。

prefork:多进程,每个请求用一个进程响应,这个过程会用到select机制来通知。
worker:多线程,一个进程可以生成多个线程,每个线程响应一个请求,但通知机制还是select不过可以接受更多的请求。
event:基于异步I/O模型,一个进程或线程,每个进程或线程响应多个用户请求,它是基于事件驱动(也就是epoll机制)实现的。

可以使用httpd -V命令来查看MPM模式
Apache2.2中,默认启用prefork模式,同时引进了实验性质的event模式;
Apache2.4中,正式支持并且默认使用了event模式。

编译的时候,可以通过configure的参数来指定:

--with-mpm=prefork|worker|event

也可以编译为三种都支持,通过修改配置来更换

--enable-mpms-shared=all

在httpd.conf中修改Apache的多处理模式MPM可以通过(modules文件夹下,会自动编译出三个MPM的so):

#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule mpm_worker_module modules/mod_mpm_worker.so
#LoadModule mpm_event_module modules/mod_mpm_event.so

prefork(预分配多进程单线程select)

prefork模式可以算是很古老但是非常稳定的Apache模式。Apache在启动之初,就预先fork一些子进程,然后等待请求进来。之所以这样做,是为了减少频繁创建和销毁进程的开销。每个子进程只有一个线程,在一个时间点内,只能处理一个请求。
优点:成熟稳定,兼容所有新老模块。同时,不需要担心线程安全的问题。
缺点:一个进程相对占用更多的系统资源,消耗更多的内存。而且,它并不擅长处理高并发请求,在这种场景下,它会将请求放进队列中,一直等到有可用进程,请求才会被处理。

Apache的httpd.conf中的配置方式:

<IfModule mpm_prefork_module>
    StartServers            5
    MinSpareServers          5
    MaxSpareServers        10
    MaxConnectionsPerChild  0
    MaxRequestWorkers      1500  ///2.3.1版本之前的叫MaxClients,看了很多博客都说MaxClients,一直没找到,原来说的是这个
</IfModule>

启动时建立StartServers个子进程,默认值5
然后按每秒创建指数级个进程直到达到MinSpareServers个进程(最多增到每秒32个),
如果空闲进程数大于MaxSpareServers,则检查kill掉一些空闲进程。
MaxRequestPerChild指定每个进程处理了多少个请求后就自我毁灭。
MaxClients指定apache最多可以同时处理的请求数,也就是进程数?
MaxClients默认不能大于256,可以通过设定ServerLimit来增大这个限制数,最大20000?

MaxClients设定Apache可同时处理的请求数量,其对Apache性能的影响非常大。默认的150远远不能满足一般站点(ps -ef | grep httpd | wc -l),超过这个数量的请求需要排队,直到前面的请求处理完毕。

MaxRequestsPerChild这个值的含义是处理多少个请求后该进程自动销毁,默认值0意味着永不销毁。当负载较高时,为了使每个进程处理更多的请求,避免销毁、创建进程的开销,一般建议设置为0或较大的数字。但是也要注意可能会造成进程占用的内存不能得到释放,所以这个值不能设置得太大,也不能太小,大了会影响资源的释放,小了会导致Apache不断地fork进程。

worker(预分配多进程多线程select)

worker模式比起上一个,是使用了多进程和多线程的混合模式。它也预先fork了几个子进程(数量比较少),然后每个子进程创建一些线程,同时包括一个监听线程。每个请求过来,会被分配到1个线程来服务。线程比起进程会更轻量,因为线程通常会共享父进程的内存空间,因此,内存的占用会减少一些。在高并发的场景下,因为比起prefork有更多的可用线程,表现会更优秀一些。

有些人会觉得奇怪,那么这里为什么不完全使用多线程呢,还要引入多进程?
原因主要是需要考虑稳定性,如果一个线程异常挂了,会导致父进程连同其他正常的子线程都挂了(它们都是同一个进程下的)。为了防止这场异常场景出现,就不能全部使用线程,使用多个进程再加多线程,如果某个线程出现异常,受影响的只是Apache的一部分服务,而不是整个服务。

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

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

注:keep-alive的长连接方式,是为了让下一次的socket通信复用之前创建的连接,从而,减少连接的创建和销毁的系统开销。保持连接,会让某个进程或者线程一直处于等待状态,即使没有数据过来。

Apache的httpd.conf中的配置方式:

<IfModule mpm_worker_module>
    StartServers                  3
    MaxClients                    2000
    ServerLimit                    25
    ThreadLimit                  200
    ThreadsPerChild            100
    MinSpareThreads        50
    MaxSpareThreads        200
    MaxRequestsPerChild  0
</IfModule>

启动时建立StartServers个子进程,
每个进程包含ThreadsPerChild个线程,缺省最大64
MinSpareThreads定义最小的空闲线程数,最大75
MaxSpareThreads定义最大的空闲线程数,超过则执行清理?最大250
MaxClients定义所有子进程中的线程总数
ThreadLimit,最大20000,默认64
ServerLimit,最大值20000,默认16

event(优化空闲长连接epoll)

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

event MPM在遇到某些不兼容的模块时,会失效,将会回退到worker模式,一个工作线程处理一个请求。官方自带的模块,全部是支持event MPM的。

注意一点,event MPM需要Linux系统(Linux 2.6+)对EPoll的支持,才能启用。

还有,需要补充的是HTTPS的连接(SSL),它的运行模式仍然是类似worker的方式,线程会被一直占用,直到连接关闭。部分比较老的资料里,说event MPM不支持SSL,那个说法是几年前的说法,现在已经支持了。

Apache的httpd.conf中的配置方式:

<IfModule mpm_event_module>
    StartServers            3
    MinSpareThreads        75
    MaxSpareThreads        250
    ThreadsPerChild        25
    MaxRequestWorkers      400
    MaxConnectionsPerChild  0
</IfModule>

Apache的三种MPM模式比较:prefork,worker,event(写的很好,很清晰)
http://blog.jobbole.com/91920/

Apache性能优化之MPM选择和配置
https://blog.csdn.net/ccscu/article/details/70182476

Nginx为什么比Apache Httpd高效:原理篇
http://www.mamicode.com/info-detail-1156329.html

Apache里的 MPM 调优比较详细
https://blog.csdn.net/ystyaoshengting/article/details/49149169


httpd负载均衡配置(反向代理)

使用自带的mod_proxy模块

mod_proxy是apache httpd自带的负载均衡模块。在Apache2以上的版本中已经集成了,因此不需要再另行安装和配置了,只需要把注释去掉即可。
其优点可以根据实际的运行时机器的环境来决定负载均衡的策略。

Apache2.2以后,提供了一种原生的方式配置负载均衡和集群,也就是mod_proxy,比mod_jk简单很多。

在httpd的配置文件中httpd.conf中加载so库:

#mod_proxy_blancer
LoadModule proxy_module modules/mod_proxy.so  #提供代理服务器功能
LoadModule proxy_connect_module modules/mod_proxy_connect.so  #链接的模块
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so #让代理服务器能支持AJP协议
LoadModule proxy_http_module modules/mod_proxy_http.so  #让代理服务器能支持HTTP协议
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so  #提供负载均衡功能

LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so #算法模块,根据server的请求量
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so #算法模块,根据server流量
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so #算法模块,根据server繁忙程度

LoadModule slotmem_shm_module modules/mod_slotmem_shm.so #共享slot内存模块

httpd端配置

<VirtualHost *:80>
    ServerAdmin limingnihao@iteye.com
    ServerName localhost
    ServerAlias localhost

    #The ProxyRequests directive should usually be set off when using ProxyPass.
    ProxyRequests Off  # 关闭正向代理
    ProxyPass /images !
    ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off
    ProxyPassReverse /test balancer://mycluster/  # ProxyPassReverse 的配置总是和ProxyPass 一致

    <Proxy balancer://mycluster>
        BalancerMember http://127.0.0.1:8080 loadfactor=3
        BalancerMember http://127.0.0.1:7080 loadfactor=3
        BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=tomcat1
        BalancerMember ajp://127.0.0.1:7009 loadfactor=1 route=tomcat2
        ProxySet lbmethod=byrequests
    </Proxy>

    ErrorLog "logs/error.log"
    CustomLog "logs/access.log" common
</VirtualHost>

解释:

  • ProxyPass 反向代理请求转发:
    ProxyPass /images ! 表示/images开头的请求不会转发,”!”指令表示禁止代理转发,禁止配置必须放在允许转发配置之前
    ProxyPass /test balancer://mycluster/ 表示所有的/test请求都会被转发到balancer://mycluster/处理。balancer是自定义的一个负载均衡器。
    ProxyPass / balancer://mycluster/ 表示所有请求都转发到mycluster,因为所有请求url都满足前缀/

  • stickySession=JSESSIONID 表示开启粘性Session,根据JSESSIONID来做粘着。他的意思是如果第一次请求分到了worker1的Tomcat,那么同一JSESSIONID的后续请求,都会分配给worker1的这个Tomcat。

  • <Proxy>配置一个负载均衡器,Proxy中的每个成员BalancerMember表示一个tomcat服务器,url指定使用的通讯协议为http或ajp,通过route指定tomcat名称

  • loadfactor表示请求的权值,该值默认为1,可以将该值设置为1到100之间的任何值。
    此外还可以配置更多参数,例如loadfactor=1 route=tomcat8_local smax=5 max=20 ttl=120 retry=300 timeout=15 最大链接,超时,等等

  • ProxySet lbmethod=byrequests 为实现负载均衡的方式(负载均衡算法),共有三种取值:byrequests(默认),bytraffic,bybusyness
    lbmethod=byrequests也可以配置在ProxyPass中,例如:ProxyPass / balancer://mycluster/ lbmethod=byrequests

tomcat端配置

使用http协议时,tomcat端配置:

<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

tomcat提供了ajp协议和httpd通信。当不想tomcat的8080端口开放时,可以使用此方式
使用ajp协议时,tomcat端配置:
根据httpd中配置的route=tomcat1/2,分别在两个Tomat中的Service.xml的 Engine 节点配置上jvmRoute的内容,如下:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

Apache学习之二、HTTPD的负载均衡
http://limingnihao.iteye.com/blog/1934548

Apache+Tomcat实现负载均衡
https://www.cnblogs.com/fly_binbin/p/3881207.html

Apache配置反向代理、负载均衡和集群(mod_proxy方式)
http://blog.itpub.net/29254281/viewspace-1070221/


mod_proxy的负载均衡策略

ProxySet lbmethod=byrequests 为实现负载均衡的方式(负载均衡算法),共有三种类型
lbmethod=byrequests 按照请求次数均衡(默认),此时loadfactor后的权重值表示请求次数
lbmethod=bytraffic 按照流量均衡,此时loadfactor后的权重值表示响应的字节数的比例
lbmethod=bybusyness 按照繁忙程度均衡(总是分配给活跃请求数最少的服务器)

如何配置轮询转发?
什么都不配的情况下,默认就是轮询,因为lbmethod默认为byrequests按请求次数均衡,权重值loadfactor默认为1,也就是1次转发给A,一次转发给B,如下:

ProxyPass / balancer://proxy/
<Proxy balancer://proxy>
      BalancerMember http://192.168.6.37:6888/
      BalancerMember http://192.168.6.38:6888/
</Proxy>

如何配置按指定的请求次数均衡?
只需在每个BalancerMember后台服务器url后配置loadfactor,因为lbmethod默认为byrequests按请求次数均衡,如下配置则连续3个请求到A,然后1个请求到B,然后继续3个请求到A

ProxyPass / balancer://proxy/
<Proxy balancer://proxy>
        BalancerMember http://192.168.6.37:6888/  loadfactor=3
        BalancerMember http://192.168.6.38:6888/  loadfactor=1
</Proxy>

如何配置按流量均衡?
指定lbmethod为bytraffic按流量均衡,并且配置比例3:1,则A负载的请求和响应的字节数是B的3倍

ProxyPass / balancer://proxy/ lbmethod=bytraffic
<Proxy balancer://proxy>
        BalancerMember http://192.168.6.37:6888/  loadfactor=3
        BalancerMember http://192.168.6.38:6888/  loadfactor=1
        # ProxySet lbmethod=bytraffic
</Proxy>

也可以把lbmethod配置放在Proxy中,ProxySet lbmethod=bytraffic

Apache学习之二、HTTPD的负载均衡
http://limingnihao.iteye.com/blog/1934548

Apache配置反向代理、负载均衡和集群(mod_proxy方式)
http://blog.itpub.net/29254281/viewspace-1070221/

apache2.2.4 负载均衡初探
https://blog.csdn.net/paulluo0739/article/details/2269052


热备(status=+H)

热备份的实现很简单,只需添加 status=+H 属性,就可以把某台服务器指定为备份服务器。
如下配置:

<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:7080 status=+H
    ProxySet lbmethod=byrequests
</Proxy>
ProxyRequests Off
ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse /test balancer://mycluster/

此时请求总是流向 8080这个url ,一旦8080挂掉, Apache会检测到错误并把请求分流给7080。Apache会每隔几分钟检测一下8080的状况,如果8080恢复,就继续使用8080。

Apache学习之二、HTTPD的负载均衡
http://limingnihao.iteye.com/blog/1934548


Session同步方式

sticky黏着session(在httpd中配置)

前端balancer可实现sticky模式的session同步功能。利用负载均衡器的sticky模式的方式把所有同一session的请求都发送到相同的Tomcat节点。这样不同用户的请求就被平均分配到集群中各个tomcat节点上,实现负载均衡的能力。这样做的缺点是没有灾难恢复的能力。一旦一个节点发生故障,这个节点上所有的session信息全部丢失;同一用户同一session只和一个webServer交互,一旦这个webserver发生故障,本次session将丢失,用户不能继续使用。

httpd中配置方式为:
ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off
其中的 stickysession=JSESSIONID 表示根据session id来做粘着
stickySession=JSESSIONID表示开启粘性Session。他的意思是如果第一次请求分到了worker1的Tomcat,那么这个用户的后续请求,都会分配给worker1的这个Tomcat。

session复制(在tomcat集群中配置)

利用Tomcat session复制的机制使得所有session在所有Tomcat节点中保持一致。当一个节点修改一个session数据的时候,该节点会把这个 session的所有内容序列化,然后广播给所有其它节点。这样当下一个用户请求被负载均衡器分配到另外一个节点的时候,那个节点上有完备的 session信息可以用来服务该请求。

这种做法的问题是对session哪怕有一点点修改,也要把整个sessions数据全部序列化 (serialize),还要广播给集群中所有节点,不管该节点到底需不需要这个session。这样很容易会造成大量的网络通信,导致网络阻塞。一般采 用这种方式,当Tomcat节点超过4个时候,整个集群的吞吐量就不能再上升了;

此方式是通过tomcat本身提供的功能,只需要修改server.xml文件
(1)修改Engine节点信息: <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
(2)去掉<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> 的注释符,也就是使此配置项生效
(3)web.xml中增加 <distributable/>

Apache学习之二、HTTPD的负载均衡
http://limingnihao.iteye.com/blog/1934548

tomcat apache session粘性配置和session复制配置
http://blog.csdn.net/su63538702/article/details/72834983

Apache+Tomcat实现负载均衡
https://www.cnblogs.com/fly_binbin/p/3881207.html


使用tomcat提供的mod_jk模块

Tomcat提供了专门的JK插件来负责Tomcat和HTTP服务器的通信。应该把JK插件安置在对方的HTTP服务器上。当HTTP服务器接收到客户请求时,它会通过JK插件来过滤URL,JK插件根据预先配置好的URL映射信息,决定是否要把客户请求转发给Tomcat服务器处理。例如预先配置好所有”/*.jsp”形式的URL都由Tomcat服务器来处理

Tomcat提供了不同的JK插件的实现模块。常用的JK插件有:
与Apache HTTPD服务器集成:mod_jk.so
与Windows IIS服务器集成:isapi_redirect.dll

mod_jk的配置相对复杂,Apache2.2以后,提供了一种原生的方式配置负载均衡和集群,也就是mod_proxy,比mod_jk简单很多。

mod_proxy和mod_jk对比

那么什么时候使用哪一个呢?这依赖于你的架构。如果你已经有了或者需要apache 2.2的功能,那么你可以再mod_proxy和mod_jk直接选择。mod_jk在apache2.2上允许得很好。关键看你需要什么样的功能:

mod_proxy
优势:
不需要编译和维护一个对立的模块。mod_proxy,mod_proxy_http,mod_proxy_ajp,mod_proxy_balancer已经是apache 2.2+的标准集成部分;
可以使用http、https和AJP协议,即便是在同一个balancer中。
劣势:
mod_proxy_ajp不支持大于8k的数据包;
只有最基本的负载均衡器;
不支持域模型集群(domain model clustering)

mod_jk
优势:
先进的负载均衡器;
先进的节点失败侦察功能;
支持大型AJP 数据包
劣势:
需要单独维护一个独立的模块;

总结
我个人建议是如果有能力维护mod_jk模块的二进制版本,尽量使用mod_jk。mod_proxy一直在更新但还缺少一些mod_jk的功能。但是,如果你需要https和一个简单的负载均衡就是用mod_proxy.

Apache学习之二、HTTPD的负载均衡
http://limingnihao.iteye.com/blog/1934548

mod_proxy和mod_jk比较/区别
https://blog.csdn.net/wubai250/article/details/8533111


Apache与Tomcat的区别和联系

Apache有两种含义,一种是指Apache基金会,一种是指Apache服务器,即Apache httpd;
Tomcat是Apache基金会的一个子项目,是和Apache服务器(也就是httpd)同级别的项目。
一般说Apache,指Apache HTTP Server,即Apache httpd;说tomcat,指Apache tomcat
httpd是web服务器(静态解析,如HTML),tomcat是java应用服务器(动态解析,如JSP),Apache httpd本身没有提供Servlet/JSP容器,因此在实际应用中,通常把httpd与tomcat连接来对外提供Web服务。

为什么要将http server与Tomcat连接

事实上Tomcat本身已经提供了HTTP服务,该服务默认的端口是8080,装好tomcat后通过8080端口可以直接使用Tomcat所运行的应用程序,你也可以将该端口改为80。既然Tomcat本身已经可以提供这样的服务,我们为什么还要引入Apache或者其他的一些专门的HTTP服务器呢?原因有下面几个:

  • 1、提升对静态文件的处理性能。
  • 2、利用Web服务器来做负载均衡以及容错。
  • 3、无缝的升级应用程序。

这三点对一个web网站来说是非常之重要的,我们希望我们的网站不仅是速度快,而且要稳定,不能因为某个Tomcat宕机或者是升级程序导致用户访问不了,而能完成这几个功能的、最好的HTTP服务器也就只有apache的http server了,它跟tomcat的结合是最紧密和可靠的。

Apache HTTP Server(httpd)项目官网
http://httpd.apache.org/

January 2017 Web Server Survey 互联网Web服务器占有率调查
https://news.netcraft.com/archives/2017/01/12/january-2017-web-server-survey.html

查看apache版本
/opt/app/apache2/bin/httpd -v
Server version: Apache/2.2.22 (Unix)
Server built: Oct 17 2016 11:34:12


编译安装

下载

下载
http://httpd.apache.org/download.cgi
其他版本下载点页面中的archive download site
http://archive.apache.org/dist/httpd/

解压
tar -xzvf httpd-2.2.32.tar.gz
这样就在当前目录下新建了一个包含发行版源代码的目录,必须cd进入这个目录以继续服务器的编译。

./configure配置源代码树

要求ANSI-C编译器及编译环境
必须装有ANSI-C编译器,推荐使用自由软件基金会(FSF)的GCC。如果没有GCC,那么要确保使用的编译器符合ANSI标准,而且PATH中必须包含指向基本编译工具比如make的路径。
否则,执行./configure配置apache源码时提示找不到gcc:

checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: no acceptable C compiler found in $PATH

这一步是根据你的特定平台和个人需求配置源代码树。位于发行源代码根目录的configure脚本会完成这个步骤。
要想用所有的默认值配置源代码树只要简单的在httpd-2.2.32目录中执行 ./configure 命令就可以了,同时configure还可以接受命令行参数以改变默认值。
最重要的选项是Apache安装目录的前缀:--prefix ,因为Apache需要知道这个目录才能正常运作,默认为/usr/local/apache2
configure需要运行几分钟,以测试指定的功能在你的系统中是否有效,并建立稍后编译时所需的许多Makefile文件。

make编译

在httpd-2.2.32目录中执行make命令就可以编译Apache的各个部分了
请耐心等候,因为对一个基本配置的编译,需要运行几分钟左右,实际需要的时间会因为你的硬件和选择的模块数量有很大不同。

make install安装

在httpd-2.2.32目录中执行make install命令即可安装apache

升级

升级的第一步是阅读源代码目录中的发布公告(release announcement)和CHANGES文件以寻找可能会对你的站点产生影响的变化。如果主板本号的变化(例如1.3→2.0或2.0→2.2)表明编译时和运行时的配置发生了重大变化,需要手动调整,所有模块也需要升级以兼容新版本的模块API 。

小幅度的版本升级(例如:2.2.55→2.2.57)很容易。make install 的过程不会改写任何已经存在的文档、日志、配置文件。此外,开发者也会尽量兼容上一版本的configure选项、运行时配置、模块API 。大多数情况下,你将能够使用与上一版本完全相同的configure命令行和运行时配置,而你原来的所有模块也将正常工作。

如果你保存了上一次安装后build子目录中的config.nice文件,升级将更加平滑。这个文件精确地保存了所有对目录树进行配置的configure命令行。你只需要将config.nice文件复制到新的源代码目录树的根文件夹并进行你希望的修改后,然后运行下面的命令即可完成升级:

$ ./config.nice
$ make
$ make install
$ PREFIX/bin/apachectl -k graceful-stop
$ PREFIX/bin/apachectl -k start

你应该总是在将新版本的Apache投入正式运行前,对这个新版本进行足够的、针对你的实际运行环境的测试。比如,你可以使用一个不同的 --prefix 设置将新版本安装在一个不同的目录,并使用Listen指令在一个不同的端口监听。经过一段时间的测试以发现可能存在的问题,然后再做出最后的决定。


启动

在Unix操作系统中,httpd程序作为一个守护进程运行,在后台不断处理请求。

遇到的问题:

[root@localhost bin]# ./apachectl -k start
httpd: apr_sockaddr_info_get() failed for localhost.centos6.8
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName

这个问题应该是没有在 /etc/httpd/conf/httpd.conf 中设定 ServerName。所以apache会用主机上的名称来取代,首先会去找 /etc/hosts 中有没有主机的定义。
所以要解决这个问题可以设定httpd.conf文件中的 ServerName,如下:
(1)ServerName localhost:80
或者在 /etc/hosts 中填入自己的主机名称 bogon,如下:
(2)127.0.0.1 bogon

在虚拟机上安装Apache,默认配置安装,默认配置启动,无法通过ip地址访问Apache
原因:centos默认没有开放80端口,在windows命令窗口telnet ip 80测试虚拟机的80端口不通
解决:需修改防火墙配置,打开80端口,并重启防火墙。


配置

配置文件

Apache服务器的配置是通过文本格式的配置文件来实现的,在文本文件中包含逐条的配置指令,正是通过这些逐条的指令从而实现对Apache运行的方方面面进行控制。在Apache2.0中涉及到的配置文件包括下面的两种:

httpd.conf

httpd.conf是Apache中最重要的配置文件,通常位于$ServerRoot下的conf目录中。不过在一些特殊的发行版本中,可能并不是这个名字,比如在许多支持SSL的Apache二进制发行版本中都会将二进制文件命名为httdsd,与之对应,配置文件也相应的改名为httdsd.conf。不管名称如何,文件内部的指令都是一样的。Httpd.conf是默认的配置文件,一般情况下不建议对其进行修改,因此通常的建议是你重新拷贝一份,对该拷贝进行修改,因此这种情况下,你可以在指令行中使用-f参数来指定新的非默认的配置文件。
从Apache 1.3.13 起通过-f指令不仅可以指定配置文件,还可以指定配置目录,即,如果配置文件是一个目录,Apache会解析该目录及其子目录中的所有文件作为配置文件。一种可能的用途是,可以通过在这个目录中建立小的配置文件来设置虚拟主机,这样就可以简单地增加和删除虚拟主机,而不用修改其他任何文件,使类似操作的自动化容易了许多。
通常,在服务器启动的时候,该文件被读取处理一次,同时在每次重新启动的时候又会被处理一次,因此对配置文件的任何修改都要等待到服务器重启后才能生效

.htaccess

httpd.conf文件通常用于控制全局的配置信息,但是有的时候Apache需要提供目录级别的控制,比如定制特定目录被访问或者被列表显示等等。尽管httpd.conf内部提供了相关的目录配置指令,但是如果需要控制的目录数目较大的话,httpd.conf无疑会急剧膨胀。因此Apache中提供了另外的一种目录级别的配置,就是.htaccess。通常情况下,.htaccess文件位于需要进行控制的目录之内,因此系统中可能存在多个.htaccess。每个.htaccesss文件都有能力为它所处的目录以及所有的子目录设置授权、目录索引、过滤器以及其余的各种相关指令。因为.htaccess文件总是包含在用户自己的共享目录文档中,因此用户完全可以建立、更新和修改自己的.htaccess文件,而不需要直接去修改httpd.conf文件,从而可以保证httpd.conf的安全性,你要知道,每个人都去修改httpd.conf的话,造成的问题,你可能甚至都无法预料。

配置指令

由于Apache只定义了一些配置的框架和配置段规则,因此Apache配置文件的结构通常很容易理解。每个可用的指令以及指令的参数并不是由Apache核心决定的,而是由模块完全决定并实现和控制。
换句话说,一个Apache配置文件可能是一个空文件,或者是包含了一个或者多个配置的指令,每个指令包含指令名称以及指令所需要的参数。指令的名称唯一的标识该指令本身,指令参数差异性则很大,参数类型,参数的个数都不尽相同。
指令只是用于控制Apache的简单的命令而已,Apache从配置文件中读取这些指令,然后执行相应的操作从而实现执行这些指令。通过使用指令,Apache管理员可以控制整个Web服务器的行为。由于Apache中提供了种类繁多的指令,这些指令使得的Apache是一个高度可配置的Web服务器。
Apache的指令可以分为两种:简单指令以及配置段指令。配置段指令都是被包含在<…>中的指令,比如<Directory>…</Directory>。配置段指令总是会包含其余的指令。

指令规则

尽管从上面的语法我们可以看到Apache的指令的语法非常的复杂,但实际上却非常的简单。在Apache进行指令处理的时候,Apache将逐行的读取这些配置指令,如果某行不是空行,同时也不是一个注释行,那么Apache将该行的第一个单词视为指令字,后面的其余的单词全部算作参数。如果某个行以”/“结尾,则下一行视上一行的继续。
因此,Apache配置指令的规则可以概括如下:

  • 使用UNIX路径法则:在所有的路径中使用“/”代替DOS下的“/”作为路径的分隔符。
  • 所有的注释行以“#”开始,同时注释行必须在一行结束,如果一行注释容不下,下一行必须继续以“#”开始。注解不能出现在同一行指令的后边,必须在新的一行开始注解。
  • 配置指令对大小写不敏感,但是指令的参数(argument)通常是大小写敏感的。但建议对非关键字均小写,而关键字则使用匈牙利方法,比如ServerRoot、TypesConfig等等。
  • 每行只能配置一个参数,配置的基本格式为:参数 参数值
  • 如果指令过长,不能够在一行中完整地放置,此时需要分割成为多行,各个行之间用 / 进行组合。如果使用 / 字符,那么在反斜杠和行的末尾不能存在任何内容和字符,包括空格或者水平制表符。
  • 系统将忽略配置文件中多余的空白字符。

指令参数

从原则上讲指令的参数可以是任何的字符串,只要指令处理函数能够理解即可。不过对于一些常用的指令参数,Apache中有一些默认的规定。一般,指令名称后面可以跟一个或多个用空格分开的参数。如果参数中有空格,则必须用双引号括起来, 用方括号括起来的是可选的参数。如果一个参数可以取多个值,则各个可能的值用”|”分开。 应该原样输入的文字使用缺省的字体,而可变的必须按实际情况加以替换的会加强显示。 使用可变参数个数的指令以”…”结尾,以示最后一个参数可以重复。


常用指令

DocumentRoot

DocumentRoot,组成网络上可见的主文档树的根目录
语法:DocumentRoot directory-path
默认值: /usr/local/apache2/htdocs
模块:core
此指令设置了httpd伺服的目录。在没有使用类似Alias这样的指令的情况下,服务器会将请求中的**URL路径(即URL中主机名和端口后面的部分)**附加到DocumentRoot后面以构成指向文档的路径。该参数指定Apache服务器对外发布的html文档存放的路径,客户程序请求的URL就被映射为这个目录下的网页文件。
比如说:DocumentRoot /usr/web
于是对http://www.my.host.com/index.html的访问就会指向/usr/web/index.html
这个目录下的子目录,以及使用符号连接指出的文件和目录都能被浏览器访问,只是要在URL上使用同样的相对目录名。
如果directory-path不是绝对路径,则被假定为是相对于ServerRoot的路径。
指定DocumentRoot时不应包括最后的”/“。


Alias

Alias,映射URL到文件系统的特定区域。
语法:Alias URL-path file-path|directory-path
模块:mod_alias
Alias指令使文档可以被存储在DocumentRoot以外的本地文件系统中。以(%已解码的)url-path路径开头的URL可以被映射到以directory-path开头的本地文件。
示例:Alias /image /ftp/pub/image
对”http://myserver/image/foo.gif" 的请求,服务器将返回”/ftp/pub/image/foo.gif”文件。因为仅匹配完整路径,所以上述例子不会匹配对”http://myserver/imagefoo.gif" 的请求。对于使用正则表达式的匹配,请参见AliasMatch指令。
注意:如果url-path中有后缀”/“,则服务器要求有后缀”/“以扩展此别名。也就是说”Alias /icons/ /usr/local/apache/icons/“并不能对”/icons”实现别名。
如果对在DocumentRoot之外的某个目录建立了一个Alias ,则可能需要通过段明确的对目标目录设定访问权限。
示例:

Alias /image /ftp/pub/image
<Directory /ftp/pub/image>
    Order allow,deny
    Allow from all
</Directory>

Redirect,URL重定向

Redirect,发送一个外部重定向使客户端重定向到一个不同的URL
语法:Redirect [status] URL-path URL
模块:mod_alias
该指令将一个老URL映射为一个新URL,此新URL被返回到客户端使之重定向到一个新地址。
老URL-path是一个(%已解码的)以”/“开头的(网络空间)绝对路径。新URL是一个(%已编码的)以”/“开头的(网络空间)绝对路径或者包含协议名和主机名的完整URL。当新URL不包含协议名和主机名时将使用与老URL-path相同的当前值
这样,对任何以老URL-path开头的请求,将返回一个指向以新URL开头的重定向应答。
示例:Redirect /service http://foo2.example.com/service
如果客户端请求”http://example.com/service/foo.txt" ,则会被重定向到”http://foo2.example.com/service/foo.txt" 。因为仅匹配完整路径,所以上述例子不会匹配”http://example.com/servicefoo.txt" 请求。对于使用正则表达式的匹配,请参见RedirectMatch指令。
注意:重定向指令总是优先于Alias和ScriptAlias指令,而无论他们在配置文件中的顺序如何。
如果没有指定status参数,则重定向是”临时的”(HTTP status 302)。也就是对客户端来说,此资源的位置变动是临时性的。此status参数可以返回以下HTTP状态码:

  • permanent
    返回一个永久性重定向状态码(301),表示此资源的位置变动是永久性的。
  • temp
    返回一个临时性重定向状态码(302),这是默认值。
  • seeother
    返回一个”参见”状态码(303),表示此资源已经被替代。
  • gone
    返回一个”已废弃”状态码(410),表示此资源已经被永久性地删除了。如果指定了这个状态码,则URL参数将被忽略。
    status可以被指定为数字状态以返回其他状态码。如果此状态在300-399之间,则必须提供URL参数,否则将被忽略。注意,此状态码必须是Apache已知的(参见http_protocol.c中的send_error_response函数)。

示例:
Redirect permanent /one http://example.com/two
Redirect 303 /three http://example.com/other


ProxyPass,反向代理

ProxyPass,将一个远端服务器映射到本地服务器的URL空间中
语法:ProxyPass [path] !|url [key=value key=value …]]
模块:mod_proxy
该指令允许你将一个远端服务器映射到本地服务器的URL空间中,此时本地服务器并不充当代理角色,而是充当远程服务器的一个镜像。path是一个本地虚拟路径名,url是一个指向远程服务器的部分URL,并且不允许包含查询字符串。
注意:当使用ProxyPass指令时,ProxyRequests指令通常应当被设为 off 。
假设本地服务器地址是:http://example.com/ ,那么,
ProxyPass /mirror/foo/ http://backend.example.com/
将会导致对http://example.com/mirror/foo/bar 的本地请求将会在内部转换为一个代理请求:http://backend.example.com/bar

“!”指令对于您不想对某个子目录进行反向代理时很有用。比如说:
ProxyPass /mirror/foo/i !
ProxyPass /mirror/foo http://backend.example.com
将会代理除/mirror/foo/i之外的所有对backend.example.com下/mirror/foo的请求。

注意:顺序很重要,您需要把拒绝指令放置在普通ProxyPass指令之前


NameVirtualHost

NameVirtualHost,为一个基于域名的虚拟主机指定一个IP地址(和端口)
语法:NameVirtualHost addr[:port]
模块:core

如果您要配置基于域名的虚拟主机,NameVirtualHost指令就是您必须的指令之一。
尽管addr参数可以使用主机名,但建议您还是使用IP地址。比如:NameVirtualHost 111.22.33.44

使用NameVirtualHost指令,您可以指定一个基于域名的虚拟主机将使用哪个IP地址来接受请求。在一个防火墙或是其它代理接受了请求并把它转到服务器所在的另外一个IP地址上的情况下,您必须指定伺服请求的机器物理界面上的IP地址。如果您对于多个地址使用了多个基于域名的虚拟主机,您应该为每个地址使用这个指令。

注意:”主服务器”和任何其它”default“服务器都不会伺服发送到NameVirtualHost IP地址的请求。(除非您指定了NameVirtualHost,但没有为这个地址指定任何VirtualHost)。

另外,您还可以为您使用的基于域名的虚拟主机指定一个端口号。比如:
NameVirtualHost 111.22.33.44:8080
IPv6地址必须封装在一对方括号内,如下例所示:
NameVirtualHost [2001:db8::a00:20ff:fea7:ccea]:8080
为了接受所有界面的请求,您可以使用”*”:
NameVirtualHost *

请注意,**<VirtualHost>指令的参数必须与NameVirtualHost指令的参数完全匹配**。例如:

NameVirtualHost 1.2.3.4
<VirtualHost 1.2.3.4>
    # ...
</VirtualHost>

VirtualHost

<VirtualHost>,包含仅作用于指定主机名或IP地址的指令
语法:<VirtualHost addr[:port] [addr[:port]] ...> ... </VirtualHost>
模块:core
<VirtualHost></VirtualHost>用于封装一组仅作用于特定虚拟主机的指令。任何在虚拟主机配置中可以使用的指令也同样可以在这里使用。当服务器接受了一个特定虚拟主机的文档请求时,它会使用封装在<VirtualHost>配置段中的指令。
Addr可以是:

  • 虚拟主机的IP地址
  • 虚拟主机IP地址对应的完整域名
  • 字符”*“,仅与”NameVirtualHost *”配合使用以匹配所有的IP地址
  • 字符串_default_,与基于IP的虚拟主机联用以捕获所有没有匹配的IP地址

示例

<VirtualHost 10.1.2.3>
    ServerAdmin webmaster@host.foo.com
    DocumentRoot /www/docs/host.foo.com
    ServerName host.foo.com
    ErrorLog logs/host.foo.com-error_log
    TransferLog logs/host.foo.com-access_log
</VirtualHost>

IPv6的地址必须放入方括号中指定,否则作为可选项的端口号将无法确定。一个IPv6的示例如下:

<VirtualHost [2001:db8::a00:20ff:fea7:ccea]>
    ServerAdmin webmaster@host.example.com
    DocumentRoot /www/docs/host.example.com
    ServerName host.example.com
    ErrorLog logs/host.example.com-error_log
    TransferLog logs/host.example.com-access_log
</VirtualHost>

每个虚拟主机必须对应不同的IP地址、端口号或是不同的主机名。在第一种情况下,服务器所在的物理机器必须配置为可以为多个IP地址接受IP包。(在机器没有多个网络硬件界面的情况下,如果您的操作系统支持,您可以使用 ifconfig alias 命令来达到这个目的)。

注意:**<VirtualHost>的使用并不影响Apache的监听地址。你需要使用Listen来确保Apache正在监听正确的地址**。
当使用基于IP的虚拟主机时,特殊的名称”default“可以在没有匹配到其它列出的虚拟主机的情况下作为匹配任何IP地址的默认虚拟主机。在没有进行”default“虚拟主机的设定时,在没有IP与请求匹配的情况下,将使用”主服务器”(在所有虚拟主机配置段之外)的配置。但请注意:任何匹配NameVirtualHost指令的IP地址既不会使用”主服务器”配置,也不会使用”default“虚拟主机的配置。参见基于域名的虚拟主机文档。

您可以指定一个”:port”来改变匹配的端口。如果没有指定,它将沿用主服务器中离它最近的那个Listen指定的值。您也可以指定”:*”来匹配那个地址上的所有端口(当您使用”default“时,这是推荐采用的方法)。


虚拟主机

术语”虚拟主机”是指在一个机器上运行多个网站(比如: www.company1.comwww.company2.com )。如果每个网站拥有不同的IP地址,则虚拟主机可以是”基于IP”的;如果只有一个IP地址,也可以是”基于主机名”的,其实现对最终用户是透明的。

Apache是率先支持基于IP的虚拟主机的服务器之一。1.1及其更新版本同时支持基于IP和基于主机名的虚拟主机。

基于IP地址的虚拟主机

系统需求
就像它的名字”基于IP”所暗示的那样,这样的服务器中每个基于IP的虚拟主机必须拥有不同的IP地址。可以通过配备多个真实的物理网络接口来达到这一要求,也可以使用几乎所有流行的操作系统都支持的虚拟界面来达到这一要求(详情请参见您的系统文档,这种功能一般被称作”IP别名”,一般用”ifconfig”命令来进行设置)。

如何配置Apache
有两种配置方法来使apache支持多主机:为每个虚拟主机运行不同的httpd守护进程;或者用同一个守护进程来支持所有虚拟主机。

以下情况使用多个守护进程:

  • 出于安全的考虑,比如说公司甲不希望公司乙的任何人能用除web以外的方式访问到他们的数据。在这种情况下,您需要启动两个守护进程。每个进程都使用不同的User, Group, Listen, ServerRoot设置。
  • 您能够为机器上的每个IP地址提供内存和文件描述符需求。您只能Listen一个”通配符型”地址或一个特定的地址。所以不管出于什么原因,如果您需要侦听一个特定的地址,您就必须同时侦听所有特定的地址。(尽管可以让一个httpd侦听N-1个地址,而让另一个侦听剩下的地址)

以下情况使用单一守护进程:

  • httpd的配置可以为多个虚拟主机共享而不引起麻烦。
  • 机器要接受大量的访问请求,从而多启动一个守护进程会导致性能大幅度降低。

设置多个守护进程
为每个虚拟主机创建一个不同的httpd安装。每次安装都在配置文件中使用Listen指令指定守护进程伺服的IP地址(或虚拟主机)。比如:
Listen www.smallco.com:80
建议您使用IP地址来取代域名(理由请参见关于DNS和Apache)。

配置拥有多个虚拟主机的单一守护进程
在这种情况下,单一的httpd将伺服所有对主服务器和虚拟主机的请求。而配置文件中的VirtualHost指令将为每个虚拟主机配置不同的ServerAdmin, ServerName, DocumentRoot, ErrorLog, TransferLog, CustomLog 。例如:

<VirtualHost www.smallco.com>
    ServerAdmin webmaster@mail.smallco.com
    DocumentRoot /groups/smallco/www
    ServerName www.smallco.com
    ErrorLog /groups/smallco/logs/error_log
    TransferLog /groups/smallco/logs/access_log
</VirtualHost>

<VirtualHost www.baygroup.org>
    ServerAdmin webmaster@mail.baygroup.org
    DocumentRoot /groups/baygroup/www
    ServerName www.baygroup.org
    ErrorLog /groups/baygroup/logs/error_log
    TransferLog /groups/baygroup/logs/access_log
</VirtualHost>

建议您使用IP地址来取代域名(理由请参见关于DNS和Apache)。

除了创建进程的指令和其他一些指令外,几乎所有的配置指令都能用于<VirtualHost>指令中。您可以使用指令索引在作用域中查询一个指令是否可以用于<VirtualHost>指令。如果使用了suEXEC包装,那么SuexecUserGroup指令也可以在<VirtualHost>段中使用。

安全警示:当指定日志文件时,请记住有安全风险。一些别有用心的人会在那个目录拥有写权限。请参见安全方面的提示获取详情。


基于主机名的虚拟主机

与基于IP的虚拟主机比较

基于IP的虚拟主机使用连接的IP地址来决定相应的虚拟主机。这样,你就需要为每个虚拟主机分配一个独立的IP地址。而基于域名的虚拟主机是根据客户端提交的HTTP头中标识主机名的部分(Host头)决定的。使用这种技术,很多虚拟主机可以共享同一个IP地址。

基于域名的虚拟主机相对比较简单,因为你只需要配置你的DNS服务器将每个主机名映射到正确的IP地址,然后配置Apache HTTP服务器,令其辨识不同的主机名就可以了。基于域名的服务器也可以缓解IP地址不足的问题。所以,如果没有特殊原因使你必须使用基于IP的虚拟主机,您最好还是使用基于域名的虚拟主机。下列情况下,你可能会想要使用基于IP的虚拟主机:

  • 一些古董级的客户端与基于域名的虚拟主机不兼容。为了与基于域名的虚拟主机兼容,客户端必须发送”Host”头。HTTP/1.1规范中对此做了要求。而所有现在常见的仅支持HTTP/1.0的旧版本浏览器都以附加的方式实现了这个要求。如果你又想支持这些老浏览器,又想使用基于域名的虚拟主机。我们提供了一个技术方案,你可以在本文末尾看到它。
  • SSL协议先天特性决定了基于域名的虚拟主机无法成为SSL安全服务器。
  • 一些操作系统和网络设备实现的带宽管理技术无法在多个主机共享一个IP的情况下区别它们。
使用基于域名的虚拟主机
  • 第一步:指定虚拟主机接受的IP及端口
    为了使用基于域名的虚拟主机,你必须指定服务器IP地址(和可能的端口)来使主机接受请求,这个可以用NameVirtualHost指令来进行配置。如果服务器上所有的IP地址都会用到,你可以用”*“作为NameVirtualHost的参数。如果你打算使用多端口(如运行SSL)你必须在参数中指定一个端口号,比如”*:80”。请注意,在NameVirtualHost指令中指定IP地址并不会使服务器自动侦听那个IP地址。请参阅设置Apache使用的地址和端口一章获取更多详情。另外,这里设定的IP地址必须对应服务器上的一个网络接口。

  • 第二步:建立<VirtualHost>
    下一步就是为每个虚拟主机建立<VirtualHost>段。**<VirtualHost>的参数与NameVirtualHost的参数必须是一样的**(比如说,一个IP地址或”*”代表的所有地址)。在每个<VirtualHost>段中,至少要有一个ServerName指令来指定伺服哪个主机和一个DocumentRoot指令来说明这个主机的内容位于文件系统的什么地方。

取消中心主机(Mainhost)
如果你想在现有的web服务器上增加虚拟主机,你必须也为现存的主机建造一个<VirtualHost>定义块。这个虚拟主机中ServerName和DocumentRoot所包含的内容应该与全局的ServerName和DocumentRoot保持一致。还要把这个虚拟主机放在配置文件的最前面,来让它扮演默认主机的角色。
比如说,假设你正在为域名www.domain.tld提供服务,而你又想在同一个IP地址上增加一个名叫www.otherdomain.tld的虚拟主机,你只需在httpd.conf中加入以下内容:

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName www.domain.tld
    ServerAlias domain.tld *.domain.tld
    DocumentRoot /www/domain
</VirtualHost>

<VirtualHost *:80>
    ServerName www.otherdomain.tld
    DocumentRoot /www/otherdomain
</VirtualHost>

当然,你可以用一个固定的IP地址来代替NameVirtualHost和<VirtualHost>指令中的”*”号,以达到一些特定的目的。比如说,你可能会希望在一个IP地址上运行一个基于域名的虚拟主机,而在另外一个IP地址上运行一个基于IP的或是另外一套基于域名的虚拟主机。

虚拟主机别名
很多服务器希望自己能通过不只一个域名被访问。我们可以把ServerAlias指令放入<VirtualHost>小节中来解决这个问题。比如说在上面的第一个<VirtualHost>配置段中ServerAlias指令中列出的名字就是用户可以用来访问同一个web站点的其它名字:
ServerAlias domain.tld *.domain.tld
这样,所有对域domain.tld的访问请求都将由虚拟主机www.domain.tld处理。通配符标记"\*"和"?"可以用于域名的匹配。当然你不能仅仅搞个名字然后把它放到ServerName或ServerAlias里就算完了。你**必须先在你的DNS服务器上进行配置,将这些名字和您服务器上的一个IP地址建立映射关系**。

最后,你可以把其他一些指令放入<VirtualHost>段中,以更好的配置一个虚拟主机。大部分指令都可以放入这些<VirtualHost>段中以改变相应虚拟主机配置。如果您想了解一个特定的指令是否可以这样运用,请参见指令的作用域。主服务器(main server)范围内的配置指令(在所有<VirtualHost>配置段之外的指令)仅在它们没有被虚拟主机的配置覆盖时才起作用

配置虚拟主机后的处理流程
这样,当一个请求到达的时候,服务器会首先检查它是否使用了一个能和NameVirtualHost相匹配的IP地址。如果能够匹配,它就会查找每个与这个IP地址相对应的<VirtualHost>段,并尝试找出一个与请求的主机名相同的ServerName或ServerAlias配置项。如果找到了,它就会使用这个服务器。否则,将使用符合这个IP地址的第一个列出的虚拟主机

综上所述,第一个列出的虚拟主机充当了默认虚拟主机的角色。当一个IP地址与NameVirtualHost指令中的配置相符的时候,主服务器中的DocumentRoot将永远不会被用到。所以,如果你想创建一段特殊的配置用于处理不对应任何一个虚拟主机的请求的话,你只要简单的把这段配置放到<VirtualHost>段中,并把它放到配置文件的最前面就可以了。


ServerRoot

ServerRoot,安装服务器的根目录。
语法:ServerRoot directory-path
默认值:ServerRoot /usr/local/apache
模块:core
ServerRoot指令设置了服务器所在的目录。一般来说它将包含conf/和logs/子目录,其它配置文件的相对路径即基于此目录 (比如Include或LoadModule)。默认为安装目录,不需更改。
ServerRoot用于指定守护进程httpd的运行目录,httpd在启动之后将自动将进程的当前目录改变为这个目录,因此如果设置文件中指定的文件或目录是相对路径,那么真实路径就位于这个ServerRoot定义的路径之下。
注意,此指令中的路径最后不要加/

ServerName

ServerName,设置服务器用于辨识自己的主机名和端口号。
语法:ServerName [scheme://]fully-qualified-domain-name[:port]
模块:core
ServerName指令设置了服务器用于辨识自己的主机名和端口号。这主要用于创建重定向URL。比如,一个放置web服务器的主机名为simple.example.com ,但同时有一个DNS别名www.example.com 。而您希望web服务器更显著一点,您可以使用如下的指令:
ServerName www.example.com:80
当没有指定ServerName时,服务器会尝试对IP地址进行反向查询来推断主机名。如果在ServerName中没有指定端口号,服务器会使用接受请求的那个端口。
可选的’scheme://‘前缀仅在2.2.3以后的版本中可用,用于在代理之后或离线设备上也能正确的检测规范化的服务器URL。
为了加强可靠性和可预测性,建议使用ServerName显式的指定一个主机名和端口号。
如果使用的是基于域名的虚拟主机,在<VirtualHost>段中的ServerName将是为了匹配这个虚拟主机,在”Host:”请求头中必须出现的主机名

ServerAlias

ServerAlias,匹配一个基于域名的虚拟主机的别名
语法:ServerAlias hostname [hostname] …
模块:core
ServerAlias指令设定主机的别名,用于基于域名的虚拟主机。例如:

<VirtualHost *>
ServerName server.domain.com
ServerAlias server server2.domain.com server2
# ...
</VirtualHost>

ServerAdmin

ServerAdmin,服务器返回给客户端的错误信息中包含的管理员邮件地址
语法:ServerAdmin email-address|URL
模块:core
ServerAdmin设置了在所有返回给客户端的错误信息中包含的管理员邮件地址。如果httpd不能将提供的参数识别为URL,它就会假定它是一个email-address ,并在超连接中用在mailto:后面。推荐使用一个Email地址,因为许多CGI脚本是这样认为的。如果你确实想使用URL,一定要保证指向一个你能够控制的服务器,否则用户将无法确保一定可以和你取得联系。
为这个目的专门设置一个邮箱是值得的,比如:
ServerAdmin www-admin@foo.example.com
因为用户一般不会注意到他们在讨论服务器的问题!


Listen

Listen,指定服务器监听的IP地址和端口
语法:Listen [IP-address:]portnumber [protocol]
模块:beos, mpm_netware, mpm_winnt, mpmt_os2, prefork, worker, event
Listen指令指示Apache只在指定的IP地址和端口上监听;默认情况下Apache会在所有IP地址上监听。
Listen是一个必须设置的指令。如果在配置文件中找不到这个指令,服务器将无法启动。这和先前的版本不一样。
Apache2.0以后必须设置该指令,protocol参数仅在2.1.5及以后版本中可用。

Listen指令指定服务器在那个端口或地址和端口的组合上监听接入请求。如果只指定一个端口,服务器将在所有地址上监听该端口。如果指定了地址和端口的组合,服务器将在指定地址的指定端口上监听。
使用多个Listen指令可以指定多个不同的监听端口和/或地址端口组合。服务器将会对列出的所有端口和地址端口组合上的请求作出应答。
例如,想要服务器接受80和8000端口上的请求,可以这样设置:
Listen 80
Listen 8000
为了让服务器在两个确定的地址端口组合上接受请求,可以这样设置:
Listen 192.170.2.1:80
Listen 192.170.2.5:8000
IPv6地址必须像下面的例子一样,用方括号括起来:
Listen [2001:db8::a00:20ff:fea7:ccea]:80

可选的protocol参数在大多数情况下并不需要。若未指定该参数,则将为443端口使用默认的https协议,为其它端口使用http协议。在这里指定协议是为了确定使用哪个模块来处理请求,以及根据AcceptFilter指令根据不同的协议有针对性的进行优化。
仅在使用非标准端口时才需要指定protocol参数。比如在8443端口运行https协议:
Listen 192.170.2.1:8443 https

错误条件
多个Listen指令指定了同一个地址和端口的组合后,会导致”Address already in use”错误。

地址和端口的绑定(Binding)

Apache启动时,会绑定本机上的地址和端口,然后等待请求的进入。默认情况下,它会监听本机的所有地址。但是,当需要监听特定的地址或端口或地址与端口的组合,或者需要对不同的IP地址、主机名、端口作出不同的响应(如使用虚拟主机)时,就必须明确指定。
Listen指令告诉服务器接只受来自特定端口(或地址+端口的组合)的请求。如果Listen指令仅指定了端口,则服务器会监听所有的IP地址;如果指定了地址+端口的组合,则服务器只监听来自此特定地址上特定端口的请求。使用多个Listen指令,可以指定在多个地址和端口上进行监听。

与虚拟主机协同工作

Listen指令并不实现虚拟主机,它只是告诉主服务器(main server)去监听哪些地址和端口。如果没有<VirtualHost>指令,服务器将对所有请求一视同仁;但是如果有<VirtualHost>指令,则服务器会对不同的地址或端口作出不同的响应。要实现虚拟主机,首先必须告诉服务器需要监听哪些地址和端口,然后为每个特定的地址和端口建立一个<VirtualHost>段来执行特定的相应。注意,如果将<VirtualHost>段设置为服务器没有监听的地址和端口,则此段无效


LoadModule

LoadModule,加载目标文件或库,并将其添加到活动模块列表。动态加载特定的DSO(Dynamic Shared Object)模块。
语法:LoadModule module filename
模块:mod_so
该指令加载目标文件或库filename并将模块结构名module添加到活动模块列表。module就是源代码文件中用于拼写module的外部变量名,并作为模块标识符(Module Identifier)列在模块文档中。
如:LoadModule status_module modules/mod_status.so
加载了位于ServerRoot下模块目录中指定的模块。
如果filename使用相对路径,则路径是相对于ServerRoot所指示的相对路径。
默认配置文件已加载所有已编译的DSO模块。

IfModule

<IfModule>,封装指令并根据指定的模块是否启用为条件而决定是否进行处理
语法:<IfModule [!]module-file|module-identifier> ... </IfModule>
模块:core
<IfModule test>...</IfModule>配置段用于封装根据指定的模块是否启用而决定是否生效的指令。在<IfModule>配置段中的指令仅当test为真的时候才进行处理。如果test为假,所有其间的指令都将被忽略。
<IfModule>段中的test可以为以下两种方式之一:

  • module,起始和结束标记之间的指令仅当module被载入后才被执行。此模块可以为编译时静态链接进核心的模块或是使用LoadModule指令动态载入的模块。
  • !module,仅当module没有载入时才进行指令的处理。

module可以是模块的标识符或者是编译模块时的文件名。比如,rewrite_module就是一个模块标识符,而mod_rewrite.c则是编译模块时的文件名。如果模块包含多个源代码文件,您应当使用包含STANDARD20_MODULE_STUFF字符串的那个。
<IfModule>配置段是可以嵌套的,从而可以实现简单的多模块测试。
此配置段主要用于需要根据某个特定的模块是否存在来决定是否使用某些配置的时候。指令一般都放在<IfModule>配置段中。


Directory

<Directory>,封装一组指令,使之仅对文件空间中的某个目录及其子目录生效
语法:<Directory directory-path> ... </Directory>
模块:core
<Directory></Directory>用于封装一组指令,使之仅对某个目录及其子目录生效。任何可以在”directory”作用域中使用的指令都可以使用。Directory-path可以是一个目录的完整路径,或是包含了Unix shell匹配语法的通配符字符串。在通配符字符串中,”?”匹配任何单个的字符,”*”匹配任何字符序列。您也可以使用”[]”来确定字符范围。以上通配符都不能匹配”/“字符。所以<Directory /*/public_html>将无法匹配/home/user/public_html ,但<Directory /home/*/public_html>能够正确匹配。

注意:使用directory-path参数的时候要注意:它们必须与Apache用于访问文件的文件系统路径保持一致。赋予特定的指令将无法对通过不同路径指向的同一个目录文件生效,比如说通过另外一个符号连接生成的路径。

也可以附加”~”字符来表示使用正则表达式。比如说:
<Directory ~ "^/www/(.+/)*[0-9]{3}">
将匹配/www/下所有由3个数字组成的目录。

如果有多个(非正则表达式)<Directory>配置段符合包含某文档的目录(或其父目录),那么指令将以短目录优先的规则进行应用。并包含.htaccess文件中的指令。比如说在

<Directory />
    AllowOverride None
</Directory>

<Directory /home/>
    AllowOverride FileInfo
</Directory>

中,访问文档/home/web/dir/doc.html的步骤如下:

  • 应用指令AllowOverride None(禁用.htaccess文件)。
  • 应用指令AllowOverride FileInfo(针对/home目录)。
  • 按顺序应用所有/home/.htaccess 、/home/web/.htaccess 、/home/web/dir/.htaccess中的FileInfo组指令。

正则表达式将在所有普通配置段之后予以考虑。所有的正则表达式将根据它们出现在配置文件中的顺序进行应用。比如说,以下配置:

<Directory ~ abc$>
    # ......
</Directory>

正则表达式配置段将在所有普通的<Directory>和.htaccess文件应用之后才予以考虑。所以正则表达式将匹配/home/abc/public_html/abc并予以应用。

针对Directory /的安全提示
请注意:Apache对<Directory />的默认访问权限为”Allow from All”。这意味着Apache将伺服任何通过URL映射的文件。我们建议您将这个配置做如下屏蔽:

<Directory />
    Order Deny,Allow
    Deny from All
</Directory>

然后在您想要使之被访问的目录中覆盖此配置。参阅安全提示以获取更多详情。

<Directory>指令不可被嵌套使用,也不能出现在<Limit><LimitExcept>配置段中。


Location

<Location>,将封装的指令作用于匹配的URL
语法:<Location URL-path|URL> ... </Location>
模块:core

<Location>提供了基于URL的访问控制。与<Directory>指令类似,它也会启用一个以</Location>结尾的配置段。<Location>配置段的处理位于<Directory>, .htaccess, <Files>之后,并依照在配置文件中出现的顺序进行处理

<Location>配置段完全独立于文件系统之外操作。这有几个重要的后果。最重要的是<Location>不能用于针对文件系统的访问控制。因为可能会有几个不同的URL指向文件系统中的同一个文件,所以这样的控制常常会被很容易的绕过。
何时使用<Location>?使用<Location>来将指令应用于独立于文件系统之外的内容。文件系统之内的内容请使用<Directory><Files>指令。不过一个例外是<Location /> ,它可以方便的作用于所用URL。

对所有的原始(非代理)请求来说,匹配的URL应该是具有”/path/“形式的URL路径。不包括访问方法、主机名、端口或查询字符串等。对于代理的请求,匹配的URL必须为”scheme://servername/path”的形式,而且必须包括前缀。

URL可以用一个通配符字符串来进行通配符的处理。”?”匹配任何单个的字符,而”*”匹配所有字符序列。

也可以附加”~”字符来表示使用正则表达式。例如:
<Location ~ "/(extra|special)/data">
将匹配所有包含字符串”/extra/data”或”/special/data”的URL。在Apache1.3及其后续版本中,加入了一个新的推荐使用的<LocationMatch>指令,其功能与<Location>的正则表达式版本相同。

与SetHandler指令联用
<Location>的功能在与SetHandler指令联用时能发挥最大效能。比如启用状态请求,但仅对来自foo.com的用户起效,您可以这样使用:

<Location /status>
    SetHandler server-status
    Order Deny,Allow
    Deny from all
    Allow from .foo.com
</Location>

请注意连续”/“(斜线)的匹配
斜线字符根据它在URL中出现的位置不同有着特殊的意义。大家可能都已经习惯在文件系统中,多个连续的斜线会被作为单一的斜线处理(例如”/home///foo”与”/home/foo”相同)。但在URL里面,这样是行不通的。<LocationMatch>指令和正则表达式版本的<Location>要求您明确使用多重斜线。比如:<LocationMatch ^/abc>将匹配请求”/abc”但不会匹配请求”//abc”。而非正则表达式版本的<Location>指令在用于代理请求时,也有类似表现。但当非正则表达式版本的<Location>作用于非代理请求时,它会将多个毗邻的斜线认作单个斜线。比如,如果您指定了<Location /abc/def>而请求是指向”/abc//def”的,那么它们就是匹配的。


SetHandler

SetHandler,强制所有匹配的文件被一个指定的处理器处理
语法:SetHandler handler-name|None
模块:core
当这个指令放入.htaccess或<Directory><Location>配置段中时,这个指令将强制所有匹配的文件通过handler-name指定的处理器处理。比如:如果想不管某个目录中的文件具有什么扩展名,都将它作为图像映射规则文件来解析,您可以将下例放入那个目录的.htaccess中:
SetHandler imap-file
再来一个例子:如果您想当http://servername/status 被请求时,服务器显示一个状态报告,您可以将下面的语句放入httpd.conf里面:

<Location /status>
    SetHandler server-status
</Location>

你可以通过使用 None 来改写一个早先定义的SetHandler指令。


  • User,设置实际提供服务的子进程的用户。
    为了使用这个指令,服务器必须以root身份启动和初始化。如果你以非root身份启动服务器,子进程将不能够切换至非特权用户,并继续以启动服务器的原始用户身份运行。如果确实以root用户启动了服务器,那么父进程将仍然以root身份运行。
    用于运行子进程的用户必须是一个没有特权的用户,这样才能保证子进程无权访问那些不想为外界所知的文件,同样的,该用户亦需没有执行那些不应当被外界执行的程序的权限。
    强烈建议专门为Apache子进程建立一个单独的用户和组。

  • Group,设置提供服务的Apache子进程运行时的用户组。
    为了使用这个指令,Apache必须以root初始化启动,否则在切换用户组时会失败,并继续以初始化启动时的用户组运行。

  • Options,控制在特定目录中将使用哪些服务器特性
    语法:Options [+|-]option [[+|-]option] …
    一般来说,如果一个目录被多次设置了Options ,则最特殊的一个会被完全接受(其它的被忽略),而各个可选项的设定彼此并不融合。然而,如果所有作用于Options指令的可选项前都加有”+” 或”-“符号,此可选项将被合并。所有前面加有”+”号的可选项将强制覆盖当前的可选项设置,而所有前面有”-“号的可选项将强制从当前可选项设置中去除。
    option可以为None,不启用任何额外特性,或者下面选项中的一个或多个:

  • All  除MultiViews之外的所有特性,这是默认设置。

  • ExecCGI  允许使用mod_cgi执行CGI脚本。

  • FollowSymLinks  服务器允许在此目录中使用符号连接,如果此配置位于<Location>配置段中,则会被忽略。

  • Includes  允许使用mod_include提供的服务器端包含。

  • IncludesNOEXEC  允许服务器端包含,但禁用”#exec cmd”和”#exec cgi”,但仍可以从ScriptAlias目录使用”#include virtual”虚拟CGI脚本。

  • Indexes  如果一个映射到目录的URL被请求,而此目录中又没有DirectoryIndex(例如:index.html),那么服务器会返回由mod_autoindex生成的一个格式化后的目录列表。

  • MultiViews  允许使用mod_negotiation提供内容协商的”多重视图”(MultiViews)。

  • SymLinksIfOwnerMatch  服务器仅在符号连接与其目的目录或文件的拥有者具有相同的uid时才使用它。 如果此配置出现在配置段中,则将被忽略。

  • AllowOverride,确定允许存在于.htaccess文件中的指令类型。
    语法:AllowOverride All|None|directive-type [directive-type] …
    AllowOverride仅在不包含正则表达式的<Directory>配置段中才是有效的。在<Location>, <DirectoryMatch>, <Files>配置段中都是无效的。
    如果此指令被设置为None ,那么.htaccess文件将被完全忽略。事实上,服务器根本不会读取.htaccess文件。
    当此指令设置为All时,所有具有”.htaccess”作用域的指令都允许出现在.htaccess文件中。
    directive-type可以是下列各组指令之一:

  • AuthConfig  允许使用与认证授权相关的指令

  • FileInfo  允许使用控制文档类型的指令、控制文档元数据的指令、mod_rewrite中的指令、mod_actions中的Action指令

  • Indexes  允许使用控制目录索引的指令

  • Limit  允许使用控制主机访问的指令

  • Options[=Option,…]  允许使用控制指定目录功能的指令(Options和XBitHack)。可以在等号后面附加一个逗号分隔的(无空格的)Options选项列表,用来控制允许Options指令使用哪些选项。

  • Order,控制默认的访问状态与Allow和Deny指令生效的顺序。
    语法:Order Ordering
    Ordering取值范围是以下几种范例之一:
    关键字只能用逗号分隔,它们之间不能有空格,在所有情况下每个Allow和Deny指令语句都将被评估。

  • Deny,Allow  Deny指令在Allow指令之前被评估。默认允许所有访问。任何不匹配Deny指令或者匹配Allow指令的客户都被允许访问。

  • Allow,Deny  Allow指令在Deny指令之前被评估。默认拒绝所有访问。任何不匹配Allow指令或者匹配Deny指令的客户都将被禁止访问。

  • Mutual-failure  只有出现在Allow列表并且不出现在Deny列表中的主机才被允许访问。这种顺序与”Order Allow,Deny”具有同样效果,不赞成使用。

  • Allow,控制哪些主机可以访问服务器的该区域。可以根据主机名、IP地址、 IP地址范围或其他环境变量中捕获的客户端请求特性进行控制。
    语法:Allow from all|host|env=env-variable [host|env=env-variable] …
    这个指令的第一个参数总是”from”,随后的参数可以有三种不同形式:

  • 如果指定”Allow from all”,则允许所有主机访问,按照下述Deny和Order指令的配置;

  • 若要只允许特定的主机或主机群访问服务器,host可以用下面任何一种格式来指定:一个(部分)域名、完整的IP地址、部分IP地址、网络/掩码、网络/nnn无类别域间路由规格;

  • 第三种参数格式允许对服务器的访问由环境变量的一个扩展指定,指定”Allow from env=env-variable”时,如果环境变量env-variable存在则访问被允许,使用由mod_setenvif提供的指令,服务器用一种基于客户端请求的弹性方式提供了设置环境变量的能力。因此,这条指令可以用于允许基于像User-Agent(浏览器类型)、Referer或其他 HTTP请求头字段的访问。

  • Deny,控制哪些主机被禁止访问服务器的该区域。可以根据主机名、IP地址、 IP地址范围或其他环境变量中捕获的客户端请求特性进行控制。
    语法:Deny from all|host|env=env-variable [host|env=env-variable] …
    此指令的参数设置和Allow指令完全相同。

  • DirectoryIndex,当客户端请求一个目录时寻找的资源列表。
    语法:DirectoryIndex Local-url [Local-url] …
    Local-url(%已解码的)是一个相对于被请求目录的文档的URL(通常是那个目录中的一个文件)。可以指定多个URL,服务器将返回最先找到的那一个,比如:
    DirectoryIndex index.html index.php

  • DefaultType,在服务器无法由其他方法确定内容类型时,发送的默认MIME内容类型。
    语法:DefaultType MIME-type
    默认:DefaultType text/plain

  • Include,在服务器配置文件中包含其它配置文件。
    语法:Include file-path|directory-path
    文件的路径可以是一个完整的绝对路径(以一个斜杠开头),或是相对于ServerRoot目录的相对路径。
    Shell风格(fnmatch())的通配符可以用于按照字母顺序一次包含多个文件。另外,如果Include指向了一个目录而不是一个文件,Apache将读入该目录及其子目录下的所有文件,并依照字母顺序将这些文件作为配置文件进行解析。但是并不推荐这么做,因为偶尔会有临时文件在这个目录中生成,从而导致httpd启动失败。

  • PidFile,默认值为 /var/run/apache.pid
    指定记录httpd配置文件守护进程的进程号的文件。由于httpd配置文件能自动复制其自身,因此系统中有多个httpd进程,但只有一个进程为最初启动的进程,它为其他进程的父进程。对这个进程发送 信号将影响所有的httpd进程。PidFile定义的文件中就记录httpd 父进程的进程号。

  • MaxClients,默认值为150
    该参数限制Apache所能提供服务的最高数值,即同一时间连接的数目不能超过这个数值。一旦连接数目达到这个限制,Apache服务器则不再为别的连接提供服务,以免系统性能大幅度下降。

  • Port,默认值为80
    该参数用来指定Apache服务器的监听端口。一般来说,标准的HTTP服务默认端口号是80

  • KeepAlive,默认值为 on
    在HTTP 1.0中,一次连接只能作传输一次HTTP请求,而KeepAlive参数用于支持HTTP 1.1版本的一次连接、多次传输功能,这样就可以在一次连接中传递多个HTTP请求。建议设为ON,以便提高访问性能。


参考


上一篇 TortoiseSVN使用笔记

下一篇 JBoss

阅读
评论
19.4k
阅读预计72分钟
创建日期 2016-10-26
修改日期 2020-03-15
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论