想用一台nginx服务器同时承接多个域名,只需为每个域名各写一个带独立server_name的server块,再统一管理好端口监听和配置文件就能实现。 下面我把原理、配置方式、实操步骤和常见坑位一次讲清楚,照着抄就能用。
nginx如何绑定多个域名到同一服务器:先弄清按什么路由
在动手写配置之前,你得先明白nginx凭什么区分不同域名,浏览器访问你的网站时,请求头里会带一个Host字段,里面写着用户输入的域名,nginx收到请求后,把Host字段和配置文件里的server_name挨个比对,命中哪个server块,就用哪个server块里的规则来处理请求,所以就算几十个域名解析到同一个公网IP,nginx也能精准地把用户送到对应的站点,互不干扰。
这种按“域名+端口+IP”三元组做路由选择的机制,是nginx虚拟主机功能的基础,行业共识认为,一台普通云服务器承载几十个低流量网站的配置压力几乎可以忽略不计,真正限制你的是带宽和内存。
nginx一台服务器绑定多个域名的三种配置方式对比
不同场景适合不同写法,不存在哪个绝对最好,常见有三种,我按推荐程度从高到低排列。
不同域名各写独立server块
这是最稳妥的结构,一个域名对应一个server块,互不影响,假设你有a.com和b.com两个站点,nginx配置文件的写法大致如下:
server {
listen 80;
server_name a.com www.a.com;
root /var/www/a.com;
index index.html;
}
server {
listen 80;
server_name b.com www.b.com;
root /var/www/b.com;
index index.html;
}
优点很明显:改动a站配置时完全不影响b站,出问题也好排查,缺点同样存在域名多起来后,主配置文件会越来越长,不好维护。
同一个server块里写多个server_name
如果你想用同一套代码、同一个目录承接多个域名,可以这么写:
server {
listen 80;
server_name a.com b.com c.com;
root /var/www/same-site;
index index.html;
}
应用场景很典型:比如你把a.com、a.cn、a.net三个域名指向同一个站点,或者买了相似域名做防丢保护,这种写法省配置,但所有域名共用一个站点根目录,没法单独控制。
用include拆分配置文件
公司里管着十几台线上服务器的人基本都会用这种结构,在/etc/nginx/conf.d/下为每个站点建一个独立.conf文件,注意文件名别用点号,比如a.conf、b.conf,然后在nginx.conf的http块里加一行:
include /etc/nginx/conf.d/.conf;
这样每个站点的配置各自独立存放,找问题、改设置都非常直观,把整台服务器的配置打包带走也方便,换服务器时直接复制目录即可。
三种方式没有绝对的优劣,关键看你需要管理多少域名、是否共用代码根目录,我实测下来,超过5个域名时用include拆分的方式最顺手。
同一台服务器多个域名从解析到生效的完整操作流程
光改nginx配置不够,从域名解析到访问生效,中间隔着好几个环节,每个都不能漏。
先把域名解析到服务器IP并放行端口
- 去域名注册商的DNS控制台添加A记录,把a.com和b.com都指向同一台服务器的公网IP。
- TTL默认值一般够用,但调试阶段建议改成600秒或更低,生效更快。
- 检查云服务商的安全组策略,放行80和443端口,这一步经常被忽略。
- 如果你人在国内,服务器也买了国内机房,域名必须先完成ICP备案才能正常访问,海外服务器则不需要。
下面用一个表格快速比对两种访问场景下的准备工作:
| 场景 | 80端口HTTP | 443端口HTTPS |
|---|---|---|
| 需准备 | A记录、安全组放行80 | A记录、安全组放行443、SSL证书 |
| 证书来源 | 无需证书 | Let’s Encrypt免费证书或云厂商免费证书 |
确认nginx安装路径和目录结构
不同系统下nginx的配置目录有点差异,Debian系和Ubuntu通常在/etc/nginx/下操作,CentOS以及通过宝塔面板安装的nginx也会使用类似的结构,先执行一条命令看清楚目录:
nginx -t
这条命令既能检查语法,也能输出你当前用的配置文件绝对路径,对找错特别有用,确认无误后,再创建站点根目录,
mkdir -p /var/www/a.com echo '<h1>Hello from a.com</h1>' > /var/www/a.com/index.html
写配置并加载
照前面说的方式写配置文件,写完后必须先跑一遍nginx -t,显示syntax is ok再reload:
nginx -t nginx -s reload
reload属于平滑加载,不会中断现有连接,如果你的nginx配置里加了SSL证书,还得确认证书文件路径和私钥路径都填对了,填错会导致nginx启动失败。
到这里,同一台服务器上的多个域名就完成绑定流程了。
nginx多域名共用80端口后访问异常怎么办
配置看起来没毛病,nginx也reload了,但打开域名发现进的不是自己想要的站,这类问题在实操中非常高频,详细说说原因和排查路径。
访问域名总是跳到第一个server块
nginx的匹配规则不是你写在前面的就优先级高,如果请求的域名根本没有对应的server_name,nginx会把请求交给默认server,也就是listen参数里带default_server标记的server块,没有任何server块标记时,nginx默认选第一个server块接包。
排查方法:确认每个域名是否真的解析到了这台服务器,再看server_name拼写有没有打错,命令行直接看当前域名指向哪里:
dig a.com +short
如果返回的IP和服务器不一致,说明问题不在nginx在DNS。
同一个IP访问正常但具体域名报错
这多半是证书出了问题,你给a.com申请了证书,但server块里写了两个server_name共用一个证书,导致访问b.com时服务器返回的是a.com的证书,浏览器自然拦截,解决办法很简单:为b.com申请独立证书,并分别写两个server块。
本地访问正常但手机端打不开
先别折腾nginx配置,检查一下你手机用的DNS和本地是不是同一个,手机可能走了运营商DNS,解析记录还没完全全球同步,一般等几分钟就好。
绑定多个域名时防盗刷和恶意解析的预防措施
域名解析到同一台服务器后,难免有人把不相关的域名也解析过来,这些域名没有对应的server_name,nginx默认把请求丢给第一个server块,如果第一个server块是个电商网站,就会收到大量陌生域名的流量,严重时甚至影响正常用户访问。
处理办法:单独建一个默认拒绝的server块,把它设为default_server:
server {
listen 80 default_server;
server_name _;
return 444;
}
返回444表示nginx直接关闭连接,不返回任何响应,把这块放在配置最前面,就能有效拦截所有不认识的域名请求,你可以在nginx日志里定期grep访问来源,把异常域名筛出来,然后配合云服务商设置防盗解析。
nginx绑定多个域名常见问题快问快答
nginx绑定多个域名时端口不同可以吗
可以,你完全可以让a.com监听80端口、b.com监听8080端口,只要公网安全组放行对应端口就能访问,但从用户体验和安全角度考虑,不建议这样做,多数情况下,门户网站都统一用80和443端口,内部测试环境用非标准端口没毛病,统一端口也便于日后统一接入CDN或WAF防护。
同一台服务器绑定的域名太多会不会拖慢响应
在合理规划下影响不大,nginx对每个server块只做字符串比对,不涉及数据库查询,几百个server块时内存占用会上升,但真正影响响应速度的是后端应用处理能力和带宽资源,一台2核4G的云服务器,承载10到20个纯静态或低并发动态站点完全没有问题,如果每个站点都有很高的并发,它们之间会互相争抢CPU和内存,这时就该考虑拆分到多台服务器或用负载均衡。
域名不备案能绑定国内云服务器吗
大哥,真的不行,国内主流云厂商(简米云、酷番云等)都要求域名先取得ICP备案号才能对80和443端口提供服务,如果你暂时不想备案,要么改用海外服务器节点,要么用云服务器厂商提供的临时域名调试,实际业务上线前,建议尽早提交备案申请,因为备案审核通常需要几天到两周不等。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/627113.html





