写在前面
天呐不敢相信有一年没更博客了(捂脸,读研后越来越忙了.jpg),最近做了两个小项目,有一个需要将新的域名解析到已经绑定了另一个域名的服务器上,实现的过程中遇到了一点问题,最后用Nginx解决了,记录一下hhh
需求场景
已有域名a.cn和b.com,a.cn解析到服务器A 1.1.1.1,b.com解析到服务器B 2.2.2.2(默认均为80端口),现在我们在服务器B上部署了另一个网站,端口为1024,想要将这个网站挂到a.cn的子域名(假设为sub.a.cn)下,而不是b.com的子域名下,且不需要通过指定端口号的方式访问,该怎么做?
解决方案
具体来说,我们最终要做到访问sub.a.cn(默认为80端口),即访问2.2.2.2:1024的效果,需要先将子域名sub.a.cn解析到服务器B的ip(2.2.2.2),但域名的A记录不能做到解析到服务器的指定端口,只能默认为80端口,因此我们在服务器端需要做一层筛选,也就是监听80号端口,如果请求来自sub.a.cn,则将请求转发到1024端口,如果请求来自b.com,则请求转发至80端口。而这个筛选,可以通过Nginx反向代理实现。下面先介绍一下Nginx反向代理原理,只关心实现的可以跳过这一部分。
Nginx反向代理
上一篇博客讲flask的时候提到过相关原理,其实理解起来很容易,没有Nginx的话,我们发出的请求(如浏览器请求等)直接发给了web服务器,而Nginx充当了中介(代理)的角色,我们的请求先发给了Nginx,Nginx处理后再发给真正的web服务端。为什么叫反向代理?我个人的理解是它站在服务器的角度对请求进行处理,而正向代理是它站在客户端(用户)的角度,即用户是知道代理的存在的。
在网上看到两张图,觉得对理解正向/反向代理很有帮助,如下(图一为正向代理,图二为反向代理):
实现
- 在a.cn域名解析处添加一条A记录,主机记录为sub.a.cn,记录值为服务器B的ip(2.2.2.2)【注:域名需要备案】
- 此时访问sub.a.cn,即相当于访问2.2.2.2:80,接下来我们需要用nginx把来自sub.a.cn的请求转发到2.2.2.2:1024
- 在/etc/nginx/nginx.conf中增加一个server块如下(当然,最好是新建一个a.conf,然后在原来的conf最后加上include a.conf):
# 原来的Server,负责b.com的请求
server{
listen 80;
server_name b.com;
location / {
proxy_pass http://localhost:4000;
}
}
# 新的server,负责sub.a.cn的请求
server{
listen 80;
server_name sub.a.cn;
location / {
proxy_pass http://localhost:1024;
}
}
- 重新加载nginx:
nginx -s reload
再次访问sub.a.cn,即自动转发到2.2.2.2:1024了,此时访问b.com,仍为2.2.2.2:80
扩展:Nginx负载均衡实现
- 作用:将多个同类型的请求分发到不同服务器上,防止单台服务器上请求数过多而崩溃
- 实现:建立upstream组,将多台服务器(这里指的是web服务器,可以在同一台物理服务器上,也可以在多台物理服务器上)绑定到同一个upstream组,监听请求后使用proxy_pass将请求转发到该upstream组
upstream testServer1 {
server 2.2.2.2:4000;
server 2.2.2.2:4001;
....
}
server{
listen 80;
server_name b.com;
location / {
proxy_pass http://testServer1;
}
}
注:upstream组的名称不能有下划线