架构师技能:技术深度硬实力透过问题看本质--深入分析nginx偶尔502错误根因

以架构师的能力标准去分析每个问题,过后由表及里分析问题的本质,复盘总结经验,并把总结内容记录下来。当你解决各种各样的问题,也就积累了丰富的解决问题的经验,解决问题的能力也将自然得到极大的提升。励志做架构师的撸码人,认知很重要。

本文主要想表达的是解决问题的态度:透过问题看本质,由虚到实,往深层次地挖掘。

一、问题和目的


1、问题现象:

接入层nginx集群某个接口偶尔出现502,但是业务nginx没有看到502日志,业务服务端口正常。

2、 本次总结的目的:积累沉淀

1)、知识学习路径:

1、最好的学习,实现90%的知识转化,分享是最好的方式。

2、知识输出:把知识内化为自己的智慧。

3、把智慧升华为世界观和方法论。

2)、不要轻视任何小问题,追根溯源问题的本质,才积累丰富的解决问题的经验。

首先需要了解nginx运行原理。Nginx工作原理和优化总结。_nginx原理-CSDN博客

nginx的健康检查机制:Nginx健康检查机制-CSDN博客

海恩法则

    · 事故的发生是量的积累的结果。
    · 再好的技术、再完美的规章 , 在实际操作层面也无法取代人自身的素质和责任心 。

薛定谔的猫

    “薛定谔的猫”告诉我们,事物发展不是确定的,而是量子态的叠加。

墨菲定律

    · 任何事情都没有表面看起来那么简单 。
    · 所有事情的发展都会比你预计的时间长 。
    · 会出错的事总会出错。
    · 如果你担心某种情况发生,那么它更有可能发生 。

蝴蝶效应

    世界会因一些微小因素的变动,而发生很大的变化。

熵增原理

    “热力学第二定律”(熵增原理)告诉我们,世界总是在变得更加混乱无序。  

      警示我们对生产环境发生的任何怪异现象和问题都不要轻易忽视,对于其背后的原因一定要彻查。同样,海恩法则也强调任何严重事故的背后 都是多次小问题的积累,积累到一定的量级后会导致质变,严重的问题就会浮出水面 。 那么,我们需要对线上服务产生的任何征兆,哪怕是一个小问题,也要刨根问底: 这就需要我们有技术攻关的能力,对任何现象都要秉着以下原则: 为什么发生? 发生了怎么应对? 怎么恢复? 怎么避免? 对问题要彻查,不能因为问题的现象不明显而忽略 。

3)、总结错误处理经验,快速定位和解决问题。

不回避问题,不怕攻关,不惧挑战。在其位要积极主动去分析排查问题,而不是被动去接受问题。

解决问题的思路是一种思维工具,通过提出问题、分析问题和解决问题的过程,可以帮助我们主动思考和积极学习。在解决问题过程中帮助我们更深入地理解和应用知识技能。

二、问题定位


出现这种问题,肯定是需要彻查日志定位和分析。

1、查接入层nginx日志:

nginx出现错误日志:(110: Connection timed out) while reading response header from upstream 一般是nginx读取来自upstream的响应头时超时。 

主要接口xxxx/container请求超时。

2、排查是否存在:no live upsteams

接口/user/autch/check出现no live upsteams,即报出502错误。

3、业务nginx查询接口xxxx/container日志情况:

接口xxxx/container请求频繁(相对历史),http code=499,即service服务处理超时,接入层直接断开请求了。

初步定位:

由于接口接口xxxx/container大量请求超时,可能导致接入层nginx会剔除业务nginx服务,然后接口/user/autch/check出现no live upsteams,即报出502错误。

验证定位:

接口xxxx/container限流降级,在业务nginx特殊处理直接返回200:

localtion /xxxx/container {

                return 200 "ok";

}

nginx -s reload后,接入层nginx的502日志消失。确定接口xxxx/container大量请求超时引起。

三、问题分析


1、为啥业务nginx明明存活负载很低,但是接入层偶尔出现502。

这个就需要了解nginx的健康检查机制:

我们接入层nginx upstream配置:

upstream upstream_6f6a3h8a0e5e1
{

     server 192.168.1.21;

     server 192.168.1.22;
}

nginx本身是没有针对负载均衡后端节点的健康检查的,但是可以通过默认自带的 ngx_http_proxy_module 模块 和ngx_http_upstream_module模块中的相关指令来完成当后端节点出现故障时,自动切换到健康节点来提供访问。

ngx_http_upstream_module模块中的server指令范例:

upstream name {
                server 10.1.1.110:8080 max_fails=1 fail_timeout=10s;
                server 10.1.1.122:8080 max_fails=1 fail_timeout=10s;
        }
当upstream没有配置max_fails和fail_timeout,即nginx使用默认值fail_timeout为10s,max_fails为1次。

由于Nginx ngx_http_upstream_module模块是基于连接探测的,如果发现后端异常,在单位周期为fail_timeout设置的时间中失败次数达到max_fails次,这个周期次数内,如果后端同一个节点不可用,那么就将把节点标记为不可用,并等待下一个周期(同样时长为fail_timeout)再一次去请求,判断是否连接是否成功。
即在10s以内后端失败了1次【即一次请求超时】,那么这个后端就被标识为不可用了,所以在接下来的10s期间,nginx都会把请求分配给正常的后端【即多次的请求正常】。

关于502伴随出现错误no live upstreams while connecting to upstream的原因:在文章Nginx中常见问题与错误处理-CSDN博客

2、为啥业务nginx 出现499,接入层nginx显示响应超时。

这是因为接入层nginx配置响应超时为30s:

proxy_read_timeout 30s;
proxy_connect_timeout 5s;

而业务nginx超时是60s,即接入层nginx超时30s会主动断开和业务nginx连接。

此时业务nginx请求日志就会出现499.

3、接口xxxx/container大量请求超时

依赖底层一个服务出现变动,导致接口处理超时。

四、解决问题


本质还是需要优化超时接口,但是为了预防某个接口出现问题进而导致整个服务不能用的情况,需要做一些预防措施。

方案1:优化 upstream 默认健康检测,主要降低出现502到概率。

upstream upstream_6f6a3h8a0e5e1 {

     server 192.168.1.21 max_fails=3 fail_timeout=60s;

     server 192.168.1.22 max_fails=3 fail_timeout=60s;
}

即在30s以内后端失败了3次那么这个后端才被标识为不可用了。

同时可以增加业务nginx数量,这样业务nginx完全被剔除概率就更低

upstream upstream_6f6a3h8a0e5e1 {

     server 192.168.1.21 max_fails=3 fail_timeout=60s;

     server 192.168.1.22 max_fails=3 fail_timeout=60s;

     server 192.168.1.23 max_fails=3 fail_timeout=60s;

     server 192.168.1.24 max_fails=3 fail_timeout=60s;
}

方案三:nginx_upstream_check_module模块主动检测:

在nginx.conf配置文件里面的upstream加入健康检查,如下:    upstream name {
           server 192.168.0.21:80;
           server 192.168.0.22:80;
           check interval=3000 rise=2 fall=5 timeout=1000 type=tcp;
           
    }

对name这个负载均衡条目中的所有节点,每个3秒检测一次端口是否存活,请求2次正常则标记 realserver状态为up,如果检测 5 次都失败,则标记 realserver的状态为down,超时时间为1秒。

目前这个是比较好的解决方案,确保正常流量都能进入到后端业务服务进行处理。

具体安装:

yum -y install pcre-devel openssl openssl-devel
 
cd  /usr/local/src/
wget http://nginx.org/download/nginx-1.12.1.tar.gz
tar -zxvf nginx-1.12.1.tar.gz

 
cd /usr/local/src
wget https://codeload.github.com/openresty/echo-nginx-module/tar.gz/refs/tags/v0.62
tar zxvf v0.62
 
#下载 nginx_upstream_check_module模块
cd /usr/local/src
wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
unzip master
 
#为nginx打补丁
cd  nginx-1.12.1
#查看对应nginx版本: ll ../nginx_upstream_check_module-master/
patch -p1 < ../nginx_upstream_check_module-master/check_1.12.1+.patch
 
#安装nginx
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_stub_status_module  --with-http_ssl_module   --add-module=/usr/local/src/echo-nginx-module-0.62 --add-module=/usr/local/src/nginx_upstream_check_module-master
 
make -j2  
make install
 
原因:我安装的nginx版本为1.12.1,在安装nginx_upstream_check_module模块时忘记修改补丁文件版本(先安装了1.5.12+,后面发现错了又安装1.12.1+),导致在在make时报错.

关于nginx健康检查机制:Nginx健康检查机制-CSDN博客

五、技术深度硬实力:透过问题看本质,解决问题和绕开问题。


透过问题看本质则是由虚到实,往深层次地挖掘:

大部分人看到这个502,就表面的认为偶尔服务异常不用关注。但问题的本质原因是什么?没深层次去挖掘。

在实践中遇到问题,不仅只解决问题,还要对问题刨根问底,深入挖掘问题发生的根本原因,这样可以系统性地修复问题,从而使其永久消失。从问题本身着手,沿着因果关系链条,顺藤摸瓜,穿越不同的抽象层面,直至找出原有问题的根本原因.

我们中国古代以来就有“打破沙锅问到底”的习惯;“打破沙锅问到底”是一句俗语,形象表达了锲而不舍、不断探索的精神,这是人们常挂在嘴边的一句口头禅。

我们遇到问题,从外到里,逐层分析:
1、问题表象是什么
2、直接原因是什么?
3、中间原因是什么?
4、根本原因是什么?

深层次挖掘:接入nginx-》业务nginx-》service 。

直接原因:直接原因是接口xxxx/container大量请求超时,解决接口xxxx/container超时后,到这虽然可以解决本次问题,但下次是否还会出现?

中间原因:接入层nginx健康检查机制配置不合理,负责nginx的人员应该具备这些专业知识。作为接入层,是不能拦截正常的业务请求,要确保业务请求流量都转发待业务nignx,如果不解决好,下次另外的接口处理频繁处理超时,是不是也要剔除业务nginx?

根本原因:接入层单纯做负载均衡,健康检查最好是使用只检测端口存活,具体http异常应该由业务nginx进行处理。

表象:是http应用协议调用,接口xxxx/container大量请求超时导致。

中层:tcp/ip跨网络调用。

底层:操作系统如何封装tcp/ip,然后通过网卡,路由器等介质进行传输。

透过问题看本质能够敏锐地发现底层之真实,系统性端到端地思考问题,识别木桶的短板并解决之。

4、挖掘本质

又回到由浅入深学习层次:了解——熟悉——掌握——精通——专家

1、了解:入门,简单的认知和记忆,表示知道。是最低水平的认知学习结果。

2、熟悉:概念,了解概念得清楚,清楚地知道概念;(对某种技术或学问)侧重于知道得清楚,比了解更进一层。

2、掌握:规则、应用规则到实践,是在熟悉的基础上能充分加以运用。

3、精通:高级规则,深入底层。

4、专家:扩展创新。

将世界万物理解为原子,将整个互联网理解成0和1,这倒的确是非常本质了,不过并不能解答任何问题。从问题现象看本质,实质上是一个从表层逐步深入的过程。

说到透过现象看本质,其实就是黄金思维圈,你在技术上遇到每一件事情, 首先问“为什么”, 所谓黄金思维圈, 其实是我们认知世界的方式。 我们看问题的方式。
可以分为三个层面——

第一个层面是what层面, 也就是事情的表象, 我们具体做的每一件事;

第二个层面是how层面, 也就是我们如何实现我们想要做的事情;

第三个层面是why层面, 也就是我们为什么做这样的事情。

六、nginx常见错误总结


Nginx中常见问题与错误处理-CSDN博客

错误日志[Error.log]

错误信息错误说明
“upstream prematurely(过早的) closed connection”请求uri的时候出现的异常,是由于upstream还未返回应答给用户时用户断掉连接造成的,对系统没有影响,可以忽略
“recv() failed (104: Connection reset by peer)”(1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉; (2)客户关掉了浏览器,而服务器还在给客户端发送数据; (3)浏览器端按了Stop
“(111: Connection refused) while connecting to upstream”用户在连接时,若遇到后端upstream挂掉或者不通,会收到该错误
“(111: Connection refused) while reading response header from upstream”用户在连接成功后读取数据时,若遇到后端upstream挂掉或者不通,会收到该错误
“(111: Connection refused) while sending request to upstream”Nginx和upstream连接成功后发送数据时,若遇到后端upstream挂掉或者不通,会收到该错误
“(110: Connection timed out) while connecting to upstream”nginx连接后面的upstream时超时
“(110: Connection timed out) while reading upstream”

nginx读取来自upstream的响应时超时

“(110: Connection timed out) while reading response header from upstream”nginx读取来自upstream的响应头时超时
“(110: Connection timed out) while reading upstream”nginx读取来自upstream的响应时超时
“(104: Connection reset by peer) while connecting to upstream”upstream发送了RST,将连接重置
“upstream sent invalid header while reading response header from upstream”upstream发送的响应头无效
“upstream sent no valid HTTP/1.0 header while reading response header from upstream”upstream发送的响应头无效
“client intended to send too large body”用于设置允许接受的客户端请求内容的最大值,默认值是1M,client发送的body超过了设置值
“reopening logs”用户发送kill  -USR1命令
“gracefully shutting down”,用户发送kill  -WINCH命令
“no servers are inside upstream”upstream下未配置server
“no live upstreams while connecting to upstream”upstream下的server全都挂了
“SSL_do_handshake() failed”SSL握手失败
“SSL_write() failed (SSL:) while sending to client”
“(13: Permission denied) while reading upstream”
“(98: Address already in use) while connecting to upstream”
“(99: Cannot assign requested address) while connecting to upstream”
“ngx_slab_alloc() failed: no memory in SSL session shared cache”ssl_session_cache大小不够等原因造成
“could not add new SSL session to the session cache while SSL handshaking”ssl_session_cache大小不够等原因造成
“send() failed (111: Connection refused)”

七、最后的总结


深度是根基,广度是枝叶。根深才能蒂固,枝繁才能叶茂,十年方可树木。

深度是专业:根深,事情做到专业职业,专业才能可靠。

广度是全面:枝繁,业务掌握全面透彻,全面才能靠谱

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring IOC(二)

1. Bean的定义与获取 1.1 定义Bean 在Spring 中定义Bean的方式主要有三种&#xff1a; 1、基于XML配置文件的方式&#xff08;了解&#xff09;&#xff1a;通常会在配置文件中使用<bean>标签来定义Bean&#xff0c;并设置Bean的属性、依赖关系等信息。 2、基于注解的方…

C语言程序设计(一)

1、指令、程序、软件 2、计算机语言&#xff1a;机器语言、汇编语言、高级语言 高级语言的发展&#xff1a;非结构化语言&#xff08;FORTRAN&#xff09;、结构化语言&#xff08;C语言&#xff09;、面向对象的语言&#xff08;C、面向对象&#xff09; 3、源程序、二进制…

数据可视化在不同行业中有哪些应用?

数据可视化即通过图表的形式将数据的内在信息有逻辑性地呈现给用户&#xff0c;使用户更容易发现数据中蕴藏的规律&#xff0c;找出问题&#xff0c;进而做出决策&#xff1b;另一方面&#xff0c;数据可视化项目也是一张重要的名片&#xff0c;是企业数字化建设效果的呈现。本…

FPGA实现图像处理之【直方图均衡-寄存器版】

FPGA实现直方图统计 一、图像直方图统计原理 直方图的全称为灰度直方图&#xff0c;是对图像每一灰度间隔内像素个数的统计。即对一张图片中每隔二灰度值的像素数量做统计&#xff0c;然后以直方图的形式展现出来。图下的亮暗分布在直方图中就可以一目了然&#xff0c;直方图…

【数据结构与算法】力扣 225. 用队列实现栈

题目描述 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。int pop() 移除并返回栈顶元…

AI项目二十:基于YOLOv8实例分割的DeepSORT多目标跟踪

若该文为原创文章&#xff0c;转载请注明原文出处。 前面提及目标跟踪使用的方法有很多&#xff0c;更多的是Deepsort方法。 本篇博客记录YOLOv8的实例分割deepsort视觉跟踪算法。结合YOLOv8的目标检测分割和deepsort的特征跟踪&#xff0c;该算法在复杂环境下确保了目标的准…

R语言的基本图形

一&#xff0c;条形图 安装包 install.packages("vcd") 绘制简单的条形图 barplot(c(1,2,4,5,6,3)) 水平条形图 barplot(c(1,2,4,5,6,3),horiz TRUE) 堆砌条形图 > d1<-c("Placebo","Treated") > d2<-c("None",&qu…

linux运行python怎么结束

假如你已经进入到【>>>】&#xff0c;那么输入【quit&#xff08;&#xff09;】&#xff0c;然后按一下回车键即可退出了。 如果是想要关闭窗口的&#xff0c;那么直接在这个窗口上按【ctrld】。

vue2集成ElementUI编写登录页面

目录 1. 整理目录文件&#xff1a; a. app.vue文件如下&#xff1a; b. Login.vue文件如下&#xff1a; c. router/index.js文件如下&#xff1a; d. 删除components中的文件&#xff1a; e. 最终项目目录整理如下&#xff1a; 2. 集成ElementUI编写登录页面 a. 安装El…

Vue3 v3.4之前如何实现组件中多个值的双向绑定?

文章目录 基础代码1. watch2. computed&#xff08;推荐&#xff09; 官方给的例子是关于el-input的&#xff0c;如下。但是input不是所有组件标签都有的属性啊&#xff0c;有没有一种通用的办法呢&#xff1f; <script setup> defineProps({firstName: String,lastName…

Docker容器:搭建LNMP架构

目录 前言 1、任务要求 2、Nginx 镜像创建 2.1 建立工作目录并上传相关安装包 2.2 编写 Nginx Dockerfile 脚本 2.3 准备 nginx.conf 配置文件 2.4 生成镜像 2.5 创建 Nginx 镜像的容器 2.6 验证nginx 3、Mysql 镜像创建 3.1 建立工作目录并上传相关安装包 3.2 编写…

FANUC机器人SOCKET断开KAREL程序编写

一、添加一个.KL文件创建编辑断开指令 添加一个KL文件用来创建karel程序中socket断开指令 二、断开连接程序karel代码 PROGRAM SOC_DIS %COMMENT SOCKET断开 %INCLUDE klevccdf VAR str_input,str_val : STRING[20] status,data_type,int_val : INTEGER rel_val : REALBEGING…

【Linux】文件打包解压_tar_zip

文章目录 &#x1f4d1;引言&#xff1a;一、文件打包压缩1.1 什么是文件打包压缩&#xff1f;1.2 为什么需要文件打包压缩&#xff1f; 二、打包解压2.1 zip2.2 unzip2.3 tar指令 &#x1f324;️全篇小结&#xff1a; &#x1f4d1;引言&#xff1a; 在Linux操作系统中&#…

简单易懂的下载学浪视频教程- 小浪助手

接下来我就教大家如何通过小浪助手&#xff0c;轻松下载你想要下载的学浪app视频 首先准备好小浪助手 工具我已经打包好了&#xff0c;有需要的自己取一下 学浪下载器链接&#xff1a;https://pan.baidu.com/s/1djUmmnsfLEt_oD2V7loO-g?pwd1234 提取码&#xff1a;1234 -…

LLaMA3(Meta)微调SFT实战Meta-Llama-3-8B-Instruct

LlaMA3-SFT LlaMA3-SFT, Meta-Llama-3-8B/Meta-Llama-3-8B-Instruct微调(transformers)/LORA(peft)/推理 项目地址 https://github.com/yongzhuo/LLaMA3-SFT默认数据类型为bfloat6 备注 1. 非常重要: weights要用bfloat16/fp32/tf32(第二版大模型基本共识), 不要用fp16, f…

Llama 3 基于知识库应用实践(一)

一、概述 Llama 3 是Meta最新推出的开源大语言模型&#xff0c;其8B和13B参数的模型的性能与之前的Llama 2相比实现了质的飞跃。以下是官方给出的模型性能评测对比结果&#xff08;引自&#xff1a;https://ai.meta.com/blog/meta-llama-3/&#xff09;&#xff0c;如Llama 3 …

后端学习记录~~JavaSE篇(Module08-异常 上 )

总览&#xff1a; Java概述&#xff1a; 思维导图文件在本人个人主页上-----资源模块 资源详情&#xff08;免费下载&#xff09;&#xff1a;Java学习思维导图异常篇资源-CSDN文库https://download.csdn.net/download/m0_61589682/89238330 整体展示&#xff1a;

文件上传安全以及防止无限制文件上传

文件上传安全以及防止无限制文件上传 在网络应用中&#xff0c;文件上传是一项常见功能&#xff0c;用户可以通过它上传图片、文档或其他媒体文件。然而&#xff0c;如果没有适当的安全措施&#xff0c;文件上传功能可能成为安全漏洞的源头。本文将探讨文件上传过程中的安全风…

小米汽车充电枪继电器信号

继电器型号&#xff1a; 参考链接 小米SU7&#xff0c;便捷充放电枪拆解 (qq.com)https://mp.weixin.qq.com/s?__bizMzU5ODA2NDg4OQ&mid2247486086&idx1&sn0dd4e7c9f7c72d10ea1c9f506faabfcc&chksmfe48a110c93f2806f6e000f6dc6b67569f6e504220bec14654ccce7d…

秋招后端开发面试题 - JVM底层原理

目录 JVM底层原理前言面试题Java 对象的创建过程&#xff1f;什么是指针碰撞&#xff1f;什么是空闲列表&#xff1f;/ 内存分配的两种方式&#xff1f;JVM 里 new 对象时&#xff0c;堆会发生抢占吗&#xff1f;JVM 是怎么设计来保证线程安全的&#xff1f;/ 内存分配并发问题…