Back to Blogs
nginx
web
linux
server

Nginx 服务器

Soloman
2019-10-27

Nginx 服务器

基本概念

正向代理

一般的访问流程是客户端直接向目标服务器发送请求并获取内容,使用正向代理后,客户端改为向代理服务器发送请求,并指定目标服务器(原始服务器),然后由代理服务器和原始服务器通信,转交请求并获得的内容,再返回给客户端。正向代理隐藏了真实的客户端,为客户端收发请求,使真实客户端对服务器不可见。

例如:你的浏览器无法直接访问谷歌,这时候可以通过一个代理服务器来帮助你访问谷歌,那么这个服务器就叫正向代理。

正向代理

反向代理

反向代理后,直接收到请求的服务器是代理服务器,然后将请求转发给内部网络上真正进行处理的服务器,得到的结果返回给客户端。反向代理隐藏了真实的服务器,代理服务器为真实服务器收发请求,使真实服务器对客户端不可见。一般在处理跨域请求的时候比较常用。现在基本上所有的大型网站都设置了反向代理。

一般给客户端做代理的都是正向代理,给服务器做代理的就是反向代理。

反向代理

负载均衡

请求爆发式增长的情况下,单个机器性能再强劲也无法满足要求了,这个时候集群的概念产生了,单个服务器解决不了的问题,可以使用多个服务器,然后将请求分发到各个服务器上,将负载分发到不同的服务器,这就是负载均衡,核心是「分摊压力」。Nginx 实现负载均衡,一般来说指的是将请求转发给服务器集群。

多个请求发送到代理服务器,那么由代理服务器根据服务器数量,平均分配,每个服务器处理少量几个请求,这个过程就叫做负载均衡。

例如:晚高峰乘坐地铁的时候,入站口经常会有地铁工作人员大喇叭“请走 B 口,B 口人少车空....”,这个工作人员的作用就是负载均衡。

负载均衡

动静分离

为了加快网站的解析速度,可以把动态页面和静态页面交给不同的服务器来解析,加快解析的速度,降低由单个服务器的压力。

一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。

动静分离

Nginx 常用命令

sudo apt-get install nginx

nginx -h # 查看 Nginx 的命令

sudo /etc/init.d/nginx start    # 启动
sudo /etc/init.d/nginx stop     # 停止
sudo /etc/init.d/nginx restart  # 重启

nginx # 启动
nginx -s reload  # 向主进程发送信号,重新加载配置文件,热重启
nginx -s reopen	 # 重启 Nginx
nginx -s stop    # 快速关闭
nginx -s quit    # 等待工作进程处理完成后关闭
nginx -T         # 查看当前 Nginx 最终的配置
nginx -t -c <配置路径>    # 检查配置是否有问题,如果已经在配置目录,则不需要-c

systemctl 是 Linux 系统应用管理工具 systemd 的主命令,用于管理系统,我们也可以用它来对 Nginx 进行管理,相关命令如下

systemctl start nginx    # 启动 Nginx
systemctl stop nginx     # 停止 Nginx
systemctl restart nginx  # 重启 Nginx
systemctl reload nginx   # 重新加载 Nginx,用于修改配置后
systemctl enable nginx   # 设置开机启动 Nginx
systemctl disable nginx  # 关闭开机启动 Nginx
systemctl status nginx   # 查看 Nginx 运行状态

Nginx 配置

/etc/nginx/conf.d/ 文件夹,是我们进行子配置的配置项存放处,/etc/nginx/nginx.conf 主配置文件会默认把这个文件夹中所有子配置项都引入

main        # 全局配置,对全局生效
├── events  # 配置影响 Nginx 服务器或与用户的网络连接
├── http    # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
│   ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│   ├── server   # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
│   ├── server
│   │   ├── location  # server 块可以包含多个 location 块,location 指令用于匹配 uri
│   │   ├── location
│   │   └── ...
│   └── ...
└── ...

配置文件的语法规则:

  • 配置文件由指令与指令块构成;
  • 每条指令以 ; 分号结尾,指令与参数间以空格符号分隔;
  • 指令块以 {} 大括号将多条指令组织在一起;
  • include 语句允许组合多个配置文件以提升可维护性;
  • 使用 # 符号添加注释,提高可读性;
  • 使用 $ 符号使用变量;
  • 部分指令的参数支持正则表达式;
main                                # 全局配置

events {                            # 工作模式配置
}

http {                              # http设置
    ....
    server {                        # 服务器主机配置(虚拟主机、反向代理等)
        ....
        location {                  # 路由配置(虚拟目录等)
            ....
        }

        location path {
            ....
        }

        location otherpath {
            ....
        }
    }

    server {
        ....
        location {
            ....
        }
    }

    upstream name {                  # 负载均衡配置
        ....
    }
}

配置文件要由6个部分组成:

  • main:用于进行nginx全局信息的配置
  • events:用于nginx工作模式的配置
  • http:用于进行http协议信息的一些配置
  • server:用于进行服务器访问信息的配置
  • location:用于进行访问路由的配置
  • upstream:用于进行负载均衡的配置

Nginx 的典型配置

user  nginx;                        # 运行用户,默认即是nginx,可以不进行设置
worker_processes  1;                # Nginx 进程数,一般设置为和 CPU 核数一样
error_log  /var/log/nginx/error.log warn;   # Nginx 的错误日志存放目录
pid        /var/run/nginx.pid;      # Nginx 服务启动时的 pid 存放位置

events {
    use epoll;     # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择最适合你操作系统的)
    worker_connections 1024;   # 每个进程允许最大并发数
}

http {   # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
    # 设置日志模式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;   # Nginx访问日志存放位置

    sendfile            on;   # 开启高效传输模式
    tcp_nopush          on;   # 减少网络报文段的数量
    tcp_nodelay         on;
    keepalive_timeout   65;   # 保持连接的时间,也叫超时时间,单位秒
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;      # 文件扩展名与类型映射表
    default_type        application/octet-stream;   # 默认文件类型

    include /etc/nginx/conf.d/*.conf;   # 加载子配置项
    
    server {
    	listen       80;       # 配置监听的端口
    	server_name  localhost;    # 配置的域名
    	
    	location / {
    		root   /usr/share/nginx/html;  # 网站根目录
    		index  index.html index.htm;   # 默认首页文件
    		deny 172.168.22.11;   # 禁止访问的ip地址,可以为all
    		allow 172.168.33.44;# 允许访问的ip地址,可以为all
    	}
    	
    	error_page 500 502 503 504 /50x.html;  # 默认50x对应的访问页面
    	error_page 400 404 error.html;   # 同上
    }
}

main 模块

  • user 指定nginx worker进程运行用户以及用户组
  • worker_processes 指定nginx要开启的子进程数量,运行过程中监控每个进程消耗内存(一般几M~几十M不等)根据实际情况进行调整,通常数量是CPU内核数量的整数倍
  • error_log 定义错误日志文件的位置及输出级别【debug / info / notice / warn / error / crit】
  • pid 指定进程id的存储文件的位置
  • worker_rlimit_nofile 指定一个进程可以打开最多文件数量的描述
user root;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events 模块

  • worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同决定的。
  • multi_accept 配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
  • use epoll 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue
events {
        worker_connections 1024;
        multi_accept on;
        use epoll;
}

http 模块

  • 诸如反向代理和负载均衡都在此配置
http {
    # 基础配置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # SSL证书配置
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    # 日志配置
    access_log /etc/nginx/log/access.log;
    error_log /etc/nginx/log/error.log;

    # Gzip 压缩配置
    gzip on;
    gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript
    # text/xml application/xml application/xml+rss text/javascript;

    # 虚拟主机配置
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

server 模块

  • srever 模块是http的一个子模块,用来定义一个虚拟服务器的配置信息
  • server:一个虚拟主机的配置,一个http中可以配置多个server
  • erver_name:用力啊指定ip地址或者域名,多个配置之间用空格分隔
  • root:表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录
  • index:用户访问web网站时的全局首页
  • charset:用于设置www/路径中配置的网页的默认编码格式
  • access_log:用于指定该虚拟主机服务器中的访问记录日志存放路径
  • error_log:用于指定该虚拟主机服务器中访问错误日志的存放路径
server {
    listen       80;
    server_name  127.0.0.1;
    root         /home/soloman/website/;
    index        index.php index.html index.html;
    charset      utf-8;
    access_log   /etc/nginx/log/access.log;
    error_log    /etc/nginx/log/error.log;
}

# 重定向http自动转https
server {
    listen 80;
    server_name soloman.vip www.soloman.vip;
    return 301 https://$server_name$request_uri;
}

location 模块

语法格式:

  1. = 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;
  2. ^~ 用于不含正则表达式的 uri 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;
  3. ~ 表示用该符号后面的正则去匹配路径,区分大小写;
  4. ~* 表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;
  5. 如果 uri 包含正则表达式,则必须要有 ~~* 标志。
location [ = | ~ | ~* | ^~] uri {
	...
}
  • location 模块是http的一个子模块,主要用于配置路由访问信息
  • location /:表示匹配访问根目录
  • root:用于指定访问根目录时,访问虚拟主机的web目录
  • index:在不指定访问具体资源时,默认展示的资源文件列表
location / {
    root    /home/soloman/website/html;
    index    index.php index.html index.htm;
}

# 反向代理配置方式
location / {
    proxy_pass http://localhost:8888;
    proxy_set_header X-real-ip $remote_addr;
    proxy_set_header Host $http_host;
}

# uwsgi模式下的服务器配置访问方式
location / {
    include uwsgi_params;
    uwsgi_pass localhost:8080;
}

Nginx 常用全局变量

网上搜索关键字「nginx内置预定义变量」可以找到更多

全局变量名功能
$host请求信息中的 Host,如果请求中没有 Host 行,则等于设置的服务器名,不包含端口
$request_method客户端请求类型,如 GETPOST
$remote_addr客户端的 IP 地址
$args请求中的参数
$arg_PARAMETERGET 请求中变量名 PARAMETER 参数的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer...
$content_length请求头中的 Content-length 字段
$http_user_agent客户端agent信息
$http_cookie客户端cookie信息
$remote_addr客户端的IP地址
$remote_port客户端的端口
$server_protocol请求使用的协议,如 HTTP/1.0HTTP/1.1
$server_addr服务器地址
$server_name服务器名称
$server_port服务器的端口号
$schemeHTTP 方法(如http,https)

反向代理配置

反向代理其他的指令:

  1. proxy_set_header:在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息;
  2. proxy_connect_timeout:配置 Nginx 与后端代理服务器尝试建立连接的超时时间;
  3. proxy_read_timeout:配置 Nginx 向后端服务器组发出 read 请求后,等待相应的超时时间;
  4. proxy_send_timeout:配置 Nginx 向后端服务器组发出 write 请求后,等待相应的超时时间;
  5. proxy_redirect:用于修改后端服务器返回的响应头中的 Location 和 Refresh

举例:比如我们监听 9001 端口,然后把访问不同路径的请求进行反向代理:

  1. 把访问 http://www.test.soloman.vip:9001/hello` 的请求转发到 http://127.0.0.1:8088
  2. 把访问 http://www.test.soloman.vip:9001/world` 的请求转发到 http://127.0.0.1:8089
server {
  listen 9001;
  server_name *.soloman.vip;

  location ~ /hello/ {
    proxy_pass http://127.0.0.1:8088;
  }
  
  location ~ /world/ {
    proxy_pass http://127.0.0.1:8089;
  }
}

跨域 CORS 配置

通过反向代理绕过

在前端服务地址为 hello.soloman.vip 的页面请求 world.soloman.vip 的后端服务导致的跨域,可以这样配置:

server {
  listen 9001;
  server_name hello.soloman.vip;

  location / {
    proxy_pass world.soloman.vip;
  }
}

这样就将对前一个域名 hello.soloman.vip 的请求全都代理到了 world.soloman.vip,前端的请求都被我们用服务器代理到了后端另一个地址下,绕过了跨域。

如果要区分动静文件,即静态文件由代理服务器处理,动态API由其他域名处理会跨域,可以重写请求:

# 请求跨域,约定代理后端服务请求path以/api/开头
location ^~/apis/ {
    # 这里重写了请求,将正则匹配中的第一个分组的path拼接到真正的请求后面,并用break停止后续匹配
    rewrite ^/apis/(.*)$/$1break;
    proxy_pass world.soloman.vip;
  
    # 两个域名之间cookie的传递与回写
    proxy_cookie_domain world.soloman.vip hello.soloman.vip;
}

配置 headers

/etc/nginx/conf.d/ 文件夹中新建一个配置文件,对应二级域名 world.soloman.vip

# /etc/nginx/conf.d/world.soloman.vip.conf

server {
  listen       80;
  server_name  world.soloman.vip;
  
	add_header 'Access-Control-Allow-Origin'$http_origin;   # 全局变量获得当前请求origin,带cookie的请求不支持 *
	add_header 'Access-Control-Allow-Credentials''true';    # 为 true 可带上 cookie
	add_header 'Access-Control-Allow-Methods''GET, POST, OPTIONS';  # 允许请求方法
	add_header 'Access-Control-Allow-Headers'$http_access_control_request_headers;  # 允许请求的 header,可以为 *
	add_header 'Access-Control-Expose-Headers''Content-Length,Content-Range';
	
  if ($request_method = 'OPTIONS') {
		add_header 'Access-Control-Max-Age' 1728000;   # OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
		add_header 'Content-Type''text/plain; charset=utf-8';
		add_header 'Content-Length' 0;
    
		return 204;                  # 200 也可以
	}
  
	location / {
		root  /usr/share/nginx/html/world;
		index index.html;
	}
}

配置 gzip 压缩

这个配置可以插入到 http 模块整个服务器的配置里,也可以插入到需要使用的虚拟主机的 server 或者下面的 location 模块中,当然像下面这样写入新建的配置文件的话,就是被 include 到 http 模块中了。

# /etc/nginx/conf.d/gzip.conf

gzip on; # 默认off,是否开启 gzip
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

# 上面两个开启基本就能跑起了,下面的愿意折腾就了解一下
gzip_static on;
gzip_proxied any;
gzip_vary on;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_min_length 1k;
gzip_http_version 1.1;
  1. gzip_types:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;
  2. gzip_static:默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容;
  3. gzip_proxied:默认 off,nginx做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;
  4. gzip_vary:用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩;
  5. gzip_comp_level:gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;
  6. gzip_buffers:获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得;
  7. gzip_min_length:允许压缩的页面最小字节数,页面字节数从header头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大;
  8. gzip_http_version:默认 1.1,启用 gzip 所需的 HTTP 最低版本;

配置负载均衡

Nginx 提供了好几种分配方式,默认为轮询,就是轮流来。有以下几种分配方式:

  1. 轮询,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;
  2. weight,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;
  3. ip_hash,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;
  4. fair(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装;
http {
  upstream myserver {
  	# ip_hash;  # ip_hash 方式
    # fair;   # fair 方式
    server 127.0.0.1:8081;  # 负载均衡目的服务地址
    server 127.0.0.1:8082;
    server 127.0.0.1:8083 weight=10;  # weight 方式,不写默认为 1
  }
 
  server {
    location / {
    	proxy_pass http://myserver;
      	proxy_connect_timeout 10;
    }
  }
}

配置动静分离

方式主要有两种,一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案。另外一种方法就是动态跟静态文件混合在一起发布, 通过 Nginx 配置来分开。通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。

具体 expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 expires 来缓存),我这里设置 3d,表示在这 3 天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化。则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。

server {
  location /www/ {
  	root /data/;
    index index.html index.htm;
    expires 3d;
  }
  
  location /image/ {
  	root /data/;
    autoindex on;
    expires 10d;
  }
}

适配 PC 或移动设备

根据用户设备不同返回不同样式的站点,以前经常使用的是纯前端的自适应布局,但无论是复杂性和易用性上面还是不如分开编写的好,比如我们常见的淘宝、京东......这些大型网站就都没有采用自适应,而是用分开制作的方式,根据用户请求的 user-agent 来判断是返回 PC 还是 H5 站点。

# /etc/nginx/conf.d/autofit.soloman.vip.conf

server {
  listen 80;
  server_name autofit.soloman.vip;

  location / {
	root  /usr/share/nginx/html/pc;
    if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
      root /usr/share/nginx/html/mobile;
    }
	index index.html;
  }
}

配置 HTTPS

server {
  listen 443 ssl http2 default_server;   # SSL 访问端口号为 443
  server_name soloman.vip;         # 填写绑定证书的域名
    
  add_header X-Frame-Options DENY;           # 减少点击劫持
  add_header X-Content-Type-Options nosniff; # 禁止服务器自动解析资源类型
  add_header X-Xss-Protection 1;             # 防XSS攻击

  ssl_certificate /etc/nginx/https/1_soloman.vip_bundle.crt;   # 证书文件地址
  ssl_certificate_key /etc/nginx/https/2_soloman.vip.key;      # 私钥文件地址
  ssl_session_timeout 10m;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      #请按照以下协议配置
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  ssl_prefer_server_ciphers on;
  
  location / {
    root         /usr/share/nginx/html;
    index        index.html index.htm;
  }
}

配置高可用集群(双机热备)

当主 Nginx 服务器宕机之后,切换到备份 Nginx 服务器,使用 keepalived

静态服务

server {
  listen       80;
  server_name  static.soloman.vip;
  charset utf-8;    # 防止中文文件名乱码

  location /download {
    alias	          /usr/share/nginx/html/static;  # 静态资源目录
    
    autoindex               on;    # 开启静态资源列目录
    autoindex_exact_size    off;   # on(默认)显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB
    autoindex_localtime     off;   # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
  }
}

图片防盗链

server {
  listen       80;
  server_name  *.soloman.vip;
  
  # 图片防盗链
  location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
    valid_referers none blocked 192.168.0.2;  # 只允许本机 IP 外链引用
    if ($invalid_referer){
      return 403;
    }
  }
}

请求过滤

# 非指定请求全返回 403
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
  return 403;
}

location / {
  # IP访问限制(只允许IP是 192.168.0.2 机器访问)
  allow 192.168.0.2;
  deny all;
  
  root   html;
  index  index.html index.htm;
}

静态文件缓存

静态文件在打包的时候通常会增加了 hash,所以缓存可以设置的长一点,先设置强制缓存,再设置协商缓存;如果存在没有 hash 值的静态文件,建议不设置强制缓存,仅通过协商缓存判断是否需要使用缓存。

# 图片缓存时间设置
location ~ .*\.(css|js|jpg|png|gif|swf|woff|woff2|eot|svg|ttf|otf|mp3|m4a|aac|txt)$ {
	expires 10d;
}

# 如果不希望缓存
expires -1;

HTTP 请求转发到 HTTPS

server {
    listen      80;
    server_name www.soloman.vip;

    # 单域名重定向
    if ($host = 'www.soloman.vip'){
        return 301 https://www.soloman.vip$request_uri;
    }
    # 全局非 https 协议时重定向
    if ($scheme != 'https') {
        return 301 https://$server_name$request_uri;
    }

    # 或者全部重定向
    return 301 https://$server_name$request_uri;

    # 以上配置选择自己需要的即可,不用全部加
}

泛域名路径分离

有时候我们可能需要配置一些二级或者三级域名,希望通过 Nginx 自动指向对应目录,比如:

  1. test1.doc.soloman.vip 自动指向 /usr/share/nginx/html/doc/test1 服务器地址;
  2. test2.doc.soloman.vip 自动指向 /usr/share/nginx/html/doc/test2 服务器地址;
server {
    listen       80;
    server_name  ~^([\w-]+)\.doc\.soloman\.vip$;

    root /usr/share/nginx/html/doc/$1;
}

泛域名转发

有时候我们希望把二级或者三级域名链接重写到我们希望的路径,让后端就可以根据路由解析不同的规则:

  1. test1.serv.soloman.vip/api?name=a 自动转发到 127.0.0.1:8080/test1/api?name=a
  2. test2.serv.soloman.vip/api?name=a 自动转发到 127.0.0.1:8080/test2/api?name=a
server {
    listen       80;
    server_name ~^([\w-]+)\.serv\.soloman\.vip$;

    location / {
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_pass              http://127.0.0.1:8080/$1$request_uri;
    }
}