一、启用必要模板
首先,你需要在Apache中启用mod_proxy
模块以及几个附属模块:
mod_proxy
:用于重定向连接的主代理Apache模块,它允许Apache充当底层应用程序服务器的网关。mod_proxy_http
:它增加了对代理HTTP连接的支持。mod_proxy_balancer
和mod_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/exampleProxyPassReverse
具有与 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
为网络套接字。