關(guān)于Nginx中虛擬主機(jī)的一些冷門(mén)知識(shí)小結(jié)
前言
nginx的虛擬主機(jī),不知道大家了解不。以前吧,如果在nginx上要反向代理多個(gè)服務(wù),我一般是讓nginx監(jiān)聽(tīng)多個(gè)不同端口,比如8080/8081,不同端口,反向代理到不同的服務(wù)。
server {
listen 9981 so_keepalive=on;
proxy_pass service1;
}
server {
listen 9982 so_keepalive=on;
proxy_pass service2;
}來(lái)了現(xiàn)在公司,發(fā)現(xiàn)這邊是基于域名(端口都是80)來(lái)反向代理到不同服務(wù),如下:


基于以上的nginx配置,域名a和b,分別代表了系統(tǒng)a和系統(tǒng)b,實(shí)際dns是指向同一臺(tái)nginx機(jī)器。當(dāng)你用域名a訪問(wèn)時(shí),就會(huì)走上面的配置;域名b訪問(wèn)時(shí),就會(huì)走下面的配置。
對(duì)線上配置的一個(gè)小疑問(wèn)
問(wèn)題背景
我的一位同事,和我差不多時(shí)間入職,接手了一個(gè)幾年前的系統(tǒng),看到線上環(huán)境的nginx配置,表示有點(diǎn)懵,不知道how it works。
這里把這個(gè)問(wèn)題,簡(jiǎn)單描述下。
為了方便我這邊模擬,假設(shè)機(jī)器ip為10.0.0.6,機(jī)器上有個(gè)python腳本,會(huì)去訪問(wèn)一個(gè)api:http://10.0.0.6:80 。
機(jī)器上的/etc/hosts如下:
[root@VM-0-6-centos nginx]# cat /etc/hosts ...... 10.0.0.6 bbbb.com
也就是說(shuō),訪問(wèn)bbbb.com,就相當(dāng)于訪問(wèn)這臺(tái)機(jī)器了。
[root@VM-0-6-centos nginx]# ping bbbb.com PING bbbb.com (10.0.0.6) 56(84) bytes of data.
基于以上信息,這個(gè)api訪問(wèn)本機(jī)的80,是會(huì)到本機(jī)的nginx(nginx監(jiān)聽(tīng)80端口),nginx配置如下:

這個(gè)配置,基于我們對(duì)虛擬主機(jī)的了解,也就是說(shuō),訪問(wèn)aaaa.com,就會(huì)到第一段的配置,aaaa.access.log里面就會(huì)有訪問(wèn)日志;如果是訪問(wèn)bbbb.com,就會(huì)到第二段的配置,bbbb.access.log就會(huì)有訪問(wèn)日志。
但是,客戶(hù)端不按套路出牌啊,用的是,10.0.0.6:80/xx這樣的url來(lái)訪問(wèn)該nginx,同時(shí),/etc/hosts里面有配置bbbb.com指向本機(jī),那么,大家覺(jué)得最終的訪問(wèn)結(jié)果如何?
實(shí)測(cè)結(jié)果
結(jié)果是,訪問(wèn)了aaaa那一段。

這。。。我們就有點(diǎn)想不通了,沒(méi)理由啊,為啥呢,why?不是不能接受結(jié)果,而是不知道為什么會(huì)這樣。
探索
排查網(wǎng)絡(luò)
按理說(shuō),用域名形式訪問(wèn),應(yīng)該才會(huì)去查看/etc/hosts文件和dns系統(tǒng),找到域名背后的ip;但是,按ip訪問(wèn),貌似java建立里面的socket底層實(shí)現(xiàn)利,也會(huì)有根據(jù)ip去獲取host的代碼(還導(dǎo)致一些超時(shí)問(wèn)題之類(lèi)的)。
所以,我們猜測(cè),難道是,訪問(wèn)10.0.0.6時(shí),查看了/etc/hosts,把10.0.0.6轉(zhuǎn)換成了aaaa.com?但是,/etc/hosts里面只有把10.0.0.6轉(zhuǎn)換為bbbb.com的可能性吧?
本著不管三級(jí)二十一,先抓個(gè)包再說(shuō)的想法,于是在nginx的80端口,開(kāi)了個(gè)tcpdump:
[root@VM-0-6-centos ~]# tcpdump -i lo tcp port 80 -Ann
然后再次訪問(wèn):
[root@VM-0-6-centos nginx]# curl 10.0.0.6:80
抓包結(jié)果:

看到這邊host是 10.0.0.6.
這讓我開(kāi)始懷疑,可能和/etc/hosts沒(méi)什么關(guān)系,問(wèn)題應(yīng)該變成了:nginx在拿到上面這段http報(bào)文時(shí),為啥要路由到aaaa.com那一段配置里面去。
排查nginx
怎么才能知道nginx做了啥呢,我們又沒(méi)有代碼,但是,好歹,我們還有shell 命令啊。 strace這個(gè)命令,可以查看一個(gè)進(jìn)程的系統(tǒng)調(diào)用,還是比較好用的。
為啥要查這個(gè)?因?yàn)槲覒岩墒遣皇莕ginx拿到10.0.0.6后,把它轉(zhuǎn)成了域名,不過(guò),轉(zhuǎn)的話(huà),應(yīng)該也是轉(zhuǎn)換為bbbb.com。另外,這個(gè)命令有沒(méi)有用,我也不確定,因?yàn)樵撁钪荒芸催@個(gè)進(jìn)程發(fā)起了哪些系統(tǒng)調(diào)用(不是java里的rpc),而是對(duì)內(nèi)核發(fā)起的系統(tǒng)調(diào)用(system call)。萬(wàn)一,ip轉(zhuǎn)域名的部分,沒(méi)有通過(guò)系統(tǒng)調(diào)用實(shí)現(xiàn)的話(huà),那這個(gè)命令就失效了。
不過(guò)還是試試?
先拿到了nginx的worker進(jìn)程的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
再開(kāi)啟一個(gè)strace:
[root@VM-0-6-centos ~]# strace -p 8845 -s 1024 -q -f -v -e trace=network
結(jié)果如下:

好像只有接收網(wǎng)絡(luò)請(qǐng)求的系統(tǒng)調(diào)用(recvfrom),系統(tǒng)調(diào)用,大家可以拿這個(gè)函數(shù)名去網(wǎng)上查。

此時(shí),排查陷入了僵局,于是,我只能提議,我先回座位上找找nginx相關(guān)資料。
然后就開(kāi)始在網(wǎng)上查,運(yùn)氣也還不錯(cuò),就找到了:
https://docs.nginx.com/nginx/admin-guide/web-server/web-server/

上面這段話(huà),大概就是說(shuō),虛擬主機(jī)的匹配,是通過(guò)取req報(bào)文里的host字段,來(lái)和nginx.conf中server里的server_name做匹配,
因?yàn)閟erver_name可以是通配符之類(lèi)的,所以這里有個(gè)優(yōu)先級(jí),完全匹配》模糊匹配。
上圖的最后那幾行,就是關(guān)鍵了:
如果完全沒(méi)匹配上(我們這里就是,拿了個(gè)ip來(lái)匹配,然而nginx.conf里配置的是aaaa.com和bbbb.com),就會(huì)路由到這個(gè)端口的默認(rèn)server。默認(rèn)server是哪個(gè)呢,就是:nginx.conf里端口為80的、且寫(xiě)在第一個(gè)的server。
ok,打完收工。
總結(jié)
知識(shí)點(diǎn)可能很小,但排查也比較麻煩,因?yàn)榫€上環(huán)境不好動(dòng),然后配置的域名其實(shí)不止兩個(gè),有7/8個(gè),中間繞的路比上面其實(shí)還多一點(diǎn)。
不過(guò)這邊的大概思路是這樣的,希望對(duì)大家也有一點(diǎn)點(diǎn)幫助。
- Nginx實(shí)現(xiàn)三種常見(jiàn)的虛擬主機(jī)配置方法
- Nginx多虛擬主機(jī)配置小結(jié)
- nginx基于IP的多虛擬主機(jī)實(shí)現(xiàn)
- Nginx虛擬主機(jī)的配置實(shí)現(xiàn)
- Apache和Nginx實(shí)現(xiàn)虛擬主機(jī)的3種方式小結(jié)
- Nginx虛擬主機(jī)的六種配置(最全)
- Nginx虛擬主機(jī)的配置步驟過(guò)程全解
- Nginx虛擬主機(jī)的搭建的實(shí)現(xiàn)步驟
- nginx配置虛擬主機(jī)的詳細(xì)步驟
- 深入淺析Nginx虛擬主機(jī)
- Ubuntu中Nginx虛擬主機(jī)設(shè)置的項(xiàng)目實(shí)踐
相關(guān)文章
Nginx流量同時(shí)轉(zhuǎn)發(fā)多后端(流量鏡像分發(fā))
在需要同時(shí)將請(qǐng)求轉(zhuǎn)發(fā)至多個(gè)后端服務(wù)的場(chǎng)景中,Nginx的mirror模塊提供了流量鏡像分發(fā)的功能,本文就來(lái)介紹一下Nginx流量同時(shí)轉(zhuǎn)發(fā)多后端(流量鏡像分發(fā)),感興趣的可以了解一下2024-10-10
Nginx服務(wù)啟動(dòng)和停止實(shí)現(xiàn)
使用Nginx的過(guò)程中,我們可能總是需要修改nginx配置文件,然后不停地啟動(dòng)或者停止nginx服務(wù),本文就來(lái)介紹一下,感興趣的可以了解一下2023-11-11
Nginx實(shí)現(xiàn)分端口部署兩個(gè)或多個(gè)項(xiàng)目的教程
這篇文章主要為大家詳細(xì)介紹了Nginx實(shí)現(xiàn)分端口部署兩個(gè)或多個(gè)項(xiàng)目的相關(guān)教程,其中包含了反向代理配置,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
Nginx之rewrite實(shí)現(xiàn)URL重寫(xiě)方式
文章介紹了Nginx的rewrite模塊,包括其重要性、相關(guān)指令(如set、if、break、return、rewrite)的使用方法和作用域,并舉例說(shuō)明了這些指令的實(shí)際應(yīng)用場(chǎng)景,如域名重定向和防盜鏈處理2025-03-03
linux查找當(dāng)前系統(tǒng)nginx路徑的兩種方法
工作中有很多服務(wù)器, 它們上面裝的 nginx 的路徑也太不相當(dāng), 當(dāng)我們拿到一個(gè)不熟悉的服務(wù)器時(shí), 我們?cè)趺粗? 當(dāng)前運(yùn)行的nginx的目錄是哪一個(gè)呢,本文小編給大家介紹了兩種linux查找當(dāng)前系統(tǒng)nginx的路徑的方法,需要的朋友可以參考下2023-11-11
利用nginx和騰訊云免費(fèi)證書(shū)制作https的方法
這篇文章主要介紹了利用nginx和騰訊云免費(fèi)證書(shū)制作https的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11

