当前位置: 首页 > news >正文

如何使用ngxin的 upstream

1.引言:

1.1反向代理:

反向代理是充当Web服务器网关的代理服务器。当您将请求发送到使用反向代理的Web服务器时,他们将先转到反向代理,由该代理将确定是将其路由到Web服务器还是将其阻止。

这意味着有了反向代理,您永远不会与使用它的Web服务器进行直接通信。可以将它们看作web服务器或服务器集群的某种包装器。通过负载平衡和缓存,它们可以保护web免遭攻击,并提供更好的web性能

1.2ngxin访问第三方服务:

Nginx提供了两种全异步方式来与第三方服务器通信:upstream与subrequest。

1.2.1upstream

可以保证在与第三方服务器交互时(包括三次握手建立TCP连接、 发送请求、 接收响应、 四次握手关闭TCP连接等) 不会阻塞Nginx进程处理其他请求, 也就是说, Nginx仍然可以保持它的高性能

1.2.2:subrequest

只是分解复杂请求的一种设计模式, 它本质上与访问第三方服务没有任何关系,但从HTTP模块开发者的角度而言, 使用subrequest访问第三方服务却很常用, 当然,subrequest访问第三方服务最终也是基于upstream实现的

1.2.3:两者的区别

从名称中可以看出, upstream被定义为访问上游服务器, 也就是说, 它把Nginx定义为代理服务器, 首要功能是透传, 其次才是以TCP获取第三方服务器的内容。 Nginx的HTTP反向代理模块就是基于upstream方式实现的

顾名思义, subrequest是从属请求的意思, 在这里我们更倾向于称它为子请求, 也就是说,subrequest将会为客户请求创建子请求, 这是为什么呢? 因为异步无阻塞程序的开发过于复
杂, 所以HTTP框架提供了这种机制将一个复杂的请求分解为多个子请求, 每个子请求负责
一种功能, 而最初的原始请求负责构成并发送响应给客户端.

综合举例子:

用subrequest访问第三方服务, 一般都是派生出子请求访问上游服务器, 父请求在完全取得上游服务器的响应后再决定如何处理来自客户端的请求。 这样做的好处是每个子请求专注于一种功能。 例如, 对于一个子请求, 通常在NGX_HTTP_CONTENT_PHASE阶段仅会使用一个HTTP模块处理, 这大大降低了模块开发的复杂度。 从HTTP框架的内部来说, subrequest与upstream也完全不同,upstream是从属于用户请求的, subrequest与原始的用户请求相比是一个(或多个) 独立的新请求, 只是新的子请求与原始请求之间可以并发的处理。

2.upstream的使用方法:

2.1ngxin的核心功能-反向代理举例

反向代理模块是在先接收完客户请求的HTTP包体后, 才向上游服务器建立连接并转
发请求的
。 假设用户要上传大小为1GB的文件, 由于网速限制, 文件完整地到达Nginx需要
10小时, 恰巧Nginx与上游服务器间的网络也很差(当然这种情况很少见) , 反向代理这个
请求到上游服务也需要10小时, 因此, 根据用户的网速也许本来只要10个小时的上传过程,
最终可能需要20个小时才能完成

2.2 upstream的工作机制

 

1) 首先需要创建上面介绍的upstream成员, 注意,upstream在初始状态下是NULL空指
针。 可以调用HTTP框架提供好的ngx_http_upstream_create方法来创建upstream。

upstream 存在于一个ngx_http_request_t r中:

typedef struct ngx_http_request_s ngx_http_request_t; 
struct ngx_http_request_s {
… 
ngx_http_upstream_t *upstream;
…
};

2) 接着设置上游服务器的地址。在HTTP反向代理功能中似乎只能使用在nginx.conf中配置好的上游服务器 ,而实际上upstream机制并没有这种要求,用户能够以任意方式指定上游服务器的IP地址。 例如, 可以从请求的URL或HTTP头部中动态地获取上游服务器地址, ngx_http_upstream_t中的resolved成员就可以帮助用户设置上游服务器


3) 由于upstream非常灵活, 在各个执行阶段中都会试图回调使用它的HTTP模块实现的8
个方法 , 用户要定义好这些回调方法。

4) 在http模块中, 调用ngx_http_upstream_init方法即可启动upstream机制。 注意,自己的模板回调方法此时必须返回NGX_DONE, 这是在要求HTTP框架不要按阶段继续向下处理请求了, 同时它告诉HTTP框架请求必须停留在当前阶段, 等待某个HTTP模块主动地继续处理这个请求(例如, 在上游服务器主动关闭连接时, upstream模块就会主动地继续处理这个请求, 很可能会向客户端发送502响应码)。
 

2.3upstream的执行机制

下图所示的upstream流程包含了epoll模块多次调度、 处理一个请求的过程, 它虽然与实
际代码执行关系不大, 但却指出了最常用的3个回调方法——create_request、
process_header、 finalize_request是如何回调的。

 

2.4 结ngx_http_upstream_t 结构体

typedef struct ngx_http_upstream_s ngx_http_upstream_t; 
struct ngx_http_upstream_s {
… ngx_chain_t *request_bufs; ngx_http_upstream_conf_t *conf;ngx_http_upstream_resolved_t *resolved;ngx_buf_t buffer;// 构造发往上游服务器的请求内容
ngx_int_t (*create_request)(ngx_http_request_t *r); ngx_int_t (*process_header)(ngx_http_request_t *r); 
// 销毁upstream请求时调用void (*finalize_request)(ngx_http_request_t *r, ngx_int_t rc); // 5个可选的回调方法
ngx_int_t (*input_filter_init)(void *data); 
ngx_int_t (*input_filter)(void *data, ssize_t bytes);
....//SSL协议访问上游服务器
unsigned ssl:1;unsigned buffering:1; …};

结构成员简介:

1.ngx_chain_t *request_bufs;

request_bufs决定发送什么样的请求给上游服务器, 在实现create_request方法时需要设置它

2.conf and resolve 

一个限制参数 另外一个是解析参数

3.ngx_buf_t buffer;

 buffer成员存储接收自上游服务器发来的响应内容, 由于它会被复用, 所以具有下列多种意义:

a)在使用process_header方法解析上游响应的包头时,buffer中将会保存完整的响应包头;

b)当下面的buffering成员为1, 而且此时upstream是向下游转发上游的包体时,buffer没有意义;

c)当buffering标志位为0时,buffer缓冲区会被用于反复地接收上游的包体, 进而向下游转发;

d)当upstream并不用于转发上游包体时,buffer会被用于反复接收上游的包体,HTTP模块实现的input_filter方法需要关注它

4.ngx_int_t (*process_header)(ngx_http_request_t *r); 

收到上游服务器的响应后就会回调process_header方法。 如果process_header返NGX_AGAIN, 那么是在告诉upstream还没有收到完整的响应包头, 此时, 对于本次upstream请求来说, 再接收到上游服务器发来的TCP流时, 还会调用process_header方法处理, 直到process_header函数返回非NGX_AGAIN值这一阶段才会停止

5.unsigned buffering:1;

在向客户端转发上游服务器的包体时才有用。 当buffering为1时, 表示使用多个缓冲区以及磁盘文件来转发上游的响应包体。当Nginx与上游间的网速远大于Nginx与下游客户端间的网速时, 让Nginx开辟更多的内存甚至使用磁盘文件来缓存上游的响应包体, 这是有意义的, 它可以减轻上游服务器的并发压力。

当buffering为0时, 表示只使用上面的这一个
buffer缓冲区来向下游转发响应包体
 

总的解析:

upstream有3种处理上游响应包体的方式, 但HTTP模块如何告诉upstream使用哪一种方式处理上游的响应包体呢?

当请求的ngx_http_request_t结构体中subrequest_in_memory标志位为1时, 将采用第1种方式, 即upstream不转发响应包体到下游,由HTTP模块实现的input_filter方法处理包体;

当subrequest_in_memory为0时, upstream会转发响应包体。

当ngx_http_upstream_conf_t配置结构体中的buffering标志位为1时, 将开启更多的内存和磁盘文件用于缓存上游的响应包体, 这意味上游网速更快;

当buffering为0时, 将使用固定大小的缓冲区(就是上面介绍的buffer缓冲区) 来转发响应包体

2.5解析conf

ngx_http_upstream_t中的conf成员, 它用于设置upstream模块处理请求时的参数, 包括连接、 发送、 接收的超时时间等。

typedef struct {
… 
//连接上游服务器的超时时间, 单位为毫秒
ngx_msec_t connect_timeout; // 发送TCP包到上游服务器的超时时间, 单位为毫秒
ngx_msec_t send_timeout;// 接收TCP包到上游服务器的超时时间, 单位为毫秒
ngx_msec_t read_timeout;…} ngx_http_upstream_conf_t;

事实上,HTTP反向代理模块在nginx.conf文件中提供的配置项大都是用来设置ngx_http_upstream_conf_t结构体中的成员的。 上面列出的3个超时时间是必须要设置的, 因为它们默认为0, 如果不设置将永远无法与上游服务器建立起TCP连接(因为connect_timeout值为0) 。
 

接下来以设置connect_timeout连接超时时间为例说明如何编写ngx_command_t来读取配置
文件

static ngx_command_t ngx_http_mytest_commands[] ={…{ ngx_string("upstream_connect_timeout"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
NGX_HTTP_LOC_CONF_OFFSET,
/*给出
connect_timeout成员在
ngx_http_mytest_conf_t结构体中的偏移字节数
*/offsetof(ngx_http_mytest_conf_t, upstream.connect_timeout), NULL },…
}


效果:nginx.conf文件中的upstream_conn_timeout配置项将被解析到ngx_http_mytest_conf_t
结构体的upstream.connect_timeout成员中。 在处理实际请求时, 只要把ngx_http_mytest_conf_t
配置项的upstream成员赋给ngx_http_upstream_t中的conf成员即

ngx_http_mytest_conf_t *mycf =
(ngx_http_mytest_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_mytest_module_t)


2.6设置需要访问的第三方服务器

ngx_http_upstream_t结构中的resolved成员可以直接设置上游服务器的地址。

首先介绍一下resolved的类型。

typedef struct {
… 
//
地址个数
ngx_uint_t naddrs;
// 上游服务器的地址
struct sockaddr *sockaddr;socklen_t socklen;
…
} ngx_http_upstream_resolved_t;


 

相关文章:

如何使用ngxin的 upstream

1.引言: 1.1反向代理: 反向代理是充当Web服务器网关的代理服务器。当您将请求发送到使用反向代理的Web服务器时,他们将先转到反向代理,由该代理将确定是将其路由到Web服务器还是将其阻止。 这意味着有了反向代理,您…...

Java数组,超详细整理,适合新手入门

目录 一、什么是Java中的数组? 二、数组有哪些常见的操作? 三、数组的五种赋值方法和使用方法 声明数组 声明数组并且分配空间 声明数组同时赋值(1) 声明数组同时赋值(2) 从控制台输入向数组赋值 四、求总和平均 五、求数组中最大值最小值 六…...

1.3数据传输控制方式:IO数据传输控制方式、程序控制(查询)方式、程序中断方式、DMA方式、通道方式、I/O处理机

1.3数据传输控制方式:IO数据传输控制方式、程序控制(查询)方式、程序中断方式、DMA方式、通道方式、I/O处理机程序控制(查询)方式程序中断方式DMA方式通道方式、I/O处理机I/O数据传输方式,由软件到硬件发展…...

Linux 设置语言

文章目录1. 临时设置环境变量2. 默认语言设置3. 语言包4. 安装浏览器 chromium1. 临时设置环境变量 通过设置环境变量,可以使单个命令使用另一种语言LANG $ LANGfr_FR.utf8 date mar. mai 24 12:16:51 CDT 2022后续命令将恢复为使用系统的默认语言进行输出。该loc…...

Python基础-数据类型之集合

一、集合的定义 集合:是一个无序的没有重复元素的序列,因此不能通过索引来进行操作 1:使用set()创建集合 set(object) # 参数为一个序列,整型不能作为参数 set_a set("abcb") print(set_a) # {b, a, c} 2&…...

[Css]Grid属性简单陈列(适合开发时有基础的快速过一眼)

[css进阶]Grid属性简介 文章目录[css进阶]Grid属性简介典型需求网格容器的属性displaygrid-template-columns和grid-template-rowsgrid-template-areasgrid-templategrid-column-gap grid-row-gapgrid-gapjustify-itemsalign-itemsjustify-contentalign-contentgrid-auto-colum…...

100种思维模型之启发式偏差思维模型-017

曾国藩在给儿子的一封家书中曾写道:余于凡事皆用困知勉行工夫,尔不可求名太骤,求效太捷也。熬过此关,便可少进。再进再困,再熬再奋,自有亨通精进之日。 不急躁不求捷径,小火慢炖,将事…...

微服务 feign远程调用时 显示服务不可用 timed-out and no fallback

目录 第一种: failed and no fallback available 1 服务挂掉了 2 服务没有开启 3 注册中心没注册进去 -> ps: 直接调用的接口 通过网关转发失败 会报503 4 高并发下的服务熔断了 第二种: timed-out and no fallback 2.1 业务场景: A服务一切正常 但是B服务显示timeo…...

第一个Java程序(初识Java)

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 文章目录1.Java概述1.1什么是Java1.2Java之父2.0第一个Java程序编译运行.class3.0程序如何跑起来的?3.1J…...

vulnhub LordOfTheRoot_1.0.1

总结:端口敲门,CVE-2015-8660提权, 目录 下载地址 漏洞分析 信息收集 端口敲门 网站分析 方法一 ssh登录提权 方法二 下载地址 LordOfTheRoot_1.0.1.ova (Size: 1.6 GB)Download: http://www.mediafire.com/download/m5tbx0dua05szjm…...

MutationObserver与IntersectionObserver

MutationObserver 出现原因:当我们需要监听元素发生变化时,不借助使元素发生变化的业务动作的情况下,使用无污染方式监听非常困难,为了解决这个问题,MutationObserver诞生! 概述 可以用来监听DOM的任何变化…...

【ESP 保姆级教程】玩转巴法云篇② ——MQTT设备云,MQTT协议下的数据通信

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-21 ❤️❤️ 本篇更新记录 2023-02-21 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...

植物大战 仿函数——C++

容器适配器 容器适配器不支持迭代器。栈这个东西,让你随便去遍历,是不好的。他是遵循后进先出的。所以他提供了一个街头top取得栈顶数据。 仿函数 仿函数(functor)是C中一种重载了函数调用运算符(operator()&#x…...

【C语言】浮点型数据在内存中的存储

🚀🚀🚀 如果文章对你有帮助不要忘记点赞关注收藏哦🚀🚀🚀 文章目录⭐浮点数在内存中的存储1.1 🤓举个例子:1.2浮点数存储规则🌈:对于M与E有一些特别规定1.3解释前面题目&…...

impala中的刷新元数据和刷新表

impala是Cloudera公司主导开发的新型查询系统,它提供SQL语义,能查询存储在Hadoop的HDFS和HBase中的PB级大数据。 虽然Hive系统也提供了SQL语义,但由于Hive底层执行使用的是MapReduce引擎,仍然是一个批处理过程,难以满…...

Vscode创建vue项目的详细步骤

目录 一、概述 操作的前提 二、操作步骤 一、概述 后端人员想在IDEA里面创建一个Vue的项目,但是这非常麻烦,用vscode这个前端专用软件创建就会非常快速。 操作的前提 1.安装vscode软件的步骤:vscode下载和安装教程和配置中文插件&#…...

如何在面试中介绍自己的项目,才能让软件测试面试官无可挑剔,

四、项目 4.1 简单介绍下最近做过的项目 根据自己的项目整理完成,要点: 1)项目背景、业务、需求、核心业务的流程 2)项目架构,B/S还是C/5,数据库用的什么? 中间件用的什么?后台什么语言开发…...

虹科方案|从 uCPE 到成熟的边缘计算平台

基于开放硬件平台,通用客户端设备 (uCPE) 支持快速添加、集成或删除任意数量的集中管理虚拟功能。 为了增加收入并保持竞争优势,托管服务提供商 (MSP) 和企业正在部署 uCPE 以增强业务敏捷性、加速新服务的引入并提高运营效率。最初,uCPE被部…...

计算机是怎么读懂C语言的?

文章目录前言程序环境翻译环境翻译环境分类编译预处理预处理符号预定义符号#define#undef命令行定义条件编译文件包含头文件包含查找规则嵌套文件包含其他预处理指令编译阶段汇编链接🎉welcome🎉 ✒️博主介绍:博主大一智能制造在读&#xff…...

hadoop入门介绍及各组件功能运行关系

文章目录Hadoop 组成部分1.HDFS2.MapReduce 架构概述3. yarn 架构概述4.HDFS、YARN、MapReduce三者关系Hadoop 组成部分 1.HDFS Hadoop Distributed File System,简称 HDFS,是一个分布式文件系统。 HDFS 架构概述 主要分为 NameNode (mn):存储文件的元…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

如何在网页里填写 PDF 表格?

有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据&#xff…...