14 nginx 的 dns 缓存的流程

news2025/4/18 7:31:39

前言

这个是 2020年11月 记录的这个关于 nginx 的 dns 缓存的问题  docker 环境下面 前端A连到后端B + 前端B连到后端A 

最近从草稿箱发布这个问题的时候, 重新看了一下 发现该问题的记录中仅仅是 定位到了 nginx 这边的 dns 缓存的问题, 但是 并没有到细节, 没有到 具体的 n种解决方式

这里 2024年2月, 本文的目的是 来看一下 这里的具体的细节, 从 nginx 具体的处理流程的过程中来看一下 为什么会是那样 ?

原始问题的上下文如下 docker部署了两套 前端+后端 的系统, appFront0 连接 appBackend0, appFront1 连接 appBackend1, 然后正常启动 前后端系统, 两个前端访问的各自后端系统

这时候, 不断的重启 appBackend0, appBackend1 直到复现 appFront0 访问 appBackend1 或者 appFront1 访问 appBackend0 的情况, 就复现了该问题

复现该问题的关键是 重启的过程中 appBackend0, appBackend1 的 ip 发生了变化

 

我们这里更侧重关注的就是 nginx 这边在 upstream 中使用域名配置了 上游服务, 然后之后 我们再 更新了 dns 服务的该域名的 ip 配置之后, 我们发现 nginx 这边使用的 ip 还是更新之前的 ip

我们这里 来梳理一下 这个流程, 然后 另外再扩展看一下 具体的 相关的系统调用这边是否有 dns 缓存

 

 

测试用例

nginx 配置如下, ”/api/” 相关的服务代理到 “http://master:8081/” 

 

http://master:8081/1.txt 的服务为一个文本文件

 

然后 /etc/hosts 中配置的 master 当前信息如下

当前配置为 192.168.220.2, 可以正常访问到服务

 

正常访问服务如下, 然后 之后将其切换为 “10.60.50.16” 一个不可用的 ip, 然后刷新页面 发现也可以正常访问到服务

我们要探究的就是 为什么 dns服务 中修改了 master 的 ip, nginx 中拿到的还是 原来映射的 192.168.220.2 呢?

 

 

问题的调试

这里会过的比较快, 大体的意思是 nginx 这边解析配置文件的时候 创建了对应的配置数据结构, 初始化的时候就进行了 dns 解析, 然后 后面的业务请求这边使用的是 这套配置

因此访问 http://localhost:82/api/1.txt 一直代理到的是 http://192.168.220.2:8081/1.txt 

 

这里是初始化和上游服务连接的地方, 这里的 fd 就是关键, 是和上游服务关联的 socket

我们来看一下这个 socket

 

看一下这里的 socket 的信息如下, 下图的 sa_data 就是上游服务的 ip + port  

这里 ngx_peer_connection_t pc 的数据来自于 ngx_http_upstream

 

这里的 sa_data 的数据解析如下, 解析为 192.168.220.2:8081

 

ngx_http_upstream.ngx_peer_connection_t 的数据来自于这里的 ngx_http_upstream.ngx_peer_connection_t.data 数据类型是 ngx_http_upstream_rr_peer_data_t

 

ngx_http_upstream.ngx_peer_connection_t.data 数据类型 ngx_http_upstream_rr_peer_data_t 来自于 upstream 这边初始化的时候

这里 ngx_inet_resolve_host 就是解析域名的地方, 然后下面 for(u.naddrs) 中将解析之后的地址信息初始化到 peer 上面去

这个就是 我们最上面和对方服务器创建连接的服务信息 192.168.220.2:8081

 

 

nginx 这边 dns 解析的方式

基于函数 getaddrinfo, 这个是 glibc 中的库函数

 

 

直接使用 getaddrinfo/gethostbyname 是否有 dns 缓存

这是 扩展的知识点

因为 我这边最开始 怀疑的缓存是在 getaddrinfo/gethostbyname 等等函数上面是否有缓存

因此 最开始的时候 做了一些测试用例, 也调试了一下 对应的函数

root@ubuntu:~/Desktop/linux/HelloWorld# cat Test31GetHostByName.c

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>

int main(int argc, char** argv) {

        char *name = "app0.com";
        char str[16];
        struct hostent* result;

        result = gethostbyname(name);
        printf(" official : %s \n", result->h_name);
        printf(" ip : %s \n", inet_ntop(result->h_addrtype, result->h_addr, str,                                                                                                                               sizeof(str)));

        sleep(10);

        result = gethostbyname(name);
        printf(" official : %s \n", result->h_name);
        printf(" ip : %s \n", inet_ntop(result->h_addrtype, result->h_addr, str,                                                                                                                               sizeof(str)));

}

 

然后在 sleep(10) 的期间, 调整 app0.com 的 ip映射配置, 结果如下, 可以看到 第二次调用拿到的是最新的 ip

root@ubuntu:~/Desktop/linux/HelloWorld# ./Test31GetHostByName
 official : app0.com
 ip : 192.168.220.130
 official : app0.com
 ip : 10.60.50.16

 

 

完 

 

 

 

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

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

相关文章

实战教程:使用JetBrians Rider快速部署与调试PS5和Xbox上的UE项目

面向主机游戏开发者的重大新闻&#xff01;在2024.3版本中&#xff0c;JetBrains Rider 增加了对 PlayStation5 和 Xbox 游戏主机的支持&#xff0c;您可以直接在您喜欢的游戏主机上构建、部署和调试 Unreal Engine 和自定义游戏引擎。 JetBrains Rider现在支持主机游戏开发&am…

专题十五:动态路由——BGP

一、BGP的基本概念 BGP&#xff08;Border Gateway Protocol&#xff0c;边界网关协议&#xff09;是一种用于在不同自治系统&#xff08;AS&#xff09;之间交换路由信息的外部网关协议&#xff08;EGP&#xff09;。通过TCP179端口建立连接。目前采用BGP4版本&#xff0c;IP…

hive数仓要点总结

1.OLTP和OLAP区别 OLTP&#xff08;On-Line Transaction Processing&#xff09;即联机事务处理&#xff0c;也称为面向交易的处理过程&#xff0c;其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理&#xff0c;并在很短的时间内给出处理结果&#xff0c;是对用…

git安装(windows)

通过网盘分享的文件&#xff1a;资料(1) 链接: https://pan.baidu.com/s/1MAenYzcQ436MlKbIYQidoQ 提取码: evu6 点击next 可修改安装路径 默认就行 一般从命令行调用&#xff0c;所以不用创建。 用vscode&#xff0c;所以这么选择。

微信小程序实战案例 - 餐馆点餐系统 阶段1 - 菜单浏览

阶段 1 – 菜单浏览&#xff08;超详细版&#xff09; 目标&#xff1a;完成「首页&#xff1d;菜品卡片列表」 打好 UI 地基会从 云数据库 拉取 categories / dishes 并渲染打 Git Tag v1.0‑menu 1. 技术/知识点速览 知识点关键词说明云数据库db.collection().where().…

Dashboard的安装和基本使用

1.Dashboard简介&#xff1a; Dashboard是Kubernetes的Web图形用户界面&#xff08;GUI&#xff09;&#xff0c;它为用户提供了一个直观的方式来管理和监控Kubernetes集群。 2.实验基础和前置条件&#xff1a; 本实验以Kubernetes集群环境搭建与初始化-CSDN博客为基础和前置…

英语单词 list 11

前言 这一个 list 是一些简单的单词。感觉这个浏览单词的方法比较低效&#xff0c;所以准备每天最多看一个 list &#xff0c;真要提升英语水平&#xff0c;感觉还是得直接做阅读理解题。就像我们接触中文阅读材料一样&#xff0c;当然光知道这个表面意思还不够&#xff0c;还…

通义灵码助力Neo4J开发:快速上手与智能编码技巧

在 Web 应用开发中&#xff0c;Neo4J 作为一种图数据库&#xff0c;用于存储节点及节点间的关系。当图结构复杂化时&#xff0c;关系型数据库的查找效率会显著降低&#xff0c;甚至无法有效查找&#xff0c;这时 Neo4J 的优势便凸显出来。然而&#xff0c;由于其独特的应用场景…

高性能文件上传服务

高性能文件上传服务 —— 您业务升级的不二选择 在当今互联网数据量激增、文件体积日益庞大的背景下&#xff0c;高效、稳定的文件上传方案显得尤为重要。我们的文件分块上传服务端采用业界领先的 Rust HTTP 框架 Hyperlane 开发&#xff0c;凭借其轻量级、低延时和高并发的特…

Java Lambda 表达式详解:发展史、语法、使用场景及代码示例

Java Lambda 表达式详解&#xff1a;发展史、语法、使用场景及代码示例 1. Lambda 表达式的发展史 背景与动机 JDK 7 前&#xff1a;Java的匿名内部类虽强大&#xff0c;但代码冗余&#xff08;如事件监听器、集合遍历&#xff09;。JDK 8&#xff08;2014&#xff09;&#…

【从0到1学Elasticsearch】Elasticsearch从入门到精通(下)

我们在【从0到1学Elasticsearch】Elasticsearch从入门到精通&#xff08;上&#xff09;这边文章详细讲解了如何创建索引库和文档及javaAPI操作&#xff0c;但是在实战当中&#xff0c;我们还需要根据一些特殊字段对文档进行查找搜索&#xff0c;仅仅靠id查找文档是显然不够的。…

Python实现贪吃蛇二

上篇文章Python实现贪吃蛇一&#xff0c;实现了一个贪吃蛇的基础版本&#xff0c;但存在一些不足&#xff0c;也缺乏一些乐趣。本篇文章将对其进行一些改进&#xff0c;主要修改/实现以下几点&#xff1a; 1、解决食物随机生成的位置与蛇身重合问题 2、蛇身移动加速/减速功能 3…

基于51单片机的正负5V数字电压表( proteus仿真+程序+设计报告+讲解视频)

基于51单片机的正负5V数字电压表( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0101 1. 主要功能&#xff1a; 设计一个基于51单片机数字电压表 1、能够…

Java雪花算法

以下是用Java实现的雪花算法代码示例&#xff0c;包含详细注释和异常处理&#xff1a; 代码下面有解析 public class SnowflakeIdGenerator {// 起始时间戳&#xff08;2020-01-01 00:00:00&#xff09;private static final long START_TIMESTAMP 1577836800000L;// 各部分…

前端大屏可视化项目 局部全屏(指定盒子全屏)

需求是这样的&#xff0c;我用的项目是vue admin 项目 现在需要在做大屏项目 不希望显示除了大屏的其他东西 于是想了这个办法 至于大屏适配问题 请看我文章 底部的代码直接复制就可以运行 vue2 px转rem 大屏适配方案 postcss-pxtorem-CSDN博客 <template><div …

01_JDBC

文章目录 一、概述1.1、什么是JDBC1.2、JDBC原理 二、JDBC入门2.1、准备工作2.1.1、建库建表2.1.2、新建项目 2.2、建立连接2.2.1、准备四大参数2.2.2、加载驱动2.2.3、准备SQL语句2.2.4、建立连接2.2.5、常见问题 2.3、获取发送SQL的对象2.4、执行SQL语句2.5、处理结果2.6、释…

Spring Boot 热部署详解,包含详细的配置项说明

Spring Boot 热部署详解 1. 热部署简介 热部署&#xff08;Hot Deployment&#xff09;允许在应用运行时修改代码或配置文件&#xff0c;无需重启应用即可使更改生效。Spring Boot 通过 spring-boot-devtools 模块实现这一功能&#xff0c;其核心依赖于 LiveReload 技术和自动…

剑指Offer(数据结构与算法面试题精讲)C++版——day12

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day12 题目一&#xff1a;小行星碰撞题目二&#xff1a;每日温度题目三&#xff1a;直方图最大矩形面积附录&#xff1a;源码gitee仓库 题目一&#xff1a;小行星碰撞 题目&#xff1a;输入一个表示小行星的数…

Docker学习笔记-docker安装、删除

一、在centOS 7中docker的默认安装目录 # Docker 主配置文件目录 ls /etc/docker# Docker 数据目录&#xff08;镜像、容器、卷等&#xff09; ls /var/lib/docker# Docker 可执行文件路径 which docker # 输出类似 /usr/bin/docker 二、docker文件目录说明 目录/文件用途/…

【Python 开源】你的 Windows 关机助手——PyQt5 版定时关机工具

&#x1f5a5;️ 你的 Windows 关机助手——PyQt5 版定时关机工具 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例&#xff0c;秉着开源精神的…