Apache mod_proxy 反向代理教程

一、启用必要模板

首先,你需要在Apache中启用mod_proxy模块以及几个附属模块:

  • mod_proxy:用于重定向连接的主代理Apache模块,它允许Apache充当底层应用程序服务器的网关。
  • mod_proxy_http:它增加了对代理HTTP连接的支持。
  • mod_proxy_balancermod_lbmethod_byrequests为多个后端服务器添加负载平衡功能。

执行以下命令启用

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests

接着重启Apache生效

sudo systemctl restart apache2

二、安装后端服务器

为了更好的演示,这里简单安装一下 flask 来作为后端服务器。
首先更新软件包列表

sudo apt-get update

然后安装 pip

sudo apt-get -y install python3-pip

接着安装 flask

sudo pip3 install flask

然后创建第一个后台程序,加入如下内容

from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
    return 'This is first server!'

该程序会在你访问根目录时返回一个 This is first server!
然后创建第二个程序,返回 This is second server!

from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
    return 'This is second server!'

然后分别启动这两个服务

$ FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &
$ FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &

接着使用 curl 返回这两个端口内容

curl http://127.0.0.1:8080/
// This is first server!
curl http://127.0.0.1:8081/
// This is second server!

执行killall flask命令可以杀死所有的 flask 程序。

三、启动代理服务器

编辑Apache的虚拟主机配置文件

$ sudo nano /etc/apache2/sites-available/000-default.conf

找到VirtualHost块,替换为如下内容

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

指令解释:

  • ProxyPreserveHost使Apache将原始Host标题传递给后端服务器。它使后端服务器知道用于访问应用程序的地址。
  • ProxyPass是主要的代理配置指令。上面的配置文件中表示在根URL(/)下的所有请求都应映射到给定地址的后端服务器。例如,如果Apache获得请求URL为 /example,它将映射到 http://127.0.0.1:8080/example
  • ProxyPassReverse具有与 ProxyPass 相同的功能。它告诉Apache修改来自后端服务器的响应头。这确保了如果后端服务器返回一个位置重定向头,客户端的浏览器将被重定向到代理地址,而不是后端服务器地址。

然后重启 apache 服务生效

$ sudo systemctl restart apache2

启动负载均衡

将上述VirtualHost块替换为如下内容,启用负载平衡

<VirtualHost *:80>
<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:8081
</Proxy>
    ProxyPreserveHost On
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
</VirtualHost>

然后重启Apache后,当你多次访问Web页面时,有时候会传递 This is first server!,而有时则是 This is second server!。

其它代理模块

这些模块使用不同的网络协议

  • mod_proxy_ftp 为FTP。
  • mod_proxy_connect 用于SSL隧道。
  • mod_proxy_ajp 用于AJP(Apache JServ协议),如基于Tomcat的后端。
  • mod_proxy_wstunnel 为网络套接字。

参考