一些闲聊

坐标深圳南山。

前两天公司晚上9点过,通知第二天要48小时核酸才能进办公楼。看到消息,已经是9点半多了,走到公司附近的核酸点,是10点过。然后发现那个点人好少,走近了才发现核酸点已经下班了,不过医护人员还没走,旁边也围了一些群众,应该是想让医护人员再做几个。

看样子做不了,我就准备换个点了,还没走远,就听到工作人员很大声地在说:“谁来理解我们?我们从大年初一就开始在这里测核酸。谁来理解我们”,“谁明天来这里做一天义工试试?”

除夕晚上,深圳出现了疫情,看深小卫下面的留言,确实是不少人,刚到家,吃了个饭,就开始买票/开车回深圳。

也不说啥了,互相多些理解吧。

事后我就想起来那句话:中国真的是被这个国家最勇敢的人保护得很好。(ps,最勇敢的人保护了这块土地,也保护了这块土地上的人)

前言

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配置,域名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配置如下:

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

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

实测结果

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

这。。。我们就有点想不通了,没理由啊,为啥呢,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

抓包结果:

看到这边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

结果如下:

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

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

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

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

上面这段话,大概就是说,虚拟主机的匹配,是通过取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个,中间绕的路比上面其实还多一点。

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

Nginx中关于虚拟主机的一点冷门知识的更多相关文章

  1. 第四百零二节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署,uwsgi安装和启动,nginx的安装与启动,uwsgi与nginx的配置文件+虚拟主机配置

    第四百零二节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署,uwsgi安装和启动,nginx的安装与启动,uwsgi与nginx的配置文件+虚拟主机配置 软件版本  uwsgi- ...

  2. Nginx(二):虚拟主机配置

    什么是虚拟主机? 虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Intemet服务器功 ...

  3. Nginx多站点虚拟主机实现单独启动停止php-fpm、单独控制权限设置

    Nginx多站点虚拟主机实现单独启动停止php-fpm.单独控制权限设置 来源:osyunwei.com 作者:qihang01 发表于:2012-08-19 21:26 点击: 说明: 站点1:bb ...

  4. 在Apache中开启虚拟主机

    最近在自学LAMP,在Apache中尝试着开启虚拟主机的时候,遇到了挺多麻烦的,这里也顺便总结一下,在Apache中开启虚拟主机的时候,主要有下面几个步骤: 1.新建一个文件夹作为虚拟主机,用来存储网 ...

  5. linux上nginx上配置虚拟主机的相关配置

    1.配置主配置: nginx/conf/nginx.conf 2.虚拟主机配置:nginx/conf/extra/learn.weixin.com.conf 配置完后,重启服务器!

  6. Nginx 和Apache 中的虚拟主机的概念

    在部署环境的时候,有时候会引用到虚拟主机的概念,什么是虚拟主机呢,博主之前一直把虚拟主机的概念没搞清楚,导致在部署的时候,一直动不动就404 ,或者500,或者服务器不通 所以,什么是虚拟主机呢? 虚 ...

  7. 通过ngx-lua来统计Nginx上的虚拟主机性能数据

    Web server调研分析 Filed under: Web Server — cmpan @ 2012-10-29 20:38:34 摘要 简单可依赖的架构首先需要有一个简单可依赖的前端WebSe ...

  8. nginx介绍(三) - 虚拟主机

    前言 前面提到过, 由nginx来分发请求到tomcat中, 那么怎么来区分这些tomcat呢? 我们一般访问网站的时候, 是不是可以使用 ip : port (127.0.0.1:8080)的方式来 ...

  9. Centos7 nginx配置多虚拟主机过程

    一.前提准备 1.已经安装好了的Centos7服务器 2.ip 为192.168.1.209   [本次的配置ip] 3.确定防火墙等已经关闭 二.nignx配置文件参数详解 要配置多台虚拟主机,就需 ...

随机推荐

  1. 【Java】main方法的理解

    main方法的理解 main()方法作为程序的入口 main()方法也是一个普通的静态方法 main()方法可以作为我们与控制台交互的方式.(之前:使用Scanner) main方法中的参数args就 ...

  2. 封装OCX

    封装OCX的办法有2种: 1. 使用C++的MFC activex项目生成OCX 2. 使用C#的用户控件生成OCX(.net core好像不支持) 注意:以管理员身份运行Visual Studio ...

  3. dubbo 实现简易分布式服务

    dubbo 实现简易分布式服务 服务器需要搭建zookeeper环境 zookeeper端口2181 还需要有java环境 1.需求 某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址: 我 ...

  4. 通过Javascript实现把数组里的内容以表格方式呈现到页面从

    一.把数组里的内容呈现到页面从,以表格方式 <!doctype html> <html> <head> <meta charset="utf-8&q ...

  5. Java集合-ArrayList源码分析

    目录 1.结构特性 2.构造函数 3.成员变量 4.常用的成员方法 5.底层数组扩容原理 6.序列化原理 7.集合元素排序 8.迭代器的实现 9.总结 1.结构特性 Java ArrayList类使用 ...

  6. 处理json中的空格

    很多json中带有空格 而json解析类很多自带去空行 导致解析json如下 只能在解析之前用"111111"之类的替换 之后再替换回来 result = result.Repla ...

  7. redis实现简易在线聊天室

    redis_flask简易聊天室 项目构建 这时一个基于Redis数据库的简单小项目,使用redis缓存数据,并通过flask部署到浏览器,运行截图如下: 输入名字后,就可以登陆到聊天室,主要包括三个 ...

  8. Git使用简单教程,从建库到远程操作

    本地库初始化 找到项目文件->右键git bash->git init 设置签名 形式: 用户名 邮箱地址 作用: 区分不同开发人员身份 注意:这里设置的签名和登录的远程库的账号密码没有任 ...

  9. 使用 Swoole 加速你的 CMS 系统

    项目介绍 MyCms是一款基于Laravel开发的开源免费的自媒体博客CMS系统,适用于个人网站及企业网站开发使用,助力个人开发者知识技术变现 Swoole介绍 Swoole: PHP的异步.并行.高 ...

  10. ApacheCN 所有教程/文档集已备份到 Coding

    QuantLearning 数据科学 WIKI 安全 WIKI 团队 WIKI Sklearn 中文文档 PyTorch 中文文档 TutorialsPoint 中文系列教程 Java8 中文官方教程 ...