关于Nginx中虚拟主机的一些冷门知识小结


Posted in Servers onMarch 03, 2022

前言

nginx的虚拟主机,不知道大家了解不。以前吧,如果在nginx上要反向代理多个服务,我一般是让nginx监听多个不同端口,比如8080/8081,不同端口,反向代理到不同的服务。

server {
	listen 9981 so_keepalive=on;
	proxy_pass service1;
}

server {
	listen 9982 so_keepalive=on;
	proxy_pass service2;
}

来了现在公司,发现这边是基于域名(端口都是80)来反向代理到不同服务,如下:

关于Nginx中虚拟主机的一些冷门知识小结

关于Nginx中虚拟主机的一些冷门知识小结

基于以上的nginx配置,域名a和b,分别代表了系统a和系统b,实际dns是指向同一台nginx机器。当你用域名a访问时,就会走上面的配置;域名b访问时,就会走下面的配置。

对线上配置的一个小疑问

问题背景

我的一位同事,和我差不多时间入职,接手了一个几年前的系统,看到线上环境的nginx配置,表示有点懵,不知道how it works。

这里把这个问题,简单描述下。

为了方便我这边模拟,假设机器ip为10.0.0.6,机器上有个python脚本,会去访问一个api:http://10.0.0.6:80 。

机器上的/etc/hosts如下:

[root@VM-0-6-centos nginx]# cat /etc/hosts
......

10.0.0.6 bbbb.com

也就是说,访问bbbb.com,就相当于访问这台机器了。

[root@VM-0-6-centos nginx]# ping bbbb.com
PING bbbb.com (10.0.0.6) 56(84) bytes of data.

基于以上信息,这个api访问本机的80,是会到本机的nginx(nginx监听80端口),nginx配置如下:

关于Nginx中虚拟主机的一些冷门知识小结

这个配置,基于我们对虚拟主机的了解,也就是说,访问aaaa.com,就会到第一段的配置,aaaa.access.log里面就会有访问日志;如果是访问bbbb.com,就会到第二段的配置,bbbb.access.log就会有访问日志。

但是,客户端不按套路出牌啊,用的是,10.0.0.6:80/xx这样的url来访问该nginx,同时,/etc/hosts里面有配置bbbb.com指向本机,那么,大家觉得最终的访问结果如何?

实测结果

结果是,访问了aaaa那一段。

关于Nginx中虚拟主机的一些冷门知识小结

这。。。我们就有点想不通了,没理由啊,为啥呢,why?不是不能接受结果,而是不知道为什么会这样。

探索

排查网络

按理说,用域名形式访问,应该才会去查看/etc/hosts文件和dns系统,找到域名背后的ip;但是,按ip访问,貌似java建立里面的socket底层实现利,也会有根据ip去获取host的代码(还导致一些超时问题之类的)。

所以,我们猜测,难道是,访问10.0.0.6时,查看了/etc/hosts,把10.0.0.6转换成了aaaa.com?但是,/etc/hosts里面只有把10.0.0.6转换为bbbb.com的可能性吧?

本着不管三级二十一,先抓个包再说的想法,于是在nginx的80端口,开了个tcpdump:

[root@VM-0-6-centos ~]# tcpdump -i lo tcp port 80 -Ann

然后再次访问:

[root@VM-0-6-centos nginx]# curl 10.0.0.6:80

抓包结果:

关于Nginx中虚拟主机的一些冷门知识小结

看到这边host是 10.0.0.6.

这让我开始怀疑,可能和/etc/hosts没什么关系,问题应该变成了:nginx在拿到上面这段http报文时,为啥要路由到aaaa.com那一段配置里面去。

排查nginx

怎么才能知道nginx做了啥呢,我们又没有代码,但是,好歹,我们还有shell 命令啊。 strace这个命令,可以查看一个进程的系统调用,还是比较好用的。

为啥要查这个?因为我怀疑是不是nginx拿到10.0.0.6后,把它转成了域名,不过,转的话,应该也是转换为bbbb.com。另外,这个命令有没有用,我也不确定,因为该命令只能看这个进程发起了哪些系统调用(不是java里的rpc),而是对内核发起的系统调用(system call)。万一,ip转域名的部分,没有通过系统调用实现的话,那这个命令就失效了。

不过还是试试?

先拿到了nginx的worker进程的pid:8845

[root@VM-0-6-centos nginx]# ps -ef|grep nginx
root       610     1  0 12:15 ?        00:00:00 nginx: master process ./nginx
nobody    8845   610  0 13:13 ?        00:00:00 nginx: worker process

再开启一个strace:

[root@VM-0-6-centos ~]# strace -p 8845 -s 1024 -q -f -v -e  trace=network

结果如下:

关于Nginx中虚拟主机的一些冷门知识小结

好像只有接收网络请求的系统调用(recvfrom),系统调用,大家可以拿这个函数名去网上查。

关于Nginx中虚拟主机的一些冷门知识小结

此时,排查陷入了僵局,于是,我只能提议,我先回座位上找找nginx相关资料。

然后就开始在网上查,运气也还不错,就找到了:

https://docs.nginx.com/nginx/admin-guide/web-server/web-server/

关于Nginx中虚拟主机的一些冷门知识小结

上面这段话,大概就是说,虚拟主机的匹配,是通过取req报文里的host字段,来和nginx.conf中server里的server_name做匹配,

因为server_name可以是通配符之类的,所以这里有个优先级,完全匹配》模糊匹配。

上图的最后那几行,就是关键了:

如果完全没匹配上(我们这里就是,拿了个ip来匹配,然而nginx.conf里配置的是aaaa.com和bbbb.com),就会路由到这个端口的默认server。默认server是哪个呢,就是:nginx.conf里端口为80的、且写在第一个的server。

ok,打完收工。

总结

知识点可能很小,但排查也比较麻烦,因为线上环境不好动,然后配置的域名其实不止两个,有7/8个,中间绕的路比上面其实还多一点。

不过这边的大概思路是这样的,希望对大家也有一点点帮助。

Servers 相关文章推荐
Nginx的反向代理实例详解
Mar 31 Servers
Nginx服务器如何设置url链接
Mar 31 Servers
Nginx反向代理至go-fastdfs案例讲解
Aug 02 Servers
Nginx配置文件详解以及优化建议指南
Sep 15 Servers
详解nginx安装过程并代理下载服务器文件
Feb 12 Servers
Nginx实现会话保持的两种方式
Mar 18 Servers
Nginx限流和黑名单配置
May 20 Servers
永中文档在线转换预览基于nginx配置部署方案
Jun 10 Servers
openEuler 搭建java开发环境的详细过程
Jun 10 Servers
Linux服务器离线安装 nginx的详细步骤
Jun 16 Servers
Linux下搭建SFTP服务器的命令详解
Jun 25 Servers
详解apache编译安装httpd-2.4.54及三种风格的init程序特点和区别
Jul 15 Servers
nginx负载功能+nfs服务器功能解析
Apache Pulsar集群搭建部署详细过程
Feb 12 #Servers
详解nginx安装过程并代理下载服务器文件
Feb 12 #Servers
nginx从安装到配置详细说明(安装,安全配置,防盗链,动静分离,配置 HTTPS,性能优化)
Nginx性能优化之Gzip压缩设置详解(最大程度提高页面打开速度)
Feb 12 #Servers
使用 Apache Dubbo 实现远程通信(微服务架构)
Nginx 反向代理解决跨域问题多种情况分析
Jan 18 #Servers
You might like
php常用的url处理函数总结
2014/11/19 PHP
实例讲解PHP设计模式编程中的简单工厂模式
2016/02/29 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
2017/05/08 PHP
javascript利用控件对windows的操作实现原理与应用
2012/12/23 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
JS传递对象数组为参数给后端,后端获取的实例代码
2016/06/28 Javascript
js 声明数组和向数组中添加对象变量的简单实例
2016/07/28 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
jsonp跨域请求实现示例
2017/03/13 Javascript
jquery插件ContextMenu设置右键菜单
2017/03/13 Javascript
不到200行 JavaScript 代码实现富文本编辑器的方法
2018/01/03 Javascript
vue路由组件按需加载的几种方法小结
2018/07/12 Javascript
教你使用vue-cli快速构建的小说阅读器
2019/05/13 Javascript
JS把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
2019/07/10 Javascript
js实现贪吃蛇小游戏
2019/10/29 Javascript
[45:59]EG vs OG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[00:43]魔廷新尊——痛苦女王至宝捆绑包
2020/06/12 DOTA
python制作爬虫并将抓取结果保存到excel中
2016/04/06 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
2018/05/25 Python
python sys.argv[]用法实例详解
2018/05/25 Python
Python 获取div标签中的文字实例
2018/12/20 Python
使用pycharm设置控制台不换行的操作方法
2019/01/19 Python
Python检查ping终端的方法
2019/01/26 Python
Python中常用的内置方法
2019/01/28 Python
python celery分布式任务队列的使用详解
2019/07/08 Python
对python中不同模块(函数、类、变量)的调用详解
2019/07/16 Python
python opencv 简单阈值算法的实现
2019/08/04 Python
pytorch实现mnist数据集的图像可视化及保存
2020/01/14 Python
Python爬虫程序架构和运行流程原理解析
2020/03/09 Python
python对一个数向上取整的实例方法
2020/06/18 Python
聪明的粉丝购买门票的地方:TickPick
2018/03/09 全球购物
创业计划书中要认真思考的问题
2013/12/28 职场文书
党员批评与自我批评材料
2014/10/14 职场文书
2015年小学美术工作总结
2015/05/25 职场文书
2016年“12.4”法制宣传日活动总结
2016/04/01 职场文书
2021年国漫热度排行前十,完美世界上榜,第四是美国动画作品
2022/03/18 国漫