Apache

#web

安装

CentOS 7:

su -
yum install httpd
systemctl start httpd
systemctl enable httpd      # 可选

配置文件

/etc/httpd/
|-- conf
|   |-- httpd.conf
|   `-- magic
|-- conf.d
|   |-- autoindex.conf
|   |-- php.conf
|   |-- phpldapadmin.conf
|   |-- README
|   |-- userdir.conf
|   `-- welcome.conf
|-- conf.modules.d
|   |-- 00-base.conf
|   |-- 00-dav.conf
|   |-- 00-lua.conf
|   |-- 00-mpm.conf
|   |-- 00-proxy.conf
|   |-- 00-systemd.conf
|   |-- 01-cgi.conf
|   `-- 10-php.conf
|-- logs -> ../../var/log/httpd
|-- modules -> ../../usr/lib64/httpd/modules
`-- run -> /run/httpd

常用命令

httpd -V        # MPM、编译参数、版本
httpd -l        # 编译进的模块

工作模式

目前共有 3 种稳定的 MPM (Multi-Processing Module,多进程处理模块),即工作模式。

Prefork:多进程+单线程模式。主进程会预先生成一批子进程。(默认)

Worker:多进程+多线程模式。keep-alive 会一直占用线程。

Event:多进程+多线程模式。有专门的线程负责管理 keep-alive 线程。

Virtual Host

# httpd-2.4.6

<VirtualHost *:8000>
    ServerName hosta
    DocumentRoot "/var/www/hosta"
    <Directory /var/www/hosta>
        Require all granted
    </Directory>
</VirtualHost>

<VirtualHost *:8000>
    ServerName hostb
    DocumentRoot "/var/www/hostb"
    <Directory /var/www/hostb>
        Require all granted
    </Directory>
</VirtualHost>

如果每个 Virutal Host 用不同的 IP,可将 * 可以换成 IP 地址。也可以用不同的端口或 ServerName

内网测试方法:在不同的 DocumentRoot 下放不同的网页,然后将 hosta、hostb 添加到 /etc/hosts,最后用域名访问,应该看到不同的网页。

URL 重定向

RewriteEngine on
RewriteCond %{HTTP_HOST} ^hosta:8000$
RewriteRule ^/(.*)$ http://hostb:8000/$1 [R,L]

如果使用了端口号,HTTP_HOST 是包含端口的。

$1 在正则表达式中代表第一个匹配的分组,即前面括号中的内容。

R 表示强制使用外部重定向 (301 Redirect)。

L 表示这是最后一条 (last) 规则,忽略后面的规则。

V2.2 与 V2.4

配置语法的差异见文档: Upgrading to 2.4 from 2.2

想兼容各个版本就需要使用 mod_version

<IfVersion >= 2.4>
     Require all granted
</IfVersion>
<IfVersion < 2.4>
     Order allow,deny
     Allow from all
</IfVersion>

目录映射 (Alias)

# /etc/httpd/conf.d/xxx.conf (httpd-2.4.6)
Alias /name /your/path
<Directory /your/path>
    Options Indexes
    Require all granted
</Directory>

Alias 指令在 alias_module 中,默认在 /etc/httpd/conf.modules.d/00-base.conf 中加载了。

某些文件的请求不记录日志

# httpd-2.4.6, CentOS 7
SetEnvIf Request_URI "\.gif$" image
SetEnvIf Request_URI "\.js$" image
SetEnvIf Request_URI "\.css$" image
CustomLog "| /usr/sbin/rotatelogs logs/xxx.com-%Y%m%d 86400" common env=!image

commonLogFormat 的名字,在 httpd.conf 中定义。

使用 logs/ 因为它是 /etc/httpd 目录下的一个软链接(指向 /var/log/httpd/),而该目录又在 httpd.conf 中被定义为 ServerRoot "/etc/httpd"。用其它路径就需要写完整。

| 表示管道,效果与 echo "apache log" | /usr/sbin/rotatelogs ... 相同。

CustomLog 指令在 log_config_module 中,在 conf.modules.d/00-base.conf 中被自动加载。

rotatelogs 命令在不同的系统中路径有可能变化。

86400 表示以 1 天为周期(单位:秒)。

WSGI

首先,要手动安装 mod_wsgi 包:

$ yum install mod_wsgi
$ rpm -ql mod_wsgi
/etc/httpd/conf.modules.d/10-wsgi.conf      # 自动加载
/usr/lib64/httpd/modules/mod_wsgi.so        # 模块安装路径
...

增加配置:

# httpd.conf (httpd-2.4.6, mod_wsgi-3.4)
WSGIScriptAlias / "/var/www/wsgi.py"

wsgi.py:

#!/usr/bin/env python2

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['Hello WSGI!']

if __name__ == '__main__':
    from flup.server.fcgi import WSGIServer
    WSGIServer(application).run()

函数 application 的名字不能变,mod_wsgi 会去调这个函数。

设置运行权限:

chmod +x /var/www/wsgi.py

这里的 wsgi.py 其实就类似 Django 等框架所在的层次,一般不会直接在这里面写业务逻辑,否则需要自己实现路由(即 URL 到处理函数的映射),而这正是框架的核心功能。