集群架构 - Apache网站服务

1. Apache基础概述

1.1 动态和静态资源

静态元素:

  • .html - HTML文件
  • .img - 图片文件
  • js - JavaScript文件
  • css - 样式表文件
  • mp4 - 视频文件

动态元素:

  • .php - PHP脚本
  • .jsp - Java Server Pages
  • .py - Python脚本

1.2 常见Web Server服务

Web服务器 说明 特点
Nginx 高性能Web服务器 轻量级、高并发
openresty 基于Nginx的Web平台 集成Lua脚本
Tengine 淘宝开发的Nginx分支 针对大流量优化
Apache 最流行的Web服务器 功能丰富、模块化
IIS Windows Web服务器 Windows平台专用

1.3 Web常见中间件

PHP中间件:

  • PHP-fpm: PHP FastCGI Process Manager
  • HHVM: HipHop Virtual Machine

Python中间件:

  • WSGI: Web Server Gateway Interface

JSP中间件:

  • Tomcat: Apache Tomcat
  • JBOSS: Red Hat JBoss
  • Resin: Caucho Resin
  • Weblogic: Oracle WebLogic

1.4 主流组合架构

架构 说明 特点
LNMP Linux + Nginx + MySQL + PHP php-fpm进程模式
LAMP Linux + Apache + MySQL + PHP php作为Apache的模块
Nginx + Tomcat Nginx与Tomcat结合 取代Apache与Tomcat结合

1.5 Apache软件包

软件包:

  • httpd: Apache HTTP服务器

服务端口:

  • 80/tcp: HTTP服务端口
  • 443/tcp: HTTPS服务端口(HTTP + SSL)

1.6 Apache配置文件

配置文件 说明
/etc/httpd/conf/httpd.conf 主配置文件
/etc/httpd/conf.d/*.conf 包含配置文件
/etc/httpd/conf.d/welcome.conf 默认测试页面

1.7 配置进程和线程

Prefork MPM(进程模式)

针对Apache 2.2,仅针对面试。

1
2
3
4
5
6
7
8
9
# prefork MPM //进程模式
<IfModule prefork.c>
StartServers 10 //初始建立的进程数
MinSpareServers 10 //最小空闲的进程数
MaxSpareServers 15 //最大空闲的进程数
ServerLimit 2000 //最大启动的进程数 默认 256
MaxClients 2000 //最大并发连接数 默认 256
MaxRequestsPerChild 4000 //每个子进程在其生命周期内允许响应的最大请求数,0 不限制
</IfModule>

Worker MPM(线程模式)

1
2
3
4
5
6
7
8
9
# worker MPM //线程模式
<IfModule worker.c>
StartServers 2 //初始建立的进程数
ThreadsPerChild 50 //每个进程建立的线程数
MinSpareThreads 100 //最小空闲的线程数
MaxSpareThreads 200 //最大空间的线程数
MaxClients 2000 //最大的并发访问量(线程)
MaxRequestsPerChild 0 //每个子进程在其生命周期内允许响应的最大请求数,0 不限制
</IfModule>

MPM说明:

  • Prefork: 每个请求使用一个进程处理
  • Worker: 使用多线程处理请求,性能更好

2. Apache安装配置

2.1 环境准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 更新系统
[root@liyanzhao ~]# yum update

# 停止防火墙
[root@liyanzhao ~]# systemctl stop firewalld

# 禁用防火墙
[root@liyanzhao ~]# systemctl disable firewalld

# 关闭SELinux
[root@liyanzhao ~]# sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config

# 临时关闭SELinux
[root@liyanzhao ~]# setenforce 0

2.2 安装Apache服务

1
2
3
4
5
6
7
8
9
10
11
# 安装Apache服务
[root@liyanzhao ~]# yum install -y httpd

# 启动Apache服务
[root@liyanzhao ~]# systemctl start httpd

# 加入开机自启动
[root@liyanzhao ~]# systemctl enable httpd

# 检查服务状态
[root@liyanzhao ~]# systemctl status httpd

2.3 防火墙配置

如果必须启动防火墙的情况执行如下指令:

1
2
3
4
5
6
7
8
# 开放HTTP服务
[root@liyanzhao ~]# firewall-cmd --permanent --add-service=http

# 重新加载防火墙
[root@liyanzhao ~]# firewall-cmd --reload

# 验证防火墙规则
[root@liyanzhao ~]# firewall-cmd --list-services

2.4 添加默认静态页面

1
2
3
4
5
6
# 定义首页文件
[root@liyanzhao ~]# echo "Web is First" >> /var/www/html/index.html

# 访问测试,也可使用浏览器访问
[root@liyanzhao ~]# curl http://192.168.56.11
Web is First

3. Apache基础配置

3.1 查看Apache重要配置文件

1
2
# 查看主配置文件(排除注释和空行)
[root@liyanzhao ~]# grep '^[a-Z]' /etc/httpd/conf/httpd.conf

主要配置参数:

参数 说明 默认值
ServerRoot "/etc/httpd" 安装目录 /etc/httpd
Listen 80 监听端口 80
Include conf.modules.d/*.conf 包含模块目录配置文件 -
User apache 运行Apache进程的用户 apache
Group apache 运行Apache进程的用户组 apache
ServerAdmin root@localhost 管理员邮箱 root@localhost
DocumentRoot "/var/www/html" 站点目录 /var/www/html
ErrorLog "logs/error_log" 错误日志 logs/error_log
LogLevel warn 日志级别 warn
AddDefaultCharset UTF-8 字符集 UTF-8
EnableSendfile on 启用sendfile on
IncludeOptional conf.d/*.conf 包含conf.d目录下的所有conf结尾的文件 -

3.2 类型模块配置

1
2
3
4
5
6
7
<IfModule mime_module>
TypesConfig /etc/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</IfModule>

3.3 日志模块配置

1
2
3
4
5
6
7
8
9
10
11
ErrorLog "logs/error_log"
LogLevel warn

<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog "logs/access_log" combined
</IfModule>

日志格式说明:

  • combined: 完整日志格式,包含Referer和User-Agent
  • common: 通用日志格式
  • combinedio: 包含输入输出字节数

3.4 目录访问控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 不允许用户直接访问/目录
<Directory />
DirectoryIndex index.html
AllowOverride none
Require all denied
</Directory>

# 允许所有用户访问/var/www
<Directory "/var/www">
DirectoryIndex index.html
AllowOverride None
Require all granted
</Directory>

# 拒绝任何人访问包含.ht文件
<Files ".ht*">
Require all denied
</Files>

参数说明:

  • DirectoryIndex: 目录默认文件
  • AllowOverride: 是否允许.htaccess文件覆盖配置
  • Require all denied: 拒绝所有访问
  • Require all granted: 允许所有访问

4. Apache虚拟主机

虚拟主机允许一个服务器上同时运行多个网站。

4.1 建立默认虚拟主机

1
2
# 创建默认虚拟主机配置文件
# vim /etc/httpd/conf.d/00-default-vhost.conf
1
2
3
4
5
6
7
8
9
<VirtualHost _default_:80>
DocumentRoot /srv/default/www/
CustomLog "logs/default-vhost.log" combined
<Directory /srv/default/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

4.2 建立www0.example.com的虚拟主机

1
2
# 创建虚拟主机配置文件
# vim /etc/httpd/conf.d/01-www0.example.com-vhost.conf
1
2
3
4
5
6
7
8
9
10
<VirtualHost *:80>
ServerName www0.example.com
DocumentRoot /srv/www0.example.com/www/
CustomLog "logs/www0.example.com-vhost.log" combined
<Directory /srv/www0.example.com/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

4.3 创建网站目录

1
2
3
4
5
6
7
8
9
10
11
# 创建网站目录
mkdir -p /srv/www0.example.com/www/

# 创建测试页面
echo "www0.example.com" > /srv/www0.example.com/www/index.html

# 设置权限
chown -R apache:apache /srv/www0.example.com/

# 重启Apache服务
systemctl restart httpd

5. Apache动态网站

5.1 安装PHP

如果需要解析动态php程序,则需要安装php。

1
2
3
4
5
6
7
8
9
10
11
12
# 安装PHP
[root@liyanzhao ~]# yum install -y php

# php作为Apache的模块运行,并生成对应配置文件
[root@liyanzhao ~]# ll /etc/httpd/modules/libphp5.so
-rwxr-xr-x 1 root root 4814560 Nov 14 21:10 /etc/httpd/modules/libphp5.so

[root@liyanzhao ~]# ll /etc/httpd/conf.d/php.conf
-rw-r--r-- 1 root root 561 Nov 14 21:10 /etc/httpd/conf.d/php.conf

# 重启Apache加载php
[root@liyanzhao ~]# systemctl restart httpd

5.2 编写PHP状态页面

1
2
3
4
5
6
# 编写php状态页面
[root@liyanzhao ~]# cat >> /var/www/html/info.php <<EOF
<?php
phpinfo();
?>
EOF

5.3 测试访问PHP状态页面

访问 http://192.168.56.11/info.php 可以查看PHP配置信息。

5.4 安装MariaDB数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 安装MariaDB数据库,启动并加入开机自启动
[root@liyanzhao ~]# yum install mariadb mariadb-server -y
[root@liyanzhao ~]# systemctl enable mariadb
[root@liyanzhao ~]# systemctl start mariadb

# 简单配置mariadb数据库
[root@liyanzhao ~]# mysql_secure_installation

# 输入y,然后设定root密码
Set root password? [Y/n]y
New password: 123
Re-enter new password: 123
# 后面暂时一路回车即可...

# 登陆MariaDB验证密码
[root@apache ~]# mysql -uroot -p123
MariaDB [(none)]> exit
Bye

5.5 编辑PHP连接数据库文件

1
2
3
4
5
6
7
8
9
10
11
# 编辑php连接数据库文件
[root@liyanzhao ~]# cat > /var/www/html/sql.php <<-EOF
<?php
\$link=mysql_connect('localhost','root','123');
if(\$link)
echo "Successfuly";
else
echo "Faile";
mysql_close();
?>
EOF

注意: 打开页面如果出现空白,说明php无法连接MariaDB,请按如下步骤操作:

1
2
3
4
5
6
7
8
9
10
11
# 安装php连接mariadb数据库模块
[root@liyanzhao ~]# yum install php-mysql -y

# 检查是否有对应数据库模块
[root@liyanzhao ~]# php -m |grep mysql
mysql
mysqli
pdo_mysql

# 重启apache服务加载
[root@liyanzhao ~]# systemctl restart httpd

5.6 验证PHP与MariaDB连接

访问 http://192.168.56.11/sql.php 应该显示 “Successfuly”。

5.7 升级PHP版本

如果觉得PHP版本过低,可进行升级PHP版本。

1
2
3
4
5
6
7
8
9
10
# 检查当前安装的PHP,并移动旧版
[root@http-server ~]# rpm -e $(yum list installed | grep php)

# 安装epel扩展源,安装php7
[root@http-server ~]# yum install epel-release
[root@http-server ~]# rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

[root@http-server ~]# yum install -y php72-php php72-php-gd php72-php-mysqlnd \
php72-php-pecl-mysql php72-php-pecl-mysql-xdevapi php72-php-opcache \
php72-php-pecl-memcache php72-php-pecl-memcached php72-php-pecl-redis

6. Apache访问控制

目录访问控制,基于IP或者主机访问控制(仅限httpd 2.4版本可用)。

6.1 访问控制指令

指令 说明
Require local 匹配本机
Require all granted 匹配所有的访问请求,并且授权访问
Require all denied 匹配所有的访问请求,并且拒绝访问
Require ip 192.168.56.11 匹配指定IP的客户端访问
Require ip 192.168.56.0/255.255.0.0 匹配某个IP网段
Require ip 192.168.56.0/24 匹配某个IP网段
Require not ip 192.168.56.11 不匹配该IP的请求
Require host desktop0.example.com 匹配主机名的客户端访问
Require host example.com 匹配某个域或主机名

主机名匹配示例:

  • example.com - 精确匹配
  • server0.example.com - 精确匹配
  • node.example.com - 精确匹配
  • *.example.com - 通配符匹配

不匹配示例:

  • Require not host gov - 不匹配所有以.gov结尾域

注意: not不能单独使用,必须使用在RequireAllRequireAnyRequireNone容器标签里。

6.2 实践环境准备

1
2
3
4
5
6
7
8
# 创建测试目录
[root@http-server ~]# mkdir /var/www/html/download/

# 创建测试文件
[root@http-server ~]# echo "web Server Apache" > /var/www/html/download/index.html

# 创建.htaccess文件
[root@http-server ~]# echo "htaccess" > /var/www/html/download/.htaccess

6.3 案例1: 允许所有主机访问

1
2
3
4
5
6
7
8
9
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AllowOverride None
Require all granted
</Directory>

说明:

  • AllowOverride All: 允许子目录中的.htaccess中的设置覆盖当前设置
  • AllowOverride None: 不允许子目录中的.htaccess中的设置覆盖当前设置

6.4 案例2: 只允许网段192.168.56|69.0/24访问

1
2
3
4
5
6
7
8
9
10
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AllowOverride None
Require ip 192.168.69.0/24
Require ip 192.168.56.0/24
</Directory>

6.5 案例3: 所有请求都允许,只拒绝某些主机访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AllowOverride None
<!-- 用于封装一组规则的授权,其中必须没有失败的授权 -->
<!-- 至少必须有一个规则成功才允许访问 -->
<RequireAll>
Require all granted
Require not host desktop0.example.com
#Require not ip 192.168.56.0/24
</RequireAll>
</Directory>

限制原理:

  1. 要求里的规则都完全匹配并且授权访问才能访问
  2. desktop0.example.com满足第一条规则
  3. desktop0.example.com不满足第二条规则,所以不能访问

6.6 案例4: 拒绝所有人访问,但允许个别主机可以访问

1
2
3
4
5
6
7
8
9
10
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AllowOverride None
Require ip 192.168.160.161
Require all denied
</Directory>

6.7 案例5: 特别的规则组合

只能本机访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AllowOverride None
<!-- 用于封装一组规则的授权,其中必须没有失败的授权 -->
<!-- 至少必须有一个规则成功才允许访问 -->
<RequireAll>
Require all granted
Require local
</RequireAll>
</Directory>

说明: <RequireAll>要求所有规则都必须通过,不能有一个失败。最终结果只能是本机访问。

只有desktop0.example.com能访问

1
2
3
4
5
6
7
8
9
10
11
12
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AllowOverride None
<RequireAll>
Require all granted
Require host desktop0.example.com
</RequireAll>
</Directory>

说明: 其他机器都不能匹配到Require host desktop0.example.com

6.8 文件访问控制

1
2
3
4
5
6
7
8
9
# 不允许在/var/www/edusoho/web/upload 目录中执行.php 文件
<Directory /webroot/baidu/upload>
AllowOverride None
Require all granted
<Files ~ "\.php$">
Order allow,deny
Deny from all
</Files>
</Directory>

6.9 用户访问控制

访问站点需要用户与密码(httpd官方参考文档)。

安装加密工具

1
2
# 安装加密工具
[root@http-server ~]# yum install -y httpd-tools

建立密码文件

1
2
3
4
5
# 建立密码文件(-c创建新文件,-b使用命令行密码)
[root@http-server ~]# htpasswd -c -b /etc/httpd/webpass bgx 123

# 如果需要新增用户,可使用如下方式(不加-c参数)
[root@http-server ~]# htpasswd -b /etc/httpd/webpass bgx1 123

配置httpd支持认证

1
2
3
4
5
6
7
8
9
10
11
12
<VirtualHost *:80>
ServerName test.bgx.com
DocumentRoot "/var/www/html/download"
</VirtualHost>

<Directory "/var/www/html/download">
AuthType "Basic"
AuthName "Hai I's To Bgx"
AuthBasicProvider file
AuthUserFile "/etc/httpd/webpass"
Require valid-user
</Directory>

参数说明:

  • AuthType "Basic": 基本认证类型
  • AuthName: 认证提示信息
  • AuthBasicProvider file: 使用文件作为认证提供者
  • AuthUserFile: 密码文件路径
  • Require valid-user: 要求有效用户

7. Apache安全服务

使用虚拟主机技术部署两个网站,按要求配置HTTPS网站。

需求:

  • 网站1:

    • 绑定域名 www0.example.com
    • 目录在 /srv/www0/www
    • 要求支持https加密访问
    • 所有通过http访问该网站都会自动调转到https
  • 网站2:

    • 绑定域名 webapp0.example.com
    • 目录在 /srv/webapp0/www
    • 要求支持https加密访问
    • 所有通过http访问该网站都会自动调转到https

7.1 安装httpd mod_ssl

1
2
3
4
5
6
# 安装httpd mod_ssl实现http和https服务
[root@http-server ~]# yum install httpd mod_ssl -y

# 启动并加入开机自启
[root@http-server ~]# systemctl enable httpd
[root@http-server ~]# systemctl start httpd

7.2 建立HTTPS网站需要的相关证书和密钥文件

证书文件位置:

  • http://classroom.example.com/pub/example-ca.crt - 根证书
  • http://classroom.example.com/pub/tls/certs/www0.crt - www0网站的证书
  • http://classroom.example.com/pub/tls/private/www0.key - www0网站的私钥
  • http://classroom.example.com/pub/tls/certs/webapp0.crt - webapp0网站的证书
  • http://classroom.example.com/pub/tls/private/webapp0.key - webapp0网站的私钥

下载证书文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 下载证书文件到指定位置
mkdir -p /etc/pki/tls/{certs,private}

# 下载根证书
wget http://classroom.example.com/pub/example-ca.crt -O /etc/pki/ca-trust/source/anchors/example-ca.crt

# 下载www0证书和私钥
wget http://classroom.example.com/pub/tls/certs/www0.crt -O /etc/pki/tls/certs/www0.crt
wget http://classroom.example.com/pub/tls/private/www0.key -O /etc/pki/tls/private/www0.key

# 下载webapp0证书和私钥
wget http://classroom.example.com/pub/tls/certs/webapp0.crt -O /etc/pki/tls/certs/webapp0.crt
wget http://classroom.example.com/pub/tls/private/webapp0.key -O /etc/pki/tls/private/webapp0.key

# 设置私钥权限
chmod 600 /etc/pki/tls/private/*.key

# 更新CA证书
update-ca-trust

7.3 建立相关目录文件

1
2
3
4
5
6
7
8
9
# 建立相关目录文件
[root@http-server ~]# mkdir -p /srv/{www0,webapp0}/www

# 创建测试页面
[root@http-server ~]# echo "www0" > /srv/www0/www/index.html
[root@http-server ~]# echo "webapp0" > /srv/webapp0/www/index.html

# 设置权限
[root@http-server ~]# chown apache:apache -R /srv/*

7.4 建立对应两台虚拟主机

配置www0虚拟主机

1
# vim /etc/httpd/conf.d/www0.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<VirtualHost *:443>
DocumentRoot "/srv/www0/www"
ServerName www0.example.com
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
SSLCertificateFile /etc/pki/tls/certs/www0.crt
SSLCertificateKeyFile /etc/pki/tls/private/www0.key
<Directory /srv/www0/www>
Require all granted
</Directory>
</VirtualHost>

<VirtualHost *:80>
ServerName www0.example.com
RewriteEngine On
RewriteRule ^(/.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>

配置webapp0虚拟主机

1
2
3
4
5
# 复制www0配置文件
[root@http-server ~]# cp /etc/httpd/conf.d/{www0,webapp0}.conf

# 替换配置中的www0为webapp0
[root@http-server ~]# sed -i 's/www0/webapp0/g' /etc/httpd/conf.d/webapp0.conf

7.5 重启服务并测试

1
2
3
4
5
6
7
8
9
10
11
12
# 测试配置文件语法
apachectl configtest

# 重启Apache服务
systemctl restart httpd

# 测试HTTPS访问
curl -k https://www0.example.com
curl -k https://webapp0.example.com

# 测试HTTP自动跳转
curl -I http://www0.example.com

配置说明:

  • SSLEngine on: 启用SSL引擎
  • SSLProtocol all -SSLv2: 允许所有SSL协议,禁用SSLv2
  • SSLCipherSuite: 指定加密套件
  • RewriteEngine On: 启用重写引擎
  • RewriteRule: HTTP自动跳转到HTTPS

8. Apache反向代理

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

8.1 Node节点部署

在两台web-node节点中均使用Yum安装一个Apache用于做真实机,监听8080端口。

web-node1.com部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 安装epel源
[root@web-node1 ~]# rpm -ivh \
http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

# 安装基础工具
[root@web-node1 ~]# yum install -y gcc glibc gcc-c++ make screen tree lrzsz

# 部署web-node1 httpd服务
[root@web-node1 ~]# yum install -y httpd

# 修改监听端口为8080
[root@web-node1 ~]# sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf

# 启动服务
[root@web-node1 ~]# systemctl start httpd

# 创建测试页面
[root@web-node1 ~]# echo "web-node1.com" > /var/www/html/index.html

# 测试访问
[root@web-node1 ~]# curl http://192.168.90.201:8080/
web-node1.com

web-node2.com部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 安装epel源
[root@web-node2 ~]# rpm -ivh \
http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

# 安装基础工具
[root@web-node2 ~]# yum install -y gcc glibc gcc-c++ make screen tree lrzsz

# 部署web-node2 httpd服务
[root@web-node2 ~]# yum install -y httpd

# 修改监听端口为8080
[root@web-node2 ~]# sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf

# 启动服务
[root@web-node2 ~]# systemctl start httpd

# 创建测试页面
[root@web-node2 ~]# echo "web-node2.com" > /var/www/html/index.html

# 测试访问
[root@web-node2 ~]# curl http://192.168.90.202:8080/
web-node2.com

8.2 反向代理部署

步骤1: Apache源码编译安装,并监听80端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 安装编译依赖
[root@lb-node1 ~]# yum install -y apr-devel apr-util-devel pcre-devel openssl-devel

# 下载Apache源码
[root@lb-node1 ~]# cd /usr/local/src
[root@lb-node1 src]# wget http://www-eu.apache.org/dist/httpd/httpd-2.4.23.tar.gz

# 解压源码
[root@lb-node1 src]# tar xf httpd-2.4.23.tar.gz
[root@lb-node1 src]# cd httpd-2.4.23

# 编译安装
[root@lb-node1 httpd-2.4.23]# ./configure --prefix=/usr/local/httpd-2.4.23 --enable-so --enable-modules="all"
[root@lb-node1 httpd-2.4.23]# make && make install

# 创建软链接
[root@lb-node1 httpd-2.4.23]# ln -s /usr/local/httpd-2.4.23/ /usr/local/httpd

# 测试配置并启动Apache
[root@lb-node1 ~]# sed -i 's@#ServerName www.example.com:80@ServerName 192.168.90.203:80@g' /usr/local/httpd/conf/httpd.conf
[root@lb-node1 ~]# /usr/local/httpd/bin/apachectl -t
Syntax OK
[root@lb-node1 ~]# /usr/local/httpd/bin/apachectl -k start

步骤2: 在httpd.conf配置引用proxy配置文件

1
2
3
4
5
# 编辑主配置文件
vim /usr/local/httpd/conf/httpd.conf

# 添加以下行
Include conf/extra/httpd-proxy.conf

步骤3: 配置proxy反向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 创建proxy配置文件
[root@linux-node1 ~]# cat > /usr/local/httpd/conf/extra/httpd-proxy.conf <<EOF
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

ProxyRequests Off

<Proxy balancer://web-cluster>
BalancerMember http://192.168.90.201:8080 loadfactor=1
BalancerMember http://192.168.90.202:8080 loadfactor=2
</Proxy>

ProxyPass /biaoganxu balancer://web-cluster
ProxyPassReverse /biaoganxu balancer://web-cluster

<Location /manager>
SetHandler balancer-manager
Order Deny,Allow
Allow from all
</Location>
EOF

步骤4: 重载Apache服务

1
2
# 重载Apache服务(优雅重启)
[root@lb-node1 ~]# /usr/local/httpd/bin/apachectl -k graceful

步骤5: 测试反向代理

1
2
3
4
5
6
7
8
9
# 测试反向代理(多次请求查看负载均衡效果)
[root@lb-node1 ~]# curl http://192.168.90.203/biaogan/
web-node1.com
[root@lb-node1 ~]# curl http://192.168.90.203/biaogan/
web-node2.com
[root@lb-node1 ~]# curl http://192.168.90.203/biaogan/
web-node2.com
[root@lb-node1 ~]# curl http://192.168.90.203/biaogan/
web-node1.com

步骤6: 使用HTTP访问Apache管理页面

访问 http://192.168.90.203/manager 可以查看负载均衡管理页面。

8.3 Apache proxy代理配置文件详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# proxy模块
LoadModule proxy_module modules/mod_proxy.so

# 链接模块
LoadModule proxy_connect_module modules/mod_proxy_connect.so

# http代理模块
LoadModule proxy_http_module modules/mod_proxy_http.so

# 负载均衡模块
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

# 算法默认是byrequest,可以是bytraffic或者bybusyness
# 算法模块,根据server的请求量
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

LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

ProxyRequests Off

# LB集群组名称
<Proxy balancer://web-cluster>
# node节点并设置权重(可很多)
BalancerMember http://192.168.90.201:8080 loadfactor=1
BalancerMember http://192.168.90.202:8080 loadfactor=2
</Proxy>

# 跳转至LB集群组名称,交由后端WEB节点处理
ProxyPass /biaogan balancer://web-cluster
ProxyPassReverse /biaogan balancer://web-cluster

# Apache管理页面
<Location /manager>
SetHandler balancer-manager
Order Deny,Allow
Allow from all
</Location>

配置说明:

  • ProxyRequests Off: 关闭正向代理
  • loadfactor: 负载因子,数字越大权重越高
  • ProxyPass: 将请求转发到后端服务器
  • ProxyPassReverse: 修改响应头中的Location和Content-Location
  • balancer-manager: 负载均衡管理界面

9. Apache服务管理

9.1 服务管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 启动服务
systemctl start httpd

# 停止服务
systemctl stop httpd

# 重启服务
systemctl restart httpd

# 重载配置(不中断连接)
systemctl reload httpd

# 查看状态
systemctl status httpd

# 开机自启
systemctl enable httpd

9.2 配置文件测试

1
2
3
4
5
6
7
8
9
10
# 测试配置文件语法
apachectl configtest
# 或
httpd -t

# 查看编译配置
httpd -V

# 查看加载的模块
httpd -M

9.3 日志管理

1
2
3
4
5
6
7
8
# 查看错误日志
tail -f /var/log/httpd/error_log

# 查看访问日志
tail -f /var/log/httpd/access_log

# 查看特定虚拟主机日志
tail -f /var/log/httpd/www0.example.com-vhost.log

10. Apache故障排查

10.1 常见问题

问题1: 服务无法启动

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
# 检查配置文件语法
apachectl configtest

# 检查端口占用
ss -lntup | grep :80

# 查看错误日志
tail -f /var/log/httpd/error_log

# 检查SELinux
getenforce

问题2: 403 Forbidden错误

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
# 检查目录权限
ls -ld /var/www/html

# 检查文件权限
ls -l /var/www/html/index.html

# 检查SELinux上下文
ls -Z /var/www/html

# 检查配置文件中的访问控制
grep -A 10 "<Directory" /etc/httpd/conf/httpd.conf

问题3: 虚拟主机不生效

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
# 检查虚拟主机配置
cat /etc/httpd/conf.d/*.conf

# 检查ServerName是否正确
grep ServerName /etc/httpd/conf.d/*.conf

# 检查DNS解析
nslookup www0.example.com

# 使用curl测试
curl -H "Host: www0.example.com" http://服务器IP

10.2 性能优化

1
2
3
4
5
6
7
8
# 优化MPM配置
vim /etc/httpd/conf.modules.d/00-mpm.conf

# 启用压缩
LoadModule deflate_module modules/mod_deflate.so

# 启用缓存
LoadModule expires_module modules/mod_expires.so

实战优化