多级nginx的配置及docker启动

多级nginx的配置及docker启动

因为自己的服务器跑了博客、api接口等服务,如:
博客:blog.luvying.com
api接口:api.luvying.com
而像api接口时不时会进行修改,又不希望因为修改api接口而导致博客一时访问不了,于是就有了试试能不能开多个nginx来配置多级nginx的想法

思路

大概的思路就是这样,首先开启一个root-nginx,作为服务器的一个大网关,来将请求转发给各个子nginx,然后开启子nginx来将请求转发到各个服务中,这样调试api接口的时候就不会影响到我博客的运行了

graph LR F(request) --> A(root-nginx:80 443) A(root-nginx:80 443) --> B(blog-nginx:8001) --> G(blog-service) A(root-nginx:80 443) --> C(api-nginx:8002) --> H(api-service1) C(api-nginx:8002) --> K(api-service2) A(root-nginx:80 443)--> D(C-nginx:8003) --> I(C-service) A(root-nginx:80 443) --> E(D-nginx:8004) --> J(D-service)

实现

首先是root-nginx

配置转发到各个子nginx
我这里展示配置了两个子nginx,blog-nginx和api-nginx,同时配置了SSL证书,如不需要直接listen 80,删去ssl相关配置即可
子nginx的server用自己云服务器内网IP就好了,没必要用外网的兜一大圈回来=。=

upstream blog-nginx{
    server 111.111.111.111:8001;  #云服务器内网IP
}
upstream api-nginx{
    server 111.111.111.111:8002;  #云服务器内网IP
}

server {
    #listen 80;
    listen 443 ssl;
    server_name blog.luvying.com;
    # 注意文件位置,是从/etc/nginx/下开始算起的
    ssl_certificate conf.d/blog.luvying.com.pem;
    ssl_certificate_key conf.d/blog.luvying.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers on;

    client_max_body_size 1024m;

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://blog-nginx;
    }
}
server {
    listen 80;
    #填写绑定证书的域名
    server_name blog.luvying.com;
    #把http的域名请求转成https
    return 301 https://$host$request_uri; 
}

server {
    #listen 80;
    listen 443 ssl;
    server_name api.luvying.com;
    # 注意文件位置,是从/etc/nginx/下开始算起的
    ssl_certificate conf.d/api.luvying.com.pem;
    ssl_certificate_key conf.d/api.luvying.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers on;

    client_max_body_size 1024m;
	    
    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header referer $http_referer;

        proxy_pass http://api-nginx;
    }
}
server {
    listen 80;
    #填写绑定证书的域名
    server_name api.luvying.com;
    #把http的域名请求转成https
    return 301 https://$host$request_uri;
}

blog-nginx

子nginx就没必要再配置多一次SSL证书了,毕竟也是之间用IP进行转发

可能有人会疑问,为什么这几个配置文件都配置了listen 80,端口不会冲突么?因为我是用docker来启动nginx的,可以进行端口映射,在启动各个nginx的时候将映射到8001、8002...上,如果在一台机器上要同时启动多个nginx的话,就得把子nginx监听端口换成8001、8002...等等,才不会端口冲突

upstream blog{
    server 111.111.111.111:8090;  #云服务器内网IP
}
server {
    listen 80;
    server_name 111.111.111.111;  #云服务器内网IP
    
    client_max_body_size 1024m;

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://blog;
    }
}

api-nginx

第二个子nginx也同理,直接转发到对应服务即可
这里展示了api-nginx将请求转到两个api服务的配置,根据实际情况修改即可

upstream api1{
    server 111.111.111.111:9001;  #云服务器内网IP
}
upstream api2{
    server 111.111.111.111:9002;  #云服务器内网IP
}
server {
    listen 80;
    server_name 111.111.111.111;  #云服务器内网IP
    
    client_max_body_size 1024m;

    location /api1 {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://api1;
    }
    location /api2 {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://api2;
    }
}

至此两级的nginx就配置完毕了,如果有需要配置更多级的nginx参照配置继续转发到下一级的nginx即可

docker启动配置

如果使用了docker,可以参考以下启动命令
root-nginx:
因为我的配置文件和证书文件放在了系统/data/nginx/conf.d/下,所以多加上了两个-v来映射,根据自己实际情况自行修改即可

docker run -itd --name root-nginx -p 80:80 -p 443:443 -v /data/nginx/conf.d/root-nginx.conf:/etc/nginx/conf.d/nginx.conf -v /data/nginx/conf.d/cert:/etc/nginx/conf.d -m 50m --restart=always nginx

blog-nginx:
同理,nginx配置文件路径根据自己实际情况自行修改
我加上了-m 51m限制nginx内存使用在51m,其实仅仅是为了能够在看docker stats的时候能够通过内存限制知道是哪个容器而已=。=
外部端口8001映射到容器内80端口

docker run -itd --name blog-nginx -p 8001:80 -v /data/nginx/conf.d/blog-nginx.conf:/etc/nginx/conf.d/nginx.conf -m 51m --restart=always nginx

api-nginx:

docker run -itd --name api-nginx -p 8002:80 -v /data/nginx/conf.d/api-nginx.conf:/etc/nginx/conf.d/nginx.conf -m 52m --restart=always nginx

后记

当然,对于不需要频繁修改配置的服务,比如博客,完全可以在root-nginx中直接进行转发,不需要再启动多一个blog-nginx(不过启动多一个nginx也就多用十几M的内存而已=。=)
如果需要其他子域名,也还是不可避免地要在root-nginx中添加相应的配置并重启,随着子域名的增加,要启动的子nginx也会增多,那么也可以对子nginx进行分组,比如分为两组:

  • 稳定不需要频繁改配置的
  • 暂时不稳定需要经常修改配置的

然后在root-nginx配置中的server_name将他们合并,如:server_name blog.luvying.com A.luvying.com B.luvying.com;,然后需要经常修改配置的几个域名也放在一块,这样就只需要启动三个nginx了:
root-nginxstable-nginxunstable-nginx

这是本菜鸡为了解决因为要经尝修改配置而重启nginx且不希望影响其他服务的处理办法,如果有dalao有更好的方法,欢迎和我交流~