如何在CentOS7上使用Apache作为带有mod proxy的反向代理

来自菜鸟教程
跳转至:导航、​搜索

介绍

反向代理 是一种代理服务器,它接受 HTTP(S) 请求并将它们透明地分发到一个或多个后端服务器。 反向代理很有用,因为许多现代 Web 应用程序使用后端应用程序服务器处理传入的 HTTP 请求,这些后端应用程序服务器并不意味着用户可以直接访问,并且通常只支持基本的 HTTP 功能。

您可以使用反向代理来防止这些底层应用程序服务器被直接访问。 它们还可用于将来自传入请求的负载分配到多个不同的应用程序服务器,从而大规模提高性能并提供故障安全性。 它们可以使用应用程序服务器不提供的功能来填补空白,例如缓存、压缩或 SSL 加密。

在本教程中,您将使用 mod_proxy 扩展将 Apache 设置为基本反向代理,以将传入连接重定向到在同一网络上运行的一个或多个后端服务器。 本教程使用使用 Flask Web 框架 编写的简单后端,但您可以使用任何您喜欢的后端服务器。

先决条件

要遵循本教程,您将需要:

  • 使用 this initial server setup tutorial 设置的一台 CentOS 7 服务器,包括 sudo 非 root 用户。
  • 按照 如何在 CentOS 7 上安装 Linux、Apache、MySQL、PHP (LAMP) 堆栈的第 1 步在您的服务器上安装 Apache 2。
  • 可选地,与 yum install nano 一起安装的 nano 文本编辑器。 CentOS 默认自带 vi 文本编辑器,但 nano 可以更人性化。

第 1 步 — 介绍必要的 Apache 模块

使用 Apache 作为反向代理所需的模块包括 mod_proxy 本身和它的几个附加模块,这些附加模块扩展了它的功能以支持不同的网络协议。 具体来说,我们将使用:

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

在全新的 CentOS 7 安装中默认启用所有四个模块。 您可以通过运行来验证它们是否已启用:

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!,另一台服务器会说 Hello world!

注意: 在非测试设置中,后端服务器通常都返回相同类型的内容。 但是,特别是对于这个测试,让两台服务器返回不同的消息可以很容易地检查负载平衡机制是否同时使用了这两个服务器。


Flask 是一个用于构建 Web 应用程序的 Python 微框架。 我们使用 Flask 来创建测试服务器,因为一个基本的应用程序只需要几行代码。 你不需要知道 Python 来设置这些,但是如果你想学习,你可以看看这些 Python 教程

让我们先安装 IUS 包存储库文件。 IUS (Inline with Upstream Stable) 是一个社区项目,它为 CentOS 提供最新版本的精选软件,包括 Python 3。

sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm

然后安装 Python 3 和推荐的 Python 包管理器 Pip。

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()' 的返回值作为对指向 / 根的 HTTP 请求的响应应用程序的 URL。

第二个后端服务器与第一个完全相同,只是返回到不同的文本行,所以从复制第一个文件开始。

cp ~/backend1.py ~/backend2.py

打开新复制的文件。

nano ~/backend2.py

将要返回的消息从 Hello world! 更改为 Howdy 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_APP 环境变量,在 flask 命令之前。 环境变量是一种将信息传递到从 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 上为 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。 如果您有自己的应用程序服务器,请改用它们的地址。

这里有三个指令:

  • ProxyPreserveHost 使 Apache 将原始的 Host 标头传递给后端服务器。 这很有用,因为它使后端服务器知道用于访问应用程序的地址。
  • ProxyPass 是主要的代理配置指令。 在这种情况下,它指定根 URL (/) 下的所有内容都应映射到给定地址的后端服务器。 例如,如果 Apache 收到对 /example 的请求,它将连接到 http://your_backend_server/example 并将响应返回给原始客户端。
  • ProxyPassReverse 应该与 ProxyPass 具有相同的配置。 它告诉 Apache 修改来自后端服务器的响应标头。 这确保如果后端服务器返回位置重定向标头,客户端的浏览器将被重定向到代理地址而不是后端服务器地址,这将无法按预期工作。

要使这些更改生效,请重新启动 Apache。

sudo systemctl restart httpd

现在,如果您在 Web 浏览器中访问 http://your_server_ip,您将看到后端服务器响应,而不是标准的 Apache 欢迎页面。 如果您按照第 2 步操作,这意味着您将看到 Hellow world!

示例 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 组成,它们指定底层后端服务器地址。 ProxyPassProxyPassReverse 指令使用名为 mycluster 的负载平衡器池而不是特定服务器。

如果您按照步骤 2 中的示例服务器进行操作,请使用 127.0.0.1:8080127.0.0.1:8081 作为 BalancerMember 指令,如上块所述。 如果您有自己的应用程序服务器,请改用它们的地址。

要使这些更改生效,请重新启动 Apache。

sudo systemctl restart httpd

如果您在 Web 浏览器中访问 http://your_server_ip,您将看到后端服务器的响应,而不是标准的 Apache 页面。 如果您按照第 2 步操作,多次刷新页面应该会显示 Hello world!Howdy world!,这意味着反向代理正常工作并且正在两个服务器之间进行负载平衡。

结论

您现在知道如何将 Apache 设置为一个或多个底层应用程序服务器的反向代理。 mod_proxy 可以有效地用于为使用大量语言和技术(例如 Python 和 Django 或 Ruby 和 Ruby on Rails)编写的应用程序服务器配置反向代理。 它还可以用于为具有大量流量的站点平衡多个后端服务器之间的流量,或通过多个服务器提供高可用性,或者为本身不支持 SSL 的后端服务器提供安全的 SSL 支持。

虽然 mod_proxymod_proxy_http 可能是最常用的模块组合,但还有其他几种支持不同的网络协议。 我们在这里没有使用它们,但其他一些流行的模块包括:

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

要了解更多关于mod_proxy的信息,您可以阅读官方Apache mod_proxy文档