介绍
反向代理是一种代理服务器,它接收HTTP(S)请求,并将其透明地分发到一个或多个后端服务器。反向代理很有用,因为许多现代Web应用程序使用后端应用程序服务器处理传入的HTTP请求,这些服务器不是直接由用户访问的,通常只支持基本的HTTP功能。 您可以使用反向代理来防止直接访问这些底层应用程序服务器。它们还可以用于将负载从传入请求分发到多个不同的应用程序服务器,从而提高规模性能并提供故障安全性。它们可以填补应用程序服务器不提供的功能,例如缓存,压缩或SSL加密。 在本教程中,您将设置Apache作为基本反向代理,使用mod_proxy
扩展将传入连接重定向到运行在同一网络上的一个或多个后端服务器。 本教程使用与
Flask Web框架一起编写的简单后端,但您可以使用任何您喜欢的后端服务器。
先决条件
要遵循本教程,您需要:- 一个CentOS 7服务器设置了这个初始服务器设置教程 ,包括一个sudo非root用户。
- Apache 2安装在您的服务器上按照第1步 如何在CentOS 7上安装Linux,Apache,MySQL,PHP(LAMP) 。
- 可选地,使用
yum install nano
的nano
文本编辑器。 CentOS默认提供vi
文本编辑器,但是nano
可以更加用户友好。
第1步 - 引入必要的Apache模块
使用Apache作为反向代理所需的模块包括mod_proxy
本身和其附加模块,它扩展了其功能以支持不同的网络协议。具体来说,我们将使用:
mod_proxy
,主代理模块Apache模块用于重定向连接;它允许Apache充当底层应用程序服务器的网关。mod_proxy_http
,它增加了对代理HTTP连接的支持。mod_proxy_balancer
和mod_lbmethod_byrequests
,它为多个后端服务器添加负载平衡功能。
httpd -M
命令输出将列出所有已启用的Apache模块。你正在寻找的四行是前面提到的模块名称:
Output. . .
proxy_module (shared)
. . .
lbmethod_byrequests_module (shared)
. . .
proxy_balancer_module (shared)
. . .
proxy_http_module (shared)
. . .
如果模块未启用,您可以通过打开具有
nano
的
/etc/httpd/conf.modules.d/00-proxy.conf
来启用它们:
sudo nano /etc/httpd/conf.modules.d/00-proxy.conf
并通过从行开始删除
#
符号来取消注释带有必要模块的行,因此文件看起来如下所示:
/etc/httpd/conf.modules.d/00-proxy.conf
. . .
LoadModule proxy_module modules/mod_proxy.so
. . .
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
. . .
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
. . .
LoadModule proxy_http_module modules/mod_proxy_http.so
. . .
要使更改生效,请保存文件并重新启动Apache。
sudo systemctl restart httpd
Apache现在准备好作为HTTP请求的反向代理。在下一步中,我们将创建两个非常基本的后端服务器。这些将帮助我们验证配置是否正常工作,但如果您已经有自己的后端应用程序,则可以跳到第3步。
第2步 - 创建后端测试服务器
运行一些简单的后端服务器是一个简单的方法来测试你的Apache配置是否正常工作。这里,我们将使两个测试服务器响应HTTP请求,打印一行文本。一个服务器会说 Hello world! 和其他会说 Howdy世界! 。 注意:在非测试设置中,后端服务器通常都返回相同类型的内容。然而,对于该测试,特别是使两个服务器返回不同的消息,使得容易检查负载平衡机制是否使用两者。 Flask是构建Web应用程序的Python微框架。我们使用Flask来创建测试服务器,因为一个基本的应用程序只需要几行代码。你不需要知道Python来设置这些,但是如果你想学习,你可以看看 这些Python教程 。 让我们先安装IUS软件包存储库文件。 IUS(Instream with Upstream Stable)是一个社区项目,为CentOS提供了最新版本的选择软件,包括Python 3。sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm
然后安装Python 3和Pip,建议使用Python包管理器。
sudo yum -y install python35u python35u-pip
使用Pip安装Flask。
sudo pip3.5 install flask
现在所有必需的组件都已安装,首先创建一个新文件,该文件将包含当前用户主目录中第一个后端服务器的代码。
nano ~/backend1.py
将以下代码复制到文件中,然后保存并关闭它。
〜/ 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请求的响应。 第二个后端服务器与第一个后端服务器完全相同,除了返回到不同的文本行,所以从复制第一个文件开始。
cp ~/backend1.py ~/backend2.py
打开新复制的文件。
nano ~/backend2.py
更改要从
Hello world返回的消息
! 到
高潮的世界! ,然后保存并关闭文件。
〜/ backend2.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Howdy world!'
使用以下命令在端口
8080
上启动第一个后台服务器。 这也将Flask的输出重定向到
/dev/null
,因为它会进一步云控制台输出。
FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &
这里,我们在
flask
命令之前通过在同一行中设置
FLASK_APP
环境变量。 环境变量是将信息传递到从shell生成的进程的一种方便的方法。 您可以在
如何在Linux VPS上读取和设置环境变量和Shell变量中了解有关环境变量的更多信息。 在这种情况下,使用环境变量确保设置仅适用于正在运行的命令,并且将不会保留可用的,因为我们将传递另一个文件名以相同的方式告诉
flask
命令启动第二个服务器 类似地,使用此命令在端口
8081
上启动第二台服务器。 请注意
FLASK_APP
环境变量的不同值。
FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &
您可以测试两个服务器正在使用
curl
运行。测试第一台服务器:
curl http://127.0.0.1:8080/
这将输出
Hello world!在终端。测试第二台服务器:
curl http://127.0.0.1:8081/
这将输出
Howdy world!代替。
注意 :要在不再需要它们后关闭两个测试服务器,就像完成本教程时一样,您可以简单地执行killall flask
。 在下一步中,我们将修改Apache的配置文件,以便将其用作反向代理。
第3步 - 修改默认配置以启用反向代理
在本节中,我们将设置默认的Apache虚拟主机,作为单个后端服务器或负载平衡后端服务器阵列的反向代理。 注意 :在本教程中,我们将在虚拟主机级别应用配置。 在Apache的默认安装中,没有配置虚拟主机。 我们将创建一个单一的默认虚拟主机,以捕获所有流量。 但是,您也可以在其他虚拟主机中使用所有这些配置碎片。 要了解有关Apache中虚拟主机的更多信息,您可以阅读 如何在CentOS 7上设置Apache虚拟主机 。 如果您的Apache服务器同时充当HTTP和HTTPS服务器,则您的逆向代理配置必须放在HTTP和HTTPS虚拟主机中。要了解有关使用Apache的SSL的更多信息,您可以阅读 如何在Apache for CentOS 7上创建SSL证书教程。 通过使用nano
或您喜欢的文本编辑器在
/etc/httpd/conf.d
目录中创建一个新的空Apache配置文件来创建新的默认虚拟主机。
sudo nano /etc/httpd/conf.d/default-site.conf
下面的第一个示例说明如何将默认虚拟主机配置为单个后端服务器的反向代理,第二个示例为多个后端服务器设置负载平衡反向代理。
示例1 - 反向代理单个后端服务器
将以下内容粘贴到default-site.conf
文件中,因此您的配置文件如下所示:
/etc/httpd/conf.d/default-site.conf
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
如果在第2步中
127.0.0.1:8080
示例服务器,请使用上面的块中写的
127.0.0.1:8080
。如果您有自己的应用程序服务器,请改用其地址。 这里有三个指令:
ProxyPreserveHost
使Apache将原始Host
头传递给后端服务器。这是有用的,因为它使后端服务器知道用于访问应用程序的地址。ProxyPass
是主要的代理配置指令。 在这种情况下,它指定根URL(/
)下的所有内容都应映射到给定地址的后端服务器。 例如,如果Apache获取/example
的请求,它将连接到http:// your_backend_server /example
并将响应返回到原始客户端。ProxyPassReverse
应该具有与ProxyPass相同的ProxyPass
。它告诉Apache修改后端服务器的响应头。这可以确保如果后端服务器返回一个位置重定向头,客户端的浏览器将被重定向到代理地址,而不是后端服务器地址,这将无法正常工作。
sudo systemctl restart httpd
现在,如果您在网络浏览器中访问
http:// your_server_ip
,您将看到后端服务器响应,而不是标准的Apache欢迎页面。 如果你遵循第2步,这意味着你会看到
和谐的世界! 。
示例2 - 跨多个后端服务器的负载平衡
如果您有多个后端服务器,当代理使用mod_proxy的负载平衡功能时,一种很好的方法来分配它们之间的流量。 将VirtualHost
块中的所有内容替换为以下内容,因此您的配置文件如下所示:
/etc/httpd/conf.d/default-site.conf
<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>
配置与上一个类似,但是不是直接指定单个后端服务器,而是使用了一个额外的
Proxy
块来定义多个服务器。 块名为
balancer:// mycluster
(名称可以自由更改),并由一个或多个
BalancerMember
组成,用于指定底层后端服务器地址。
ProxyPass
和
ProxyPassReverse
指令使用名为
mycluster
的负载平衡器池,而不是特定的服务器。 如果在第2步中
127.0.0.1:8080
示例服务器,请使用
127.0.0.1:8080
和
127.0.0.1:8081
作为
BalancerMember
伪指令,如上面的
BalancerMember
所写。如果您有自己的应用程序服务器,请改用其地址。 要使这些更改生效,请重新启动Apache。
sudo systemctl restart httpd
如果您在网络浏览器中访问
http:// your_server_ip
,您将看到后端服务器的响应,而不是标准的Apache页面。 如果你按照第2步,多次刷新页面应该显示
Hello world! 和
高兴的世界! ,意味着反向代理工作,并在两个服务器之间的负载平衡。
结论
您现在知道如何将Apache设置为一个或多个底层应用程序服务器的反向代理。mod_proxy
可以有效地配置以大量语言和技术编写的应用程序服务器的逆向代理,例如Python和Django或Ruby和Ruby on Rails。它还可用于平衡多个后端服务器上的流量,以便为具有大量流量的站点提供高可用性,或者为不支持SSL的后端服务器提供安全的SSL支持。 虽然
mod_proxy
与
mod_proxy_http
是可能最常用的模块组合,但还有其他几个支持不同的网络协议。我们没有在这里使用它们,但其他一些流行的模块包括:
mod_proxy_ftp
用于FTP。mod_proxy_connect
用于SSL隧道。mod_proxy_ajp
用于AJP(Apache JServ协议),如基于Tomcat的后端。- web套接字的
mod_proxy_wstunnel
。
mod_proxy
更多信息,您可以阅读
官方Apache mod_proxy
文档 。