用Nginx反向代理将请求转移到相关服务器,并记录客户的请求头。

369 阅读3分钟

在这个例子中,我们将使用Nginx的反向代理功能,将传入的请求转发给相关的应用服务器。我们将检查请求的URL,并决定将请求转发给哪个应用程序。如果你不想将你的内部网络暴露在互联网上,这种方法经常被使用。解决方案是有一个单一的服务器,让它为你处理流量。这个例子是基于Docker容器的,所有的容器都在一台Linux机器上运行。欲了解更多信息,请阅读Nginx反向代理页面。

流程

我们的网络上有3个私人应用服务器(Authentication,RestfulWebsite )和1个公共Nginx反向代理服务器(Gateway )。

正如你所看到的,所有的请求都进入了 "网关 "nginx服务器,然后根据请求的URL决定将流量转发到哪里。

  • /aut/* 的请求被转发到 "认证 "应用服务器。

  • /api/* 的请求被转发到 "restful "应用服务器。

  • /web/* 的请求被转发到 "网站 "应用服务器。

任何其他不匹配的请求URL会导致 "404错误请求 "的响应。

注意事项

  • 公共网关服务器应该开放给互联网访问,并使用HTTPS,而不是HTTP - 我保留HTTP只是为了演示。

  • 从互联网直接访问所有其他的私人服务器必须被阻止。根据要求,HTTP和HTTPS都可以被启用。目前,网关服务器将所有请求引向HTTP,只是为了演示。

  • 所有私人服务器将记录Gateway服务器的请求ID以及它们自己的请求ID。

  • 实际的客户端和代理服务器相关的信息将被传递给私人服务器,并将在全局$_SERVER 变量中作为HTTP_X_**** headers和环境变量提供。见下面的 "可选 "Symfony例子。

  • 这个例子使用Docker容器,所有的Nginx服务器日志都被发送到stdout ,所以如果你愿意,可以使用$ docker logs -f {nginx_container_name} 命令来阅读日志。

  • 为了提供更好的可读性,Nginx日志是以JSON格式写入应用服务器的。

要求

  • 网关的请求ID被转发到应用服务器,这样它就会在日志文件中出现,以及应用服务器的实际请求ID。这有助于我们跟踪客户端的请求和它的端到端旅程。**注意:**在收到Gateway的请求后,如果一个应用程序调用另一个应用程序,请确保在请求头中添加x-request-trace-id 头,否则将失去跟踪。

  • Gateway的请求ID会作为响应头的一部分发回给客户端。这也有助于我们找到与客户请求相关的日志,否则我们就不知道哪个日志属于哪个用户的请求。

可选的

如果你想在Symfony应用程序中记录来自Nginx的任何自定义头文件数据,你可以做以下事情。

# service.yaml
# Custom logger
# The log

你也可以在相关的类中使用$request->headers->get('x-request-*****') 方法,如控制器、事件监听器等。

Docker

私人应用服务器使用 "docker compose",因为每个服务器上都有Nginx和PHP-FPM容器。然而,公共Nginx代理服务器本身就是一个Nginx容器,所以它只是一个 "Dockerfile "解决方案。

$ docker ps

我们使用下面的命令来构建和运行Nginx反向代理服务器。

$ docker build -t gateway:nginx .

如果你想直接在主机操作系统上测试所有这些服务器,你可以使用以下命令。

# AUTHENTICATION

我们的主机Debian OS服务器的IP地址是192.168.99.30 ,所以你可以使用下面的地址来访问公共网关反向代理服务器。

http://192.168.99.30:8080/{aut|api|web}/*

文件

网关

Docker文件
FROM nginx:1.15.8-alpine
app.conf
server {
nginx.conf
user nginx;

身份验证

其他两个应用服务器的文件是一样的,所以我不会添加这些。然而,显然只有docker相关文件中的小部分内容不同。比如说。(aut, api, web)和暴露的端口。我也不会添加PHP-FPM文件,因为它们不相关。

docker-compose.yml
version: "3"
Docker文件
FROM nginx:1.15.8-alpine
app.conf
server {
nginx.conf
user nginx;

测试和日志

在HTTP和HTTPS日志之间没有真正的区别,所以我只添加HTTP日志以保持博客的简短。还要注意针对 "直接访问 "和 "网关访问 "的日志条目,因为它们携带的信息非常不同。我们感兴趣的是与 "网关访问 "有关的日志,因为它将是生产中的一个。

直接访问

我们直接访问应用服务器,不通过网关代理服务器。

$ curl -i "http://localhost:5080" # Authentication

网关访问

我们正在访问Gateway代理服务器,这就是生产中的情况。

$ curl -i "http://localhost:8080/aut/" # Authentication

我的docker设置是在Vagrant盒子上运行的,所以我是通过在主机操作系统的浏览器中通过http://192.168.99.30:8080 来测试的。

http://192.168.99.30:8080/aut/ # Authentication

在这个例子中,我用 "ngrok "打开了我的主机到互联网,所以我通过在主机的浏览器中通过http://b119fda7.ngrok.io ,指向192.168.99.30:8080 来测试它。 下面的日志是最像生产的日志。

http://b229fda7.ngrok.io/aut/ # Authentication