深入理解nginx upstream共享内存机制

目录

  • 1. 概述
  • 2. 开启upstream共享内存机制
  • 3. 源码分析
    • 3.1 配置指令分析
    • 3.2 共享内存区的初始化

1. 概述

   我们知道,nginx的配置是由主进程来加载到内存的,然后fork出各个worker进程,而worker进程自然继承了主进程的内存状态,所以worker进程自然有了加载好的配置信息。然而,每个worker进程运行起来后,它们就各自为政互不干涉的,譬如说upstream功能的各个Real Server的服务器状态也是独立维护的,这样,可能worker A可能已经认为某个后端服务器不可用了,然而worker B却还认为其可用继续将请求发送到这个后端服务器,这就导致多个worker之间的状态不一致。
  为了解决这个问题,nginx引入了ngx_http_upstream_zone_module模块来解决这个问题,当upstream的配置加载完成后,ngx_http_upstream_zone_module模块会把peer信息拷贝到分配好的共享内存中,后续每个worker就在共享内存中进行peer信息的读写,从而解决worker之间peer信息不一致的问题,通过共享内存的方式,甚至可以很方便地实现Real Server的运行时动态增删改操作(在nginx的商业版中提供了这个能力)。当然由于是多进程共享,因此需要必然需要用到跨进程的读写锁,在一定程度上可能对性能有些许影响。

2. 开启upstream共享内存机制

  ngx_http_upstream_zone_module模块仅提供了一个指令来开启共享内存机制,如下:

语  法:zone name [size]
默  认:-
上下文:upstream

   以上指令定义了一个名字为name大小为size的共享内存区,用来保存upstream的配置和运行时状态信息供各个worker进程使用。而且多个upstream可以共享一个同名字的zone,这样子,只要为一个upstream的zone配置指定一个size值就可以了。举例如下:

upstream {zone peer_sh_zone  1m;server 192.168.0.1 weight=1;server 192.168.0.2 weight=1;server 192.168.0.3 weight=1;
}

  特别提一下,当然nginx本身也是支持不开启upstream共享内存机制的,只是可能导致多个worker进程各自管理自己的upstream的配置和状态信息,大部分情况下这不会是什么大的问题。

3. 源码分析

  以下结合ngx_http_upstream_zone_module和ngx_http_upstream_round_robin两个模块来进行详细分析。

3.1 配置指令分析

  在ngx_http_upstream_zone_module中定义了如下配置指令:

static ngx_command_t  ngx_http_upstream_zone_commands[] = {{ ngx_string("zone"),NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,ngx_http_upstream_zone,0,0,NULL },ngx_null_command
};

  所以,nginx在分析到upstream块中的zone指令的时候,就会调用ngx_http_upstream_zone函数进行zone指令的解析,下面来分析ngx_http_upstream_zone函数,函数的源码如下:

static char *
ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ssize_t                         size;ngx_str_t                      *value;ngx_http_upstream_srv_conf_t   *uscf;ngx_http_upstream_main_conf_t  *umcf;uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);value = cf->args->elts;if (!value[1].len) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"invalid zone name \"%V\"", &value[1]);return NGX_CONF_ERROR;}/* 配置的参数个数如果是2个说明有size字段, 以下解析size字段的值 */if (cf->args->nelts == 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/734406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

北约 / 多个国家地区的 数据链 汇总

战术数据链 编号用途说明Link-1地地北约用于NADGE(北约地面防空系统)的雷达情报数据传输Link-2地地其功能类似于Link-1,用于北约陆基雷达站间的数据传输,现已停止发展Link-3地地类似于Link-14的低速电报数据链,用于某些防空预警单元Link-4空…

python实现--分块查找

python实现–顺序查找 python实现–折半查找 python实现–分块查找 python实现B/B树 分块查找(Block Search),也称为索引顺序查找,是一种结合顺序查找和索引查找思想的查找算法。它适用于线性表中数据量较大,但是分布不…

qt 格式化打印 日志 QMessagePattern 格式词法语法及设置

一、qt源码格式化日志 关键内部类 QMessagePattern qt为 格式化打印日志 提供了一个简易的 pattern(模式/格式) 词法解析的简易的内部类QMessagePattern,作用是获取和解析自定义的日志格式信息。 该类在qt的专门精心日志操作的源码文件Src\qtbase\src\corelib\global\qloggi…

[LeetCode][226]翻转二叉树

题目 226. 翻转二叉树 给你一棵二叉树的根节点 root,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1] 示例 2: 输入:root [2,1,3] 输出&#x…

深度学习500问——Chapter02:机器学习基础(5)

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 2.14 贝叶斯分类器 2.14.1 图解极大似然估计 极大似然估计的原理,用一张图片来说明,如下图所示: 例:有两个外形完全相同的箱子,1号箱…

重学SpringBoot3-内容协商机制

重学SpringBoot3-内容协商机制 ContentNegotiationConfigurer接口配置内容协商URL参数Accept头使用Url扩展名 自定义内容协商格式步骤1: 注册自定义媒体类型步骤2: 实现HttpMessageConverter接口步骤3: 使用自定义HttpMessageConverter 注意点 在 Spring Boot 3 中,…

linux系统Docker容器Dockerfile示例

Dockerfile示例 可以使用systemctl命令的镜像Dockerfile 基于centos7创建mysql镜像Dockerfilemysql.sh 可以使用systemctl命令的镜像 Dockerfile vim DockerfileFROM centos:7 ENV container dockerRUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs R…

SQL中如何添加数据:基础指南

在数据库管理系统中,添加数据是一项常见的任务。无论是向现有表中添加新行,还是创建新表并插入数据,都需要使用SQL(Structured Query Language)语句来执行。本文将介绍SQL中如何添加数据的基本方法,以及一些…

vue学习笔记21-组件传递数据_Props

组件与组件之间不是完全独立的&#xff0c;而是有交集的&#xff0c;那就是组件与组件之间是可以传递数据的 传递数据的解决方案就是props 父级&#xff1a; 在父级中引入子集 <template><h3>Parent</h3><Child/> </template><script> i…

PyCaret(Python自动化机器学习)自定义交互式解释性模型

要点 PyCaret代码实现数学定义分类、聚类、异常检测和自然语言处理模型PyCaret模型创建模型和数据分析&#xff1a;身体质量指数回归模型探索性数据分析&#xff0c;植物物种分类模型预测&#xff0c;合成数据聚类模型探索性数据分析&#xff0c;批发商客户异常检测模型探索性…

GFP-GAN环境搭建推理测试

引子 近期&#xff0c;文生图&#xff0c;wav2lip很火&#xff0c;文生图&#xff0c;见识的太多&#xff0c;不多说了。wav2lip其通过语音驱动唇部动作并对视频质量进行修复&#xff0c;里面一般涉及到三个步骤&#xff0c;文本到语音转化&#xff0c;语音驱动唇部动作&#…

YOLOv9/YOLOv8算法改进【NO.103】引入YOLOv9提出模块RepNCSPELAN模块,亲测有效

前 言 YOLO算法改进系列出到这,很多朋友问改进如何选择是最佳的,下面我就根据个人多年的写作发文章以及指导发文章的经验来看,按照优先顺序进行排序讲解YOLO算法改进方法的顺序选择。具体有需求的同学可以私信我沟通: 首推,是将两种最新推出算法的模块进行融合形成…

【C++初阶】第五站:C/C++内存管理 (匹配使用,干货到位)

前言&#xff1a; 本文知识点&#xff1a; 1. C/C内存分布2. C语言中动态内存管理方式3. C中动态内存管理4. operator new与operator delete函数 5. new和delete的实现原理 &#xff08;干货在此&#xff09; 6. 定位new表达式(placement-new)7. 常见面试题 目录 C/C内…

Linux操作系统内核参数调优-2

1. 请解释Linux内核参数调优的目的和重要性。 Linux内核参数调优的目的主要是提高系统性能、稳定性和安全性。它的重要性体现在以下几个方面&#xff1a; 提升系统性能&#xff1a;通过调整内核参数&#xff0c;可以使系统更高效地利用硬件资源&#xff0c;例如CPU、内存和I/…

Java反射、枚举类和lambda表达式

前言&#xff1a; 本章我们就来了解Java中的反射和枚举类。枚举类和反射其实有些关系&#xff0c;接下来我们就来学习他们的使用。 反射&#xff1a; 反射的作用&#xff1a; 反射&#xff1a;反射允许对成员变量&#xff0c;成员方法和构造方法的信息进行编程访问。 Java中有…

CVE-2021-31440:eBPF verifier __reg_combine_64_into_32 边界更新错误

文章目录 前言漏洞分析构造 vuln reg 漏洞利用漏洞修复参考 前言 影响版本&#xff1a;Linux 5.7 ~ 5.11.20 8.8 编译选项&#xff1a;CONFIG_BPF_SYSCALL&#xff0c;config 所有带 BPF 字样的编译选项。General setup —> Choose SLAB allocator (SLUB (Unqueued Allocat…

从0到1手把手实现RPC|01 RpcProvider本地实现

RPC的简化版原理如下图&#xff08;核心是代理机制&#xff09;。 1.本地代理存根: Stub2.本地序列化反序列化3.网络通信4.远程序列化反序列化5.远程服务存根: Skeleton6.调用实际业务服务7.原路返回服务结果8.返回给本地调用方 注意处理异常。 RpcProvider的本地实现 1、工…

xss.haozi.me靶机 通关

0x00 没有任何过滤可以直接注入<img srcx οnerrοralert(1)> 0x01 使用了testarea标签将我们的输入内容以普通的字符串进行展示 但是我们可以将标签进行闭合 </textarea><img srcx οnerrοralert(1)> 0x02 我们依然可以先闭合之后添加属性a" οncl…

word[::-1] for word in s.split()得到的是一个列表

你可以将上述的列表推导式代码拆分为更明确的几个步骤&#xff0c;如下所示&#xff1a; # 原始字符串 s "hello world" # 使用 split() 方法将字符串分割成单词列表 words s.split() # 创建一个空列表&#xff0c;用于存储反转后的单词 reversed_words [] # 遍历…

npm与Maven:前端与后端构建工具深度对比学习

文章目录 npm与Maven&#xff1a;前端与后端构建工具深度对比学习引言一、基础概念与起源1.1 npm简介&#xff1a;定义与在Node.js生态中的角色及其发展历程1.2 Maven简介&#xff1a;设计理念“约定优于配置”及在Java生态系统中的地位与应用范围二、核心功能对比分析2.1 依赖…