我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Nginx中的upstream模块如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Nginx中的upstream模块如何使用

这篇文章主要介绍“Nginx中的upstream模块如何使用”,在日常操作中,相信很多人在Nginx中的upstream模块如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Nginx中的upstream模块如何使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

upstream模块简介

  • nginx模块一般被分成三大类:handler、filter和upstream。前面的章节中,读者已经了解了handler、filter。利用这两类模块,可以使nginx轻松完成任何单机工作。

  • 而upstream模块,将使nginx跨越单机的限制,完成网络数据的接收、处理和转发。

  • 数据转发功能,为nginx提供了跨越单机的横向处理能力,使nginx摆脱只能为终端节点提供单一功能的限制,使它具备了网络应用级别的拆分、封装和整合的功能。

  • 数据转发是nginx有能力构建一个网络应用的关键组件。当然,鉴于开发成本的问题,一个网络应用的关键组件一开始往往会采用高级编程语言开发。但是当系统到达一定规模,并且需要更重视性能的时候,为了达到所要求的性能目标,高级语言开发出的组件必须进行结构化修改。

此时,对于修改代价而言,nginx的upstream模块体现出了它的优势,因为它天生就快。作为附带,nginx的配置系统提供的层次化和松耦合使得系统的扩展性也达到比较高的程度。

upstream模块接口

从本质上说,upstream属于handler,只是他不产生自己的内容,而是通过请求后端服务器得到内容,所以才称为upstream(上游)。请求并取得响应内容的整个过程已经被封装到nginx内部,所以upstream模块只需要开发若干回调函数,完成构造请求和解析响应等具体的工作。

upstream模块回调函数列举如下:

函数名称描述
create_request生成发送到后端服务器的请求缓冲(缓冲链),在初始化upstream 时使用
reinit_request在某台后端服务器出错的情况,nginx会尝试另一台后端服务器。 nginx选定新的服务器以后,会先调用此函数,以重新初始化 upstream模块的工作状态,然后再次进行upstream连接
process_header处理后端服务器返回的信息头部。所谓头部是与upstream server 通信的协议规定的,比如HTTP协议的header部分,或者memcached 协议的响应状态部分
abort_request在客户端放弃请求时被调用。不需要在函数中实现关闭后端服务 器连接的功能,系统会自动完成关闭连接的步骤,所以一般此函 数不会进行任何具体工作
finalize_request正常完成与后端服务器的请求后调用该函数,与abort_request 相同,一般也不会进行任何具体工作
input_filter处理后端服务器返回的响应正文。nginx默认的input_filter会 将收到的内容封装成为缓冲区链ngx_chain。该链由upstream的 out_bufs指针域定位,所以开发人员可以在模块以外通过该指针得到后端服务器返回的正文数据。memcached模块实现了自己的 input_filter,在后面会具体分析这个模块。
input_filter_init初始化input filter的上下文。nginx默认的input_filter_init 直接返回

memcached模块分析

  • memcache是一款高性能的分布式cache系统,得到了非常广泛的应用。memcache定义了一套私有通信协议,使得不能通过HTTP请求来访问memcache。但协议本身简单高效,而且memcache使用广泛,所以大部分现代开发语言和平台都提供了memcache支持,方便开发者使用memcache。

  • nginx提供了ngx_http_memcached模块,提供从memcache读取数据的功能,而不提供向memcache写数据的功能。

upstream模块使用的就是handler模块的接入方式。

同时,upstream模块的指令系统的设计也是遵循handler模块的基本规则:配置该模块才会执行该模块。

那么,upstream模块的特别之处究竟在哪里呢?那就是upstream模块的处理函数,upstream模块的处理函数进行的操作都包含一个固定的流程:(以memcached模块举例,在memcached的处理函数ngx_http_memcached_handler中)

创建upstream数据结构:

ngx_http_upstream_t            *u;if (ngx_http_upstream_create(r) != NGX_OK) {    return NGX_HTTP_INTERNAL_SERVER_ERROR;}u = r->upstream;

设置模块的tag和schema。schema现在只会用于日志,tag会用于buf_chain管理:

ngx_str_set(&u->schema, "memcached://");u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;

设置upstream的后端服务器列表数据结构:

mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);u->conf = &mlcf->upstream;

设置upstream回调函数:

u->create_request = ngx_http_memcached_create_request;u->reinit_request = ngx_http_memcached_reinit_request;u->process_header = ngx_http_memcached_process_header;u->abort_request = ngx_http_memcached_abort_request;u->finalize_request = ngx_http_memcached_finalize_request;   u->input_filter_init = ngx_http_memcached_filter_init;u->input_filter = ngx_http_memcached_filter;

创建并设置upstream环境数据结构:

ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));if (ctx == NULL) {    return NGX_HTTP_INTERNAL_SERVER_ERROR;}ctx->request = r;ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);u->input_filter_ctx = ctx;

完成upstream初始化并进行收尾工作:

r->main->count++;ngx_http_upstream_init(r);return NGX_DONE;

任何upstream模块,简单如memcached,复杂如proxy、fastcgi都是如此。
不同的upstream模块在这6步中的最大差别会出现在第2、3、4、5上。

其中第2、4两步很容易理解,不同的模块设置的标志和使用的回调函数肯定不同。第5步也不难理解。

只有第3步是有点费解的,不同的模块在取得后端服务器列表时,策略的差异非常大,有如memcached这样简单明了的,也有如proxy那样逻辑复杂的。

第6步不同模块之间通常是一致的。将count加1,然后返回NGX_DONE。
nginx遇到这种情况,虽然会认为当前请求的处理已经结束,但是不会释放请求使用的内存资源,也不会关闭与客户端的连接。
之所以需要这样,是因为nginx建立了upstream请求和客户端请求之间一对一的关系,在后续使用ngx_event_pipe将upstream响应发送回客户端时,还要使用到这些保存着客户端信息的数据结构。
将upstream请求和客户端请求进行一对一绑定,这个设计有优势也有缺陷。优势就是简化模块开发,可以将精力集中在模块逻辑上,而缺陷同样明显,一对一的设计很多时候都不能满足复杂逻辑的需要。

回调函数:(依然是以memcached模块的处理函数为例)

  • ngx_http_memcached_create_request:很简单的按照设置的内容生成一个key,接着生成一个“get $key”的请求,放在r->upstream->request_bufs里面。

  • ngx_http_memcached_reinit_request:无需初始化。

  • ngx_http_memcached_abort_request:无需额外操作。

  • ngx_http_memcached_finalize_request:无需额外操作。

  • ngx_http_memcached_process_header:模块的业务重点函数。memcache协议的头部信息被定义为第一行文本,代码如下:

#define LF     (u_char) '\n'for (p = u->buffer.pos; p < u->buffer.last; p++) {    if (*p == LF) {        goto found;    }}

如果在已读入缓冲的数据中没有发现LF(&lsquo;\n&rsquo;)字符,函数返回NGX_AGAIN,表示头部未完全读入,需要继续读取数据。nginx在收到新的数据以后会再次调用该函数。

nginx处理后端服务器的响应头时只会使用一块缓存,所有数据都在这块缓存中,所以解析头部信息时不需要考虑头部信息跨越多块缓存的情况。而如果头部过大,不能保存在这块缓存中,nginx会返回错误信息给客户端,并记录error log,提示缓存不够大。

ngx_http_memcached_process_header的重要职责是将后端服务器返回的状态翻译成返回给客户端的状态。例如:

u->headers_in.content_length_n = ngx_atoof(start, p - start);···u->headers_in.status_n = 200;u->state->status = 200;···u->headers_in.status_n = 404;u->state->status = 404;

u->state用于计算upstream相关的变量。比如u->state->status将被用于计算变量“upstream_status”的值。u->headers_in将被作为返回给客户端的响应返回状态码。而u->headers_in.content_length_n则是设置返回给客户端的响应的长度。

在这个函数中一定要在处理完头部信息以后需要将读指针pos后移,否则这段数据也将被复制到返回给客户端的响应的正文中,进而导致正文内容不正确。

ngx_http_memcached_process_header函数完成响应头的正确处理,应该返回NGX_OK。如果返回NGX_AGAIN,表示未读取完整数据,需要从后端服务器继续读取数据。返回NGX_DECLINED无意义,其他任何返回值都被认为是出错状态,nginx将结束upstream请求并返回错误信息。

ngx_http_memcached_filter_init:修正从后端服务器收到的内容长度。因为在处理header时没有加上这部分长度。

ngx_http_memcached_filter:
memcached模块是少有的带有处理正文的回调函数的模块。
因为memcached模块需要过滤正文末尾CRLF “END” CRLF,所以实现了自己的filter回调函数。

处理正文的实际意义是将从后端服务器收到的正文有效内容封装成ngx_chain_t,并加在u->out_bufs末尾。

nginx并不进行数据拷贝,而是建立ngx_buf_t数据结构指向这些数据内存区,然后由ngx_chain_t组织这些buf。这种实现避免了内存大量搬迁,也是nginx高效的原因之一。

到此,关于“Nginx中的upstream模块如何使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Nginx中的upstream模块如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Nginx中的upstream模块如何使用

这篇文章主要介绍“Nginx中的upstream模块如何使用”,在日常操作中,相信很多人在Nginx中的upstream模块如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Nginx中的upstream
2023-07-05

Tengine如何新增nginx upstream模块

这篇文章主要介绍了Tengine如何新增nginx upstream模块,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。后端长连接超时功能ngx_http_upstream_k
2023-06-04

Nginx中upstream模块的具体用法

本文主要介绍了Nginx中upstream模块的具体用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-14

Nginx反向代理与负载均衡概念及upstream模块如何使用

本篇内容主要讲解“Nginx反向代理与负载均衡概念及upstream模块如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Nginx反向代理与负载均衡概念及upstream模块如何使用”吧!
2023-06-29

Nginx中如何使用limit模块限制并发数

小编给大家分享一下Nginx中如何使用limit模块限制并发数,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! nginx 限制ip并发数,nginx限制IP连接数的范例参考:如何Nginx限制同一个ip的连接数,限制并发数
2023-06-04

如何去掉不用的Nginx模块

小编给大家分享一下如何去掉不用的Nginx模块,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!去掉不用的Nginx模块在编译安装时,执行./configure方法时
2023-06-05

autoindex模块怎么在Nginx中使用

这期内容当中小编将会给大家带来有关autoindex模块怎么在Nginx中使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1. 简介ngx_http_browser_module 模块,通过判断"Use
2023-06-07

rewrite模块怎么在Nginx中使用

rewrite模块怎么在Nginx中使用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。rewrite模块即ngx_http_rewrite_module模块,主要功能是改写
2023-06-06

如何开启nginx的ssl模块

要开启Nginx的SSL模块,您需要按照以下步骤进行操作:1. 安装Nginx:首先,您需要在您的计算机上安装Nginx。您可以从Nginx官方网站下载适合您操作系统的二进制包,或者使用包管理工具进行安装。2. 生成SSL证书和私钥:SSL
2023-09-05

Python中的binascii模块如何使用

这篇文章主要介绍“Python中的binascii模块如何使用”,在日常操作中,相信很多人在Python中的binascii模块如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中的binas
2023-06-30

python中的decimal模块如何使用

本篇内容主要讲解“python中的decimal模块如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python中的decimal模块如何使用”吧!1. Decimal类型的优点Decim
2023-07-05

python中的xlwt模块如何使用

这篇文章主要介绍“python中的xlwt模块如何使用”,在日常操作中,相信很多人在python中的xlwt模块如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python中的xlwt模块如何使用”的疑
2023-07-05

python中如何使用smtplib模块

python中如何使用smtplib模块,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。说明1、创建SMTP的操作对象,连接smtp目标服务器,可以是163、QQ等。2、根据
2023-06-20

python中如何使用 String模块

本篇文章为大家展示了python中如何使用 String模块,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。string成员常量:ascii_letters = abcdefghijklmnopqrs
2023-06-17

 Python中logging模块如何使用

这篇文章主要讲解了“ Python中logging模块如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ Python中logging模块如何使用”吧!1.为什么要用logging模块在
2023-06-29

python中utils模块如何使用

在Python中,utils模块通常是一个包含一些常用的工具函数的模块。要使用utils模块中的功能,首先需要导入该模块:import utils然后就可以调用utils模块中的函数了。例如,假设utils模块中有一个名为print_me
python中utils模块如何使用
2024-04-03

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录