今天公司项目遇到一个奇怪的问题,记录一下。

注: 数据已经过脱敏处理,未暴露公司具体的IP等数据。

TLDR; 项目简单介绍

用 Vue + ElementUI 实现的后台项目(以下简称:a-project),不包含 Node 聚合层,前端开发完成后将打包生成的 dist 文件夹上传到服务器的某目录下,由 Nginx 作为 Web 服务器驱动页面。

同时 Nginx 实现了反向代理,隐藏了服务器真实的 IP 地址。

Nginx 默认配置为 /etc/nginx/nginx.conf 文件,摘录如下:

# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid; # Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf; events {
worker_connections 1024;
} http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048; include /etc/nginx/mime.types;
default_type application/octet-stream; include /etc/nginx/conf.d/*.conf; server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html; # Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
} error_page 404 /404.html;
location = /40x.html {
} error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}

从上面配置可以获取到以下信息:

  1. 错误日志存储在 /var/log/nginx/error.log 文件中;
  2. 访问日志存储在 /var/log/nginx/access.log 文件中;
  3. 监听80端口,子站的配置存储在 /etc/nginx/default.d 目录下在的 *.nginx 文件中;

a-project 的 Nginx 配置文件为:/etc/nginx/default.d/project-a.homedo.com.conf,关键信息摘录如下:

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server
{
listen 1024;
server_name a-project.homedo.com;
index index.html index.htm;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
root /home/xxxx/projectA; location ^~/a-api/{
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass https://a-api.homedo.com/;
} # <======= 注:此处 b-api 的转发突然失败
location ^~/b-api/ {
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://b-api.homedo.com/;
} location ^~/c-api/ {
add_header 'Access-Control-Allow-Origin' '*';![20200621094514.jpg](https://poppython.oss-cn-beijing.aliyuncs.com/pdf_report/92f83018-1fb7-45f3-9f1f-de34eede661f__20200621094514.jpg)
proxy_pass http://c-api.homedo.com/;
}
# ... 其他配置
}

问题描述

从上面的 Nginx 配置可以看到 project-a 使用到了 a-apib-apic-api 三个子域名的接口,测试反馈说项目中某些接口突然报错500,经排查发现:

  1. http://b-api.homedo.com 通过 Swagger 可以正常访问,通过 PostMan 也可以正常访问;
  2. 访问 http://a-project.homedo.com 访问 b-api 下的接口,集体报错:500;
  3. 和用户权限无关,所有用户必现;
  4. 和接口权限无关,所有 b-api 下的接口均报错;

排查过程

STEP1

基本锁定问题是 b-api 转发失败,Nginx 错误日志 /var/log/nginx/error.log 为空,Nginx 并没有捕获到这些报错,access.log 也没有有用的信息。

project-a 所在服务器 xx.xx.xx.100 访问 http://a-project.homedo.com/areas/all 接口发现报错:

在另一台服务器(xx.xx.xx.200)访问 http://a-project.homedo.com/areas/all 接口发现可以正常拿到结果。

注: 此处正常是因为 xx.xx.xx.200 从未访问过,目标域名未被 DNS 缓存。

STEP2

询问其他同事发现好多项目都遇到了同样的问题,原因是运维改了域名的解析地址。

解决办法:

  1. 重启服务器
  2. 清空DNS缓存

问题原因

首先梳理一下访问路径:

  1. 用户访问了系统,a-project.homedo.com,DNS将域名解析到 xx.xx.xx.100
  2. a-project.homedo.com 调用 a-api.homedo.com 时,DNS会解析到服务器 xx.xx.xx.101
  3. a-project.homedo.com 调用 b-api.homedo.com 时,DNS会解析到服务器 xx.xx.xx.102
  4. a-project.homedo.com 调用 c-api.homedo.com 时,DNS会解析到服务器 xx.xx.xx.103

(也许是因为机器迁移)运维将 b-api.homedo.com 解析地址改动为 xx.xx.xx.202 后,以上第 3 步由于机器缓存了DNS解析记录,所以报错500。

总结

1. 怎么清除 DNS 缓存?

service nscd restart

2. 为什么重启后问题就解决了?

nscd 服务被重启了。

3. 什么是 nscd?

nscd(Name Service Cache Daemon)是一种能够缓存 passwd、group、hosts 的本地缓存服务,分别对应三个源 /etc/passwd、/etc/hosts、/etc/resolv.conf。其最为明显的作用就是加快 DNS 解析速度,在接口调用频繁的内网环境建议开启。

4. 正向代理和反向代理?

  • 正向代理隐藏了用户的真实地址;
  • 反向代理隐藏了服务器的真实地址;

记一次Nginx反向代理500的排查记录的更多相关文章

  1. nginx反向代理压测问题记录

    使用nginx反向代理压测web程序,100个用户并发时,每隔一段时间loadrunner工具中就会报错,报错信息如下: Continuing after Error -26610: HTTP Sta ...

  2. nginx反向代理后端web服务器记录客户端ip地址

    nginx在做反向代理的时候,后端的nginx web服务器log中记录的地址都是反向代理服务器的地址,无法查看客户端访问的真实ip. 在反向代理服务器的nginx.conf配置文件中进行配置. lo ...

  3. 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则

    负载均衡-Nginx中文文档 http://www.nginx.cn/doc/example/loadbanlance.html 负载均衡 一个简单的负载均衡的示例,把www.domain.com均衡 ...

  4. 端口被占用通过域名的处理 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则

    负载均衡-Nginx中文文档 http://www.nginx.cn/doc/example/loadbanlance.html 负载均衡 一个简单的负载均衡的示例,把www.domain.com均衡 ...

  5. Nginx反向代理,负载均衡,redis session共享,keepalived高可用

    相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...

  6. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...

  7. Nginx反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...

  8. Nginx 反向代理、负载均衡、页面缓存、URL重写以及读写分离

    1.环境准备 前端Nginx:10.160.65.44 后端WEB服务器两台:10.160.65.49/10.160.65.50 2.安装Nginx: 下载nginx-1.9.15.tar.gz,放置 ...

  9. nginx 反向代理 与 Apache backend的配置联合配置

    nginx 反向代理 与 Apache backend的配置联合配置: 说明: nginx 将http映射到Apache上的特定子目录. 配置方法步骤: 1.  设置域名, 子域名映射到指定服务器ip ...

随机推荐

  1. 安装篇一:安装VMware12

    #1.安装VMware12 前提:安装不了的解决办法(进入BIOS系统,把虚拟化技术那一项修改为enable) 说明:安装流程(自定义安装)              #2.网络适配器设置 虚拟网络编 ...

  2. Raft算法系列教程4:日志不一致的解决

    网络不可能一直处于正常情况,因为Leader或者某个Follower有可能会崩溃,从而导致日志不能一直保持一致.因此存在以下三种情况: (1)Follower缺失当前Leader上存在的日志条目.(2 ...

  3. python保存二维列表到txt文件,读取txt文件里面的数据转化为二维列表

    源码: # 读文件里面的数据转化为二维列表 def Read_list(filename): file1 = open(filename+".txt", "r" ...

  4. VS2017+qt5.9的安装

    VS2017+qt5.9的安装 运行环境: win7旗舰版+vs2017专业版+qt5.9.2 第一步:安装qt5.9.2 下载qt安装包:下载地址http://mirrors.ustc.edu.cn ...

  5. AjaxControlToolKit CalendarExtender(日历扩展控件)的使用方法

    设置CalendarExtender的TargetControlID为需要显示日期的TextBox的ID,textBox控件的readOnly属性设置为 false ,这样就可以点击textbox控件 ...

  6. 如何使用容器镜像服务 TCR 轻松实现容器 DevOps

    作者周明,腾讯云容器产品工程师.目前主要负责腾讯云TKE.TCR等产品控制台的相关研发工作. 概述 当你使用云厂商提供的容器服务部署业务服务后,是否对交付部署全链路的效率有更高的需求,例如实现基于容器 ...

  7. spark优化项

    一.Shuffle优化项 1.Shuffle优化配置 - spark.shuffle.file.buffer 默认值:32k 参数说明:该参数用于设置shuffle write task的Buffer ...

  8. 【Redis3.0.x】NoSql 入门

    Redis3.0.x NoSql 入门 概述 NoSQL(Not Only SQL ),即不仅仅是 SQL,泛指非关系型的数据库.NoSQL 数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑 ...

  9. 来不及解释!Linux常用命令大全,先收藏再说

    摘要:Linux常用命令,很适合你的. 一提到操作系统,我们首先想到的就是windows和Linux.Windows以直观的可视化的方式操作,特别适合在桌面端PC上操作执行相应的软件.相比较Windo ...

  10. 从Java的字符串池、常量池理解String的intern()

    前言 逛知乎遇到一个刚学Java就会接触的字符串比较问题: 通常,根据"==比较的是地址,equals比较的是值"介个定理就能得到结果.但是String有些特殊,通过new Str ...