Nginx流量同时转发多后端(流量镜像分发)

 更新时间:2024年10月24日 09:21:56   作者:GEEK JUMP  
在需要同时将请求转发至多个后端服务的场景中,Nginx的mirror模块提供了流量镜像分发的功能,本文就来介绍一下Nginx流量同时转发多后端(流量镜像分发),感兴趣的可以了解一下

一、背景

请注意,我这里标题提到的是一个请求流量被同时转发到2个或者多个后端,而非负载均衡的场景!!!

负载均衡的场景我想就不用赘述了,定义一个upstrem, upstrem定了一组提供相同服务的server地址, 最后通过proxy_pass转发到这个upstrem。  但是,这个是负载均衡的场景,那就意味着,无论你的算法如何,最终只会转发到一个server目标上。

那文章标题提到的流量镜像是什么场景呢?  那就是一次HTTP请求,被同时转发到多个后端。 例如一次请求,既代理到A服务、也代理到B服务,发送了2次或者n次的情况。

为什么有这个流量镜像分发需求呢?  我们有这么一个场景, 由于新版服务和旧版服务的代码变更, 出于某种原因,既想保留旧版、也想保留新版做过渡, 所以想把前端的流量分发2次,这样新旧系统的数据都能保存下来,不影响业务使用。 等过段时间,过渡期好了之后,再把旧版server下掉。

寻找了一些资料,openresty+lua也许能实现,但是我测试不行。 最终发现了Nginx本身就有这个功能模块。 这个就是mirror模块。

二、Nginx mirror模块

mirror模块从Nginx1.13开始就是内置了,所以只要是1.13版本以后就可以直接使用,不需要重新编译nginx。

官方文档地址: Module ngx_http_mirror_module

从配置样例来看,很简单。 首先代理的location / 还是先做主代理站点, proxy_pass到$backend,  之后再加一个mirror  /mirror;  流量镜像分发到/mirror的URL,  再看下面定了了/mirror的location定义, 这里面再次定义proxy_pass 到test_backend, 从而完成流量镜像分发的目的。

三、实际配置测试

1、准备2个flask服务,8081、8082端口

1、flask-8081.py

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/api/data', methods=['GET', 'POST'])
def save_request_data():
    headers = dict(request.headers)
    if request.is_json:
        # 如果请求体是 JSON 格式
        body = request.get_json(silent=True)
    elif request.content_type and 'form' in request.content_type.lower():
        # 如果请求体是表单数据
        body = request.form.to_dict()
    else:
        # 其他类型的请求体(例如纯文本)
        body = request.data.decode('utf-8')
    args = request.args.to_dict()
    data = {
        "headers": headers,
        "body": body,
        "args": args
    }
    with open('request_data.txt', 'a') as file:
        file.write(str(data))
        file.write('\n')
    return jsonify({
        "status": "success",
        "message": "Data has been saved."
    })


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081, debug=True)

2、flask-8082.py

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/api/data', methods=['GET', 'POST'])
def save_request_data():
    headers = dict(request.headers)
    if request.is_json:
        # 如果请求体是 JSON 格式
        body = request.get_json(silent=True)
    elif request.content_type and 'form' in request.content_type.lower():
        # 如果请求体是表单数据
        body = request.form.to_dict()
    else:
        # 其他类型的请求体(例如纯文本)
        body = request.data.decode('utf-8')
    args = request.args.to_dict()
    data = {
        "headers": headers,
        "body": body,
        "args": args
    }
    with open('request_data.txt', 'a') as file:
        file.write(str(data))
        file.write('\n')
    return jsonify({
        "status": "success",
        "message": "Data has been saved."
    })


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8082, debug=True)

2、修改nginx的配置文件

    location /api/data/ {
       #优先转发172.16.0.3:8081
       proxy_pass http://172.16.0.3:8081/api/data;
       #同时, 流量镜像转发到/mirror/, 172.16.0.3:8082
       mirror /mirror/;
    }
    location /mirror/ {
       internal;
       proxy_pass http://172.16.0.3:8082/api/data;
    }

3、测试结果

CURL请求代理的nginx端口,然后分别查看8081、8082端口是否同时接收到相同的HTTP请求: 

观察8081端口程序日志输出:

观察8082端口程序日志 输出:

由此发现,我们在nginx发生的2次请求, 2个后端8081、8082同时收到了2次请求。 由此证明,我们的流量镜像分发是符合预期的。

 4、最终响应内容是8081还是8082的内容?

结论:   一切都以第一个proxy_pass的站点的实际响应结果为准,不管第二个被mirror流量分发站点的响应情况是否正常

服务运行情况以及响应信息表格如下:

8081 正常8082正常以8081内容为准, 正常, 2台都会转发
8081 正常8082异常以8081内容为准, 正常,  8082不会在后台转发
8081 异常8082正常以8081内容为准, 异常, 8082会在后台转发
8081 异常8082异常以8081内容为准, 异常, 8082不会在后台转发

四、总结

mirror流量镜像分发的场景还是有实际存在意义的,要不然官方也不会把它纳入到内置模块当中。具体的需求情况需要自己判定。

流量转发毕竟是2次转发过程,对于nginx的压力、以及性能应该是会有损耗的,但是具体损耗没测试过, 这个读者朋友可以自行测试。

到此这篇关于Nginx流量同时转发多后端(流量镜像分发)的文章就介绍到这了,更多相关Nginx 流量镜像分发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Nginx服务器下配置使用索引目录的教程

    Nginx服务器下配置使用索引目录的教程

    这篇文章主要介绍了Nginx服务器下配置使用索引目录的教程,包括自带的auto_index和使用fancy插件美化的用法,需要的朋友可以参考下
    2016-01-01
  • Nginx安装及具体应用小结

    Nginx安装及具体应用小结

    Nginx 动静分离简单来说就是把动态请求跟静态请求分开,Nginx 处理静态请求,Tomcat处理动态请求,这篇文章主要介绍了Nginx安装及具体应用小结,需要的朋友可以参考下
    2024-02-02
  • nginx请求时找路径问题解决

    nginx请求时找路径问题解决

    当你安装了nginx的时候,为nginx配置了如下的location,想要去访问路径下面的内容,可是总是出现404,找不到文件,这是什么原因呢,今天我们就来解决这个问题,感兴趣的朋友一起看看吧
    2023-10-10
  • Linux环境下nginx搭建简易图片服务器

    Linux环境下nginx搭建简易图片服务器

    这篇文章主要介绍了Linux环境下nginx搭建简易图片服务器,需要的朋友可以参考下
    2014-10-10
  • nginx-rtmp-module构建流媒体直播服务器实战指南

    nginx-rtmp-module构建流媒体直播服务器实战指南

    本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • Nginx配置移动端和PC端自动跳转方式

    Nginx配置移动端和PC端自动跳转方式

    文章介绍了如何通过Nginx配置PC端和移动端自动跳转,PC端和移动端各有独立的域名,PC端访问任何域名时会跳转到www.yxf.com,移动端访问任何域名时会跳转到m.yxf.com,配置时需要修改Nginx的conf文件,使用302或301重定向
    2025-11-11
  • 聊聊Django+uwsgi+nginx服务器部署问题

    聊聊Django+uwsgi+nginx服务器部署问题

    这篇文章主要介绍了Django+uwsgi+nginx服务器部署的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • Nginx配置本地图片服务器的实现

    Nginx配置本地图片服务器的实现

    本文主要介绍了Nginx配置本地图片服务器的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • 解决Nginx 配置 proxy_pass 后 返回404问题

    解决Nginx 配置 proxy_pass 后 返回404问题

    这篇文章主要介绍了Nginx 配置 proxy_pass 后 返回404问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • nginx反向代理proxy_set_header

    nginx反向代理proxy_set_header

    这篇文章主要介绍了nginx反向代理proxy_set_header,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06

最新评论