9

nginx server 如何写,如何写 nginx 配置

 3 years ago
source link: https://deepzz.com/post/how-to-write-nginx-server.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

nginx server 如何写,如何写 nginx 配置

本篇文章主要介绍 nginx server 虚拟服务器如何配置。其中包括的一些例子我会已保存到 nginx 。尽可能的想要整理一份比较完整的配置说明,避免找寻资料的麻烦。博主也尽可能的保证本篇文章的准确性,如有失误,请告知。

通过 $ nginx -V,你可以看到 nginx 的编译配置信息:

$ nginx -V
nginx version: nginx/1.17.3
built by gcc 8.3.0 (Debian 8.3.0-6)
built with OpenSSL 1.1.1c  28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads ...

其中可以看到 --prefix=/etc/nginx,nginx 安装时会把相关数据文件写入到该目录,如我们的配置文件 --conf-path

每次更改 nginx 的配置文件,你需要执行一下操作:

# 验证配置文件的正确性
$ nginx -T

# 重新加载配置文件
$ nginx -s reload

这里推荐 nginx 的官方文档地址:http://nginx.org/en/docs/

文档中涵盖了各个模块的配置用法,以及默认值,可以填写的上下文位置。

nginx-module-doc

目前 nginx 支持多种服务类型:

http
mail
stream
google perftools

我们 着重介绍 http 服务。其它服务基本知识点都能涵盖到。

安装完 nginx ,我们先来看一看 nginx 的默认配置 /etc/nginx/nginx.conf,当然可能与你的默认配置不同,不过大同小异:

# worker以什么身份运行
user  nginx; // default nobody

# worker进程个数,一般为 CPU 个数,也可选 auto
worker_processes  1; # default 1

# 每个worker可打开的描述符限制
worker_rlimit_nofile 8192;

# 错误日志保存路径和级别
error_log  /var/log/nginx/error.log warn;

# 进程pid保存路径
pid        /var/run/nginx.pid;

# 指定dns服务器
resolver 10.0.0.1;

events {
    # 每个worker最大连接数
    worker_connections  1024; # default 1024
}

# http 服务定义
http {
    # 加载 mime 类型
    include       /etc/nginx/mime.types;
    # 定义默认数据类型
    default_type  application/octet-stream;
    # 日志格式
    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;
    # 是否调用sendfile函数(zero copy 方式)来输出文件,如果磁盘IO重负载应用,可设置为off
    sendfile        on;
    # 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
    #tcp_nopush     on;

    keepalive_timeout  65;

    # 代理相关设置
    # proxy_connect_timeout 90;
    # proxy_read_timeout 180;
    # proxy_send_timeout 180;
    # proxy_buffer_size 256k;
    # proxy_buffers 4 256k;
    # proxy_busy_buffers_size 256k;
    # proxy_temp_file_write_size 256k;

    # tcp_nodelay on;
    
    # gzip 压缩
    #gzip  on;

    # 加载其它配置,这样我们在 conf.d 下写的文件才会生效
    include /etc/nginx/conf.d/*.conf;
}

加载配置 /etc/nginx/conf.d,才能让我们的配置生效:

# 加载其它配置
include /etc/nginx/conf.d/*.conf;

一般的,如果是小站点不用去修改默认配置。当流量到达一定程度,需要进行适当优化。

内置变量,nginx 各个模块都将请求的一些参数进行变量化,通过 $ + 变量名 即可使用。每个模块或多或少都有自己的变量。着重介绍下核心模块的 内置变量

# 通过arg_<name>的方式可取出相关参数,若请求 /foo?name=Tony&age=2,则 arg_name=tony arg_age=2
$arg_name
$args
# 客户端IP地址二进制
$binary_remote_addr
# 发送到客户端的字节数,不包括响应头
$body_bytes_sent
# 发送给客户端字节数
$bytes_sent
# 连接序列号
$connection
# 当前已经连接的请求书
$connection_requests
# Content-Length 请求头
$content_length
# Content-Type 请求头
$content_type
# cookie 名称
$cookie_name
# 当前请求的 root 或 alias 的值
$document_root
# 与 $uri 相同
$document_uri
# 优先级:请求行中的 host name,请求头中的 Host,请求匹配的 server name
$host
# host name
$hostname
# 任意请求头字段。变量名的最后一部分是转换为小写的字段名,用下划线替换破折号
$http_name
# 如果连接在 SSL 模式下运行,则为 on,否则为空字符串
$https
# ? 后如果请求行有参数,或者空字符串
$is_args
# 设置此变量可以限制响应速度
$limit_rate
# 当前时间(秒),分辨率为毫秒
$msec
# nginx 版本号
$nginx_version
# 当前 worker 进程号
$pid
# 如果是 pipelined 则为 p,否则为 . 
$pipe
# 代理协议头中的客户端地址,否则为空字符串,代理协议之前必须通过在listen指令中设置 proxy_protocol 参数来启用
$proxy_protocol_addr
# 来自代理协议头的客户端端口,否则为空字符串,代理协议之前必须通过在listen指令中设置 proxy_protocol 参数来启用
$proxy_protocol_port
# 与 $args 相同
$query_string
# 与当前请求的 root 或 alias 指令值对应的绝对路径名,所有符号链接都解析为实际路径
$realpath_root
# 客户端地址
$remote_addr
# 客户端端口
$remote_port
# 使用 Basic auth 的用户名
$remote_user
# 完整的请求行
$request
# 请求体,当将请求体读入内存缓冲区时,proxy_pass、fastcgi_pass、uwsgi_pass和scgi_pass指令处理的位置可以使用变量的值
$request_body
# 具有请求主体的临时文件的名称
$request_body_file
# 如果请求完成则为 OK,否则为空
$request_completion
# 当前请求的文件路径,基于 root 或 alias 和请求 URI
$request_filename
# 由16个随机字节生成的惟一请求标识符,以十六进制表示
$request_id
# 请求长度(包括请求行、头和请求体)
$request_length
# 请求方法,如 GET 或 POST
$request_method
# 请求处理时间,从客户端读取第一个字节以来的时间
$request_time
# 若请求 /foo?a=1&b=2,则 request_uri=/foo?a=1&b=2
$request_uri
# 如 http 或 https
$scheme
# 任意响应报头字段,变量名的最后一部分是转换为小写的字段名,用下划线替换破折号
$sent_http_name
# 响应结束时发送的任意字段,变量名的最后一部分是转换为小写的字段名,用下划线替换破折号
$sent_trailer_name
# 接受请求的服务器的地址
$server_addr
# 接受请求的 server 名称
$server_name
# 接受请求的 server 端口
$server_port
# 请求协议,如 HTTP/1.0 或 HTTP/1.1 或 HTTP/2.0
$server_protocol
# 响应状态
$status
$tcpinfo_rtt,$tcpinfo_rttvar,$tcpinfo_snd_cwnd,$tcpinfo_rcv_space
# 本地时间ISO 8601标准格式
$time_iso8601
# 通用日志格式的本地时间
$time_local
# 若请求 /foo?a=1&b=2,则 uri=/foo
$uri
# 用户代理
$http_user_agent
# cookie
$http_cookie

你还可以通过自定义变量指令 set 进行变量的定义。

server定义

server 即虚拟服务,它用来描述我们站点一些访问规则。需要填写在 http 标签中,可定义多个,如:

http {
    server {
        ...
    }
    server {
        ...
    }
    ...
}

一个常见的 server 的定义:

resolver 10.0.0.1;

# 负载均衡
upstream dynamic {    
    zone upstream_dynamic 64k;

    server backend1.example.com      weight=5;
    server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;
    server backend3.example.com      resolve;
    server backend4.example.com      service=http resolve;

    server backup1.example.com:8080  backup;
    server backup2.example.com:8080  backup;
}

# http服务
server {
    listen 80;
    server_name example.com www.example.com;
    location / {
        rewrite https://$host; # 重定向到https
    }
}

# https 服务
server {
    listen 443 ssl; # 监听端口
    server_name example.com www.example.com; # 匹配域名

    # ssl证书
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
    ssl_certificate     /usr/local/nginx/conf/cert.pem;
    ssl_certificate_key /usr/local/nginx/conf/cert.key;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    # 静态服务
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }
    # 反向代理
    location /api {
        proxy_pass http://dynamic;
        health_check;
    }
}

下面就让我们来详细解释下。

http_upstream_module

http_upstream_moduleupstream 说白了就是做负载均衡,它可以帮助我们定义一组相同服务的别名,如backend,当请求到来的时候可以通过相关策略帮我们选一组服务提供响应。

目前只能被 proxy_passfastcgi_passuwsgi_passscgi_passmemcached_passgrpc_pass 使用。

形式如下:

upstream <name> { # 命名
    server <address> [parameters]; # 服务
    server <address> [parameters];
    ...
}

[parameters] 参数可选以下值:

  • weight=number,default 1,设置 server 的权重
  • max_conns=number,default 0,限制 server 的活跃连接数,0 代表不限制
  • max_fails=number,default 1,设置在 fail_timeout 时间内失败的最大次数,可由 proxy_next_upstreamfastcgi_next_upstreamuwsgi_next_upstreamscgi_next_upstreammemcached_next_upstreamgrpc_next_upstream 指定下组 upstream,0 值代表不启用
  • fail_timeout=time,default 10s,设置多长时间判定无连接服务器失败
  • backup,标记 server 为备用 server,当 primary server 不可用时启用
  • down,标记 server 下线不可用
  • resolve,用来监视与服务器域名对应IP地址的更改,它会自动更改上游配置,upstream 必须驻留在共享内存中,必须写在 http 标签中。
http {
  resolver 10.0.0.1;

  upstream u {
    zone ...;
    ...
    server example.com resolve;
  }
}
  • route=string,设置 server 路由名称
  • server=name,
  • slow_start=time,慢启动,server 非正常状态恢复到正常需要的时间
  • drain,设置为 drain 模式

其它负载均衡设置:

  • zone name [size],设置共享内存的名称和大小
  • state file
  • hash key [consistent],负载均衡方式,key 可以为文本,变量,或其组合
  • ip_hash,负载均衡方式,根据IP地址范围分布 server,用 IPv4 前三个8位或整个IPv6
  • keepalive connections,设置到上游 server 保持最大空闲连接
upstream memcached_backend {
  server 127.0.0.1:11211;
  server 10.0.0.2:11211;

  keepalive 32;
}

server {
  ...

  location /memcached/ {
    set $memcached_key $uri;
    memcached_pass memcached_backend;
  }
}
  • keepalive_requests number,设置最大请求连接数
  • keepalive_timeout timeout,连接超时时间
  • ntlm,允许使用NTLM身份验证代理请求
upstream http_backend {
  server 127.0.0.1:8080;

  ntlm;
}

server {
  ...

  location /http/ {
    proxy_pass http://http_backend;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    ...
  }
}
  • least_conn,负载均衡方式,将请求传给活跃连接数最少的 server
  • least_time header | last_byte [inflight],负载均衡方式,将请求传给平均响应时间和活跃连接数最少的 server
  • queue number [timeout=time],队列缓存,当选择不到 server 处理请求时放入队列,如果队列满,返回502
  • random [two [method]],负载均衡方式,
  • sticky,会话关联,同一客户端请求将会被传给同一 upstream 的同一 server
  # cookie
  upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;

    sticky cookie srv_id expires=1h domain=.example.com path=/;
  }
  # route
  map $cookie_jsessionid $route_cookie {
    ~.+\.(?P<route>\w+)$ $route;
  }

  map $request_uri $route_uri {
    ~jsessionid=.+\.(?P<route>\w+)$ $route;
  }

  upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;

    sticky route $route_cookie $route_uri;
  }
  # learn
  upstream backend {
    server backend1.example.com:8080;
    server backend2.example.com:8081;

    sticky learn
      create=$upstream_cookie_examplecookie
      lookup=$cookie_examplecookie
      zone=client_sessions:1m;
  }

listen

listen 监听设置,来看一看可选参数:

默认 listen *:80 | *:8000;
listen address[:port] [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
listen port [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
listen unix:path [default_server] [ssl] [http2 | spdy] [proxy_protocol] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];

真的多,可平时也没用几个,举例:

listen 127.0.0.1:8000;
listen 127.0.0.1; # 如果只指定地址,默认监听 80
listen 8000;
listen *:8000;
listen localhost:8000;
listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;

# IPv6
listen [::]:8000;
listen [::1];

# unix socket
listen unix:/var/run/nginx.sock;

其它参数说明:

  • default_server,如果指定,server 将会成为默认 server
  • ssl,开启 ssl 模式,即 https
  • http2,正常情况开启 http2 都应该开始 ssl,但 nginx 也支持不开启 ssl 下的 http2 协议
  • spdy,和 http2 一样,建议开启 ssl
  • setfib=number,监听套接字设置关联的路由表FIB (SO_SETFIB选项)。这目前只适用于FreeBSD
  • fastopen=number,为监听套接字启用“TCP Fast Open”(1.5.8),并限制尚未完成三方握手的连接队列的最大长度
  • backlog=number
  • rcvbuf=size,接受 buffer 的大小(SO_CRCVBUF)
  • sndbuf=size,发送 buffer 的大小(SO_SNDBUF)
  • accept_filter=filter,可选 dataready 和 httpready,在 accept() 前过滤
  • deferred,指示在Linux上使用deferred accept() (TCP_DEFER_ACCEPT套接字选项)
  • bind,标记指定 address:port 单独的绑定
  • ipv6only on|off,只接受 IPv6 连接
  • reuseport
  • so_keepaliv on|off|[keepidle]:[keepintv1]:[keepcnt],”TCP keepalive” 开关

server_name

server_name,设置虚拟主机的名称。

形式如下:

默认值 server_name "";
server_name name ...;

例1,穷举域名

server {
    server_name example.com www.example.com;
}

例2,通配符写法

server {
    server_name example.com *.example.com www.example.*;
}

例3,这种写法满足例1

server {
    server_name .example.com;
}

例4,正则表达式,以 ~ 开头

server {
    server_name www.example.com ~^www\d+\.example\.com$;
}

例5,正则表达式捕获

server {
    server_name ~^(www\.)?(.+)$;

    location / {
        root /sites/$2;
    }
}

server {
    server_name _;

    location / {
        root /sites/default;
    }
}

例6,正则表达式变量

server {
    server_name ~^(www\.)?(?<domain>.+)$;

    location / {
        root /sites/$domain;
    }
}

server {
    server_name _;

    location / {
        root /sites/default;
    }
}

例7,与空名称使用

server {
    server_name www.example.com "";
}

如果当一个名称匹配多个 server 的是时候,匹配优先级如下:

  1. 确切的名称
  2. 以 * 开头的最长的通配符名称
  3. 以 * 结尾的最长通配符名称
  4. 第一个匹配的正则表达式

更多匹配规则请查阅:http://nginx.org/en/docs/http/server_names.html

location

location 是用来干嘛的,它是用来根据 URI 进行配置设置的,如:

server {
    listen 80;
    server_name example.com;

    location / { # 普通请求网页
        root /usr/share/nginx/html;
        index index.html index.htm;
    }

    location /api { # API请求代理
        proxy_pass http://dynamic;
        health_check;
    }
}

形式如下:

location [ = | ~ | ~* | ^~ ] uri { ... }
  • none,如果没有修饰符,则将该位置解释为前缀匹配。这意味着给定的位置将根据请求URI的开头进行匹配,以确定匹配
  • =,代表精确匹配,完全相等即匹配
  • ~,区分大小写的正则表达式匹配
  • ~*,不区分大小写的正则表达式匹配
  • ^~,普通字符匹配,如果该选项匹配,只匹配该选项

nginx 的匹配过程如下:

  1. 精确匹配 =,如果匹配成功,搜索停止
  2. 前缀匹配,最长位置匹配,如果该匹配具有 ^~,搜索停止
  3. 正则匹配,按配置文件中定义的顺序进行匹配。
  4. 如果第3条规则产生匹配的话,结果被使用。否则,使用第2条规则的结果。

让我们通过一个例子来了解下匹配规则:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

请求 / 将会匹配 A,请求 /index.html 将会匹配 B,请求 /documents/document.html 将会匹配 C,请求 /images/1.gif 将会匹配 D,请求 /documents/1.jpg 将会匹配 E。

ssl mode

ssl 模式可以让我们站点启用 HTTPS,具体详细请参考 http_ssl_module

想要开启 ssl 模式,需要在 listen 关键字处添加上 ssl,如:

server {
    listen              443 ssl;
    server_name         example.com;

    ssl_certificate     example.com.rsa.crt;
    ssl_certificate_key example.com.rsa.key;

    ssl_certificate     example.com.ecdsa.crt;
    ssl_certificate_key example.com.ecdsa.key;

    ...
}

上面的例子是部署双证书,当某一证书因某种原因失效不至于导致站点不能访问。下面来看看参数解释:

  • ssl_buffer_size size,default 16k,发送数据的缓冲区的大小
  • ssl_certificate file,PEM 格式证书文件
  • ssl_certificate_key file,PEM 格式私钥文件
  • ssl_ciphers ciphers,default HIGH:!aNULL:!MD5,ssl套件 openssl ciphers
  • ssl_client_certificate file,用于验证客户端证书的 CA 文件
  • ssl_crl file,用于验证客户端证书的吊销文件
  • ssl_dhparam file,为DHE密码指定具有DH参数的文件
  • ssl_early_data on|off,default on
  • ssl_ecdh_curve curve,default auto,为ECDHE密码指定一条曲线
  • ssl_password_file file,私钥密码文件
  • ssl_prefer_server_ciphers on|off,是否启用服务器套件偏好
  • ssl_protocols [SSLv2] [SSLv3] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3],default TLSv1 TLSv1.1 TLSv1.2,可选的ssl协议
  • ssl_session_cache off|none|[builtin[:size]] [shared:name:size],default none,设置 session cache 的类型和大小
ssl_session_cache builtin:1000 shared:SSL:10m;
  • ssl_session_ticket_key file,设置一个文件,其中包含用于加密和解密TLS会话票据的密钥
ssl_session_ticket_key current.key;
ssl_session_ticket_key previous.key;

随机一个 AES256(80),AES128(40)
openssl rand 80 > ticket.key
  • ssl_session_tickets on|off,default on,是否启用 session ticket
  • ssl_session_timeout time,default 5m,超时时间
  • ssl_stapling on|off,default off,ocsp 装订 ssl_stapling on; resolver 192.0.2.1;
  • ssl_stapling_file file
  • ssl_stapling_responder url
  • ssl_stapling_verify on|off,default off
  • ssl_trusted_certificate file,指定验证客户端证书的 CA 文件
  • ssl_verify_client on|off|optional|optional_no_ca,default off,是否验证客户端证书
  • ssl_verify_depth number,default 1,设置客户端证书链的验证深度
$ssl_cipher,已建立连接使用的 ciphers
$ssl_ciphers,客户端支持的 ciphers
$ssl_client_escaped_cert,urlencoded 客户端证书
$ssl_client_fingerprint,SHA1指纹
$ssl_client_i_dn,issuer DN
$ssl_client_i_dn_legacy,同上,1.11.6之后使用
$ssl_client_raw_cert,PEM格式客户端证书
$ssl_client_s_dn,subject DN
$ssl_client_s_dn_legacy,同上,1.11.6之后使用
$ssl_client_serial,客户端证书序列号
$ssl_client_v_end,客户端证书结束时间
$ssl_client_v_remain,剩余多少天
$ssl_client_v_start,证书开始时间
$ssl_client_verify,客户端证书是否验证成功,"SUCCESS" 或 "FAILED:reason" 或 "NONE"
$ssl_curves,客户端支持的曲线
$ssl_early_data
$ssl_protocol,连接使用的协议
$ssl_server_name,从 SNI 获取的 server name
$ssl_session_id,连接的 session id
$ssl_session_reused,session是否重用,"r" 重用,"." 没有

其它模块你需要根据文档及编译信息判断该模块是否默认编译在 nginx 中,并且版本是否匹配:

ngx_http_access_module
ngx_http_addition_module
ngx_http_api_module
ngx_http_auth_basic_module
ngx_http_auth_jwt_module
ngx_http_auth_request_module
ngx_http_autoindex_module
ngx_http_browser_module
ngx_http_charset_module
ngx_http_dav_module
ngx_http_empty_gif_module
ngx_http_f4f_module
ngx_http_fastcgi_module
ngx_http_flv_module
ngx_http_geo_module
ngx_http_geoip_module
ngx_http_grpc_module
ngx_http_gunzip_module
ngx_http_gzip_module
ngx_http_gzip_static_module
ngx_http_headers_module
ngx_http_hls_module
ngx_http_image_filter_module
ngx_http_index_module
ngx_http_js_module
ngx_http_keyval_module
ngx_http_limit_conn_module
ngx_http_limit_req_module
ngx_http_log_module
ngx_http_map_module
ngx_http_memcached_module
ngx_http_mirror_module
ngx_http_mp4_module
ngx_http_perl_module
ngx_http_proxy_module
ngx_http_random_index_module
ngx_http_realip_module
ngx_http_referer_module
ngx_http_rewrite_module
ngx_http_scgi_module
ngx_http_secure_link_module
ngx_http_session_log_module
ngx_http_slice_module
ngx_http_spdy_module
ngx_http_split_clients_module
ngx_http_ssi_module
ngx_http_ssl_module
ngx_http_status_module
ngx_http_stub_status_module
ngx_http_sub_module
ngx_http_upstream_module
ngx_http_upstream_conf_module
ngx_http_upstream_hc_module
ngx_http_userid_module
ngx_http_uwsgi_module
ngx_http_v2_module
ngx_http_xslt_module

nginx完整配置

一份给新人的 nginx 完整配置:https://github.com/deepzz0/nginx

[1] http://nginx.org/en/docs/

本文链接:https://deepzz.com/post/how-to-write-nginx-server.html参与评论 »

--EOF--

发表于 2019-08-18 02:30:00。

本站使用「署名 4.0 国际」创作共享协议,转载请注明作者及原网址。更多说明 »

提醒:本文最后更新于 489 天前,文中所描述的信息可能已发生改变,请谨慎使用。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK