Debian 9 使用Apache实现反向代理和负载均衡
反向代理的原理
Reverse Proxy
What is Reverse Proxy Server
A reverse proxy server is an intermediate connection point positioned at a network’s edge. It receives initial HTTP connection requests, acting like the actual endpoint.
Essentially your network’s traffic cop, the reverse proxy serves as a gateway between users and your application origin server. In so doing it handles all policy management and traffic routing.
A reverse proxy operates by:
Receiving a user connection request
Completing a TCP three-way handshake, terminating the initial connection
Connecting with the origin server and forwarding the original request
Reverse Proxy
Reverse Proxy vs Forward Proxy
In contrast, a forward proxy server is also positioned at your network’s edge, but regulates outbound traffic according to preset policies in shared networks. Additionally, it disguises a client’s IP address and blocks malicious incoming traffic.
Forward proxies are typically used internally by large organizations, such as universities and enterprises, to:
Block employees from visiting certain websites
Monitor employee online activity
Block malicious traffic from reaching an origin server
Improve the user experience by caching external site content
Apache反向代理和负载均衡
第1步 - 启用必要的Apache模块
Apache有许多与其捆绑在一起的模块,但在全新安装中不启用。
我将使用:
mod_proxy ,主代理模块Apache模块用于重定向连接;允许Apache充当底层应用程序服务器的网关。
mod_proxy_http ,增加了对代理HTTP连接的支持。
mod_proxy_balancer和mod_lbmethod_byrequests ,为多个后端服务器添加负载平衡功能。
要启用这四个模块,连续执行以下命令:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_balancer
a2enmod lbmethod_byrequests
root@newbie-unknown85882:/etc/apache2# a2enmod proxy
Enabling module proxy.
To activate the new configuration, you need to run:
systemctl restart apache2
root@newbie-unknown85882:/etc/apache2# a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Enabling module proxy_http.
To activate the new configuration, you need to run:
systemctl restart apache2
root@newbie-unknown85882:/etc/apache2# a2enmod proxy_balancer
Considering dependency proxy for proxy_balancer:
Module proxy already enabled
Considering dependency alias for proxy_balancer:
Module alias already enabled
Considering dependency slotmem_shm for proxy_balancer:
Enabling module slotmem_shm.
Enabling module proxy_balancer.
To activate the new configuration, you need to run:
systemctl restart apache2
root@newbie-unknown85882:/etc/apache2# a2enmod lbmethod_byrequests
Considering dependency proxy_balancer for lbmethod_byrequests:
Considering dependency proxy for proxy_balancer:
Module proxy already enabled
Considering dependency alias for proxy_balancer:
Module alias already enabled
Considering dependency slotmem_shm for proxy_balancer:
Module slotmem_shm already enabled
Module proxy_balancer already enabled
Enabling module lbmethod_byrequests.
To activate the new configuration, you need to run:
systemctl restart apache2
要使这些更改生效,重新启动Apache。
root@newbie-unknown85882:/etc/apache2# systemctl restart apache2
第2步 - 创建后端测试服务器
运行一些简单的后端服务器是一个简单的方法来测试你的Apache配置是否正常工作。这里,我将使两个测试服务器响应HTTP请求,打印一行文本。一个服务器会打印Hello World!另一个会打印Howdy World! 。 注意:在非测试设置中,后端服务器通常都返回相同类型的内容。然而,对于该测试,特别是使两个服务器返回不同的消息,使得容易检查负载平衡机制是否使用两者。Flask是构建Web应用程序的Python微框架,我使用Flask来创建测试服务器。
更新软件包列表:
root@newbie-unknown85882:/etc/apache2# apt-get update
忽略:1 http://apt.x.netease.com:8660/debian stretch InRelease
获取:2 http://sa.apt.netease.com:8660/debian stretch InRelease [3,300 B]
获取:3 http://apt.x.netease.com:8660/debian stretch-updates InRelease [91.0 kB]
获取:4 http://apt.x.netease.com:8660/debian-security stretch/updates InRelease [63.0 kB]
获取:5 http://sa.apt.netease.com:8660/debian stretch/main amd64 Packages [12.5 kB]
命中:6 http://apt.x.netease.com:8660/debian stretch Release
获取:7 http://apt.x.netease.com:8660/debian stretch-updates/main Sources.diff/Index [2,704 B]
...
#信息太多,已省略。
安装pip,flask:
root@newbie-unknown85882:/etc/apache2# apt-get -y install python3-pip
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
将会同时安装下列软件:
python-pip-whl python3-cffi-backend python3-crypto python3-cryptography python3-dbus python3-gi python3-idna python3-keyring python3-keyrings.alt
python3-pyasn1 python3-secretstorage python3-wheel python3-xdg
建议安装:
python3-crypto-dbg python-crypto-doc python-cryptography-doc python3-cryptography-vectors python-dbus-doc python3-dbus-dbg gnome-keyring libkf5wallet-bin
gir1.2-gnomekeyring-1.0 python3-pykde4 doc-base python-secretstorage-doc
下列【新】软件包将被安装:
python-pip-whl python3-cffi-backend python3-crypto python3-cryptography python3-dbus python3-gi python3-idna python3-keyring python3-keyrings.alt
python3-pip python3-pyasn1 python3-secretstorage python3-wheel python3-xdg
升级了 0 个软件包,新安装了 14 个软件包,要卸载 0 个软件包,有 33 个软件包未被升级。
需要下载 2,967 kB 的归档。
解压缩后会消耗 7,931 kB 的额外空间。
获取:1 http://apt.x.netease.com:8660/debian stretch/main amd64 python-pip-whl all 9.0.1-2 [1,406 kB]
获取:2 http://apt.x.netease.com:8660/debian stretch/main amd64 python3-cffi-backend amd64 1.9.1-2 [70.1 kB]
获取:3 http://apt.x.netease.com:8660/debian stretch/main amd64 python3-crypto amd64 2.6.1-7 [259 kB]
...
#信息太多,已省略。
root@newbie-unknown85882:/etc/apache2# pip3 install flask
Collecting flask
Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
100% |████████████████████████████████| 92kB 239kB/s
Collecting Werkzeug>=0.7 (from flask)
Using cached Werkzeug-0.14.1-py2.py3-none-any.whl
Collecting itsdangerous>=0.21 (from flask)
Using cached itsdangerous-0.24.tar.gz
Collecting Jinja2>=2.4 (from flask)
Downloading Jinja2-2.10-py2.py3-none-any.whl (126kB)
100% |████████████████████████████████| 133kB 707kB/s
...
#信息太多,已省略。
现在所有必需的组件都已安装,首先创建一个新文件,其中将包含当前用户主目录中第一个后端服务器的代码。
用nano创建文件,Ctrl+x再按y保存退出:
oot@newbie-unknown85882:~# nano ~/backend1.py
GNU nano 2.7.4 文件: /root/backend1.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello World!'
前两行初始化Flask框架。有一个函数, home() ,它返回一行文本( Hello World! )。 home()函数定义上面的@app.route('/')行告诉Flask使用home()的返回值作为对指向应用程序的/ root URL的HTTP请求的响应。 第二个后端服务器与第一个后端服务器完全相同,除了返回到不同的文本行,所以可以直接复制第一个文件再更改。
root@newbie-unknown85882:~# cp ~/backend1.py ~/backend2.py
root@newbie-unknown85882:~# nano ~/backend2.py
GNU nano 2.7.4 文件: /root/backend2.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Howdy World!'
分别在9999端口和10000端口上启动后台服务器:
root@newbie-unknown85882:~# FLASK_APP=~/backend1.py flask run --port=9999 >/dev/null 2>&1 &
[1] 12223
root@newbie-unknown85882:~# FLASK_APP=~/backend2.py flask run --port=10000 >/dev/null 2>&1 &
[2] 12237
测试:
root@newbie-unknown85882:~# curl http://127.0.0.1:9999/
Hello World!root@newbie-unknown85882:~#
root@newbie-unknown85882:~# curl http://127.0.0.1:10000/
Howdy World!root@newbie-unknown85882:~#
关闭和启动测试服务器的方法:
root@newbie-unknown85882:~# killall flask
root@newbie-unknown85882:~# curl http://127.0.0.1:9999/
curl: (7) Failed to connect to 127.0.0.1 port 9999: 拒绝连接
root@newbie-unknown85882:~# curl http://127.0.0.1:10000/
curl: (7) Failed to connect to 127.0.0.1 port 10000: 拒绝连接
root@newbie-unknown85882:~# FLASK_APP=~/backend1.py flask run --port=9999 >/dev/null 2>&1 &
[1] 17359
root@newbie-unknown85882:~# FLASK_APP=~/backend2.py flask run --port=10000 >/dev/null 2>&1 &
[2] 17362
root@newbie-unknown85882:~# curl http://127.0.0.1:9999/
Hello World!root@newbie-unknown85882:~#
root@newbie-unknown85882:~# curl http://127.0.0.1:10000/
Howdy World!root@newbie-unknown85882:~#
第3步 - 修改默认配置以启用反向代理
示例1 - 反向代理单个后端服务器
root@newbie-unknown85882:~# vim /etc/apache2/sites-available/000-default.conf
<VirtualHost *:8888>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:9999/
ProxyPassReverse / http://127.0.0.1:9999/
ServerAdmin webmaster@localhost
DocumentRoot /home/www/sites/psiral
ErrorDocument 404 /indexl.html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
/etc/apache2/sites-available/000-default.conf [+] 14,44 全部
"/etc/apache2/sites-available/000-default.conf" 38L, 1496C 已写入
root@newbie-unknown85882:~# systemctl restart apache2
测试:
反向代理单个后端服务器示例2 - 跨多个后端服务器的负载均衡
root@newbie-unknown85882:~# vim /etc/apache2/sites-available/000-default.conf
<VirtualHost *:8888>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
<Proxy balancer://mycluster>
BalancerMember http://127.0.0.1:9999
BalancerMember http://127.0.0.1:10000
</Proxy>
ProxyPreserveHost On
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
ServerAdmin webmaster@localhost
DocumentRoot /home/www/sites/psiral
ErrorDocument 404 /indexl.html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
/etc/apache2/sites-available/000-default.conf 15,0-1 顶端
"/etc/apache2/sites-available/000-default.conf" 43L, 1620C 已写入
root@newbie-unknown85882:~# apachectl configtest #检查配置
Syntax OK
root@newbie-unknown85882:~# systemctl restart apache2
测试:
跨多个后端服务器的负载均衡刷新
跨多个后端服务器的负载均衡
这说明Apache实现了反向代理和负载均衡功能。
网友评论