nginx 核心知识100讲笔记(一)

栏目: 服务器 · Nginx · 发布时间: 7年前

内容简介:32核64G, 数千万并发链接nginx-1.14.0 14 双数版本, 为稳定版, 奇数为不稳定版替换 nginx 的二进制执行文件

nginx 核心知识100讲笔记

主要应用场景

  1. 静态资源服务
    • 本地文件系统
  2. 反向代理服务
    • 缓存
    • 负载均衡
  3. API 服务
    • OpenRestry

32核64G, 数千万并发链接

nginx 组成

  1. 二进制可执行文件
  2. 配置文件 nginx.conf
  3. access.log , 记录每一条 http 请求信息
  4. error.log , 定位问题

nginx-1.14.0 14 双数版本, 为稳定版, 奇数为不稳定版

nginx 编译

nginx-1.14.1
├── CHANGES
├── CHANGES.ru
├── LICENSE
├── README
├── auto  # 提供编译的包, 识别操作系统
├── conf  # 实例文件
├── configure  # 编译脚本
├── contrib  #  提供 vim 语法. cp -r contrib/vim/* ~/.vim/
├── html  # 50x.html, index.html
├── man  # nginx 帮助文件
└── src  # 源代码
./configure --help
  1. 文件目录. 主要使用 --prefix
  2. 参数, with 表示默认不包括, 需要手动添加. without 表示默认包括, 需要手动排除
  3. 特殊参数
./configure  # 会生成中间文件, 路径 objs/, 里面有个 ngx_modules.c, 内容是编辑中包含的模块
make  # 生成中间文件, 和运行的二进制文件, 路径 objs/ . !!!做版本升级的时候, 把二进制文件拷贝到目录, 不需要执行 make install !!!
make install  # 首次安装时使用的命令

nginx 配置语法

  1. 配置文件由指令与指令快构成, http {} 指令快
  2. 每条指令以 ; 结尾, 指令与参数之间以空格分割
  3. 指令快以 {} 将多个指令组织在一起
  4. include 语句允许组合多个配置文件以提升可维护性
  5. # 注释
  6. $ 使用变量
  7. 支持正则

时间单位

  • ms 毫秒
  • s 秒
  • m 分
  • h 小时
  • d 天
  • w 周
  • M 月
  • y 年

空间单位

  • 不加表示 bytes 字节
  • k/K 千字节
  • m/M 兆
  • g/G

http 指令快

  • http
  • server
  • location
  • upstream

nginx 命令行

  • nginx -s reload
  • -? -h
  • -c 配置文件
  • -g 配置指令
  • -p 运行目录
  • -s 发送信号 stop/quit(优雅停止)/reload/reopen(重新开始记录日志文件)
  • -t -T
  • -v -V

热部署, 版本升级

替换 nginx 的二进制执行文件

kill -USR2 12345 # 12345 是 nginx 运行的主进程号

这时会有两个 nginx 进程, 一个老的, 一个新的

kill -WINCH 12345 # 优雅的关闭老的所有进程

这时还是有两个 nginx 进程

旧的会保留在那里, 用作版本回退, 把老的 nginx 恢复回去, 然后 kill -USR1 12345 来重新启用.

如果没问题, 用 kill -QUIT 把老进程号杀掉

lsof -p 进程号 # 可以看到进程打开的句柄, 也包括监听的端口

日志切割

mv  access.log  access.log.bak
nginx -s reopen

简单服务器

# 命名为 main
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" ';
                            '"$http_user_agent" "$http_x_forwarded_for"'
gzip on;
gzip_min_length 1; # 小于1字节就不再压缩了
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css applicatioin/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 要压缩的文件类型

server {
    listen 8080;
    location / {
        alias dlib/; # 相对路径
        autoindex on; # 显示目录
        set $limit_rate 1k; # 限制速度, 每秒传输
    }
    access_log logs/access.log main;
}

具有缓存的反向代理

# 设置缓存目录, 10M 共享内存
proxy_cache_path /tmp/nginxcache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m user_temp_path=off;
server {
    listen 127.0.0.1:8080;
}
upstream local {
    server 127.0.0.1:8080;
}
server {
    server_name abc.com;
    listen 80;
    location / {
        proxy_set_header Host $host; # 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_cache my_cache;
        proxy_cache_key $host$uri$is_args$args; # 设定 key
        proxy_cache_valid 200 304 302 1d;
        proxy_pass http://local;
    }
}

goaccess

官网

goaccess access.log -o report.html --log-format=COMBINED

Let's Encrypt

官网

详细参考官方文档

yum install python2-certbot-nginx
certbot --nginx --nginx-server-root=/usr/loca/nginx/conf -d www.abc.com
# 该命令自动增加了
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/www.abc.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.abc.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;  #  表示非对称加密使用的参数

cat /etc/letsencrypt/options-ssl-nginx.conf
ssl_session_cache shared:le_nginx_SSL:1m;  #  ssl 最消耗是握手, 增加 cache 1m, 大约是4000个连接
ssl_session_timeout 1440m;  #  每个握手第一次连接, 如果断开了, 在1440分(一天)时间内是可以复用的

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers "这里一堆安全套件名称";

OpenResty

官网

下载最新版

openresty-1.13.6.2
├── COPYRIGHT
├── README-windows.txt
├── README.markdown
├── bundle  # 模块
├── configure
├── patches
└── util

编译

./configure
make && make install

简单示例, 把用户代理显示到浏览器中

location /lua {
    default_type text/html;
    content_by_lua 'ngx.say("User-Agent: ", ngx.req.get_headers()["User-Agent"])';
}

nginx 进程结构

多进程结构

nginx -s reload # 关掉 work 和 cache 进程, 重新启用, 不用进程号,  父进程号一样
kill -SIGHUP 9170 # 父进程号,  同 reload

kill -SIGTERM 16982 # 子进程号, 杀掉子进程, 父进程会自动重新启用一个子进程

nginx 信号

master 进程

监控 worker 进程

  • CHLD # 子进程终止的时候, 会向父进程发送这个信号

管理 worker 进程

接受信号

  • TERM, INT # 立刻停止进程
  • QUIT # 优雅停止
  • HUP # 重载配置文件
  • USR1 # 重新打开日志文件, 做日志文件切割
  • # 上面4个可以通过 nginx 命令行运行, 下面两个只能通过 kill 直接向父进程发送信号
  • USR2 # 这两个热部署
  • WINCH

worker 进程

接受信号, 通常不对 work 进程发送信号

  • TERM, INT
  • QUIT-
  • USR1
  • WINCH

nginx 命令行

  • reload : HUP
  • reopen : USR1
  • stop : TERM
  • quit : QUIT

热升级流程

编译选项, 路径必须一致

  1. 将旧 nginx 文件换成新 nginx 文件(注意备份)
  2. 向 master 进程发送 USR2 信号
  3. master 进程修改 pid 文件名, 加后缀 .oldbin
  4. master 进程用新 nginx 文件启动新 master 进程
  5. 向老 master 进程发送 WINCH 信号, 关闭老 worker
  6. 回滚: 向老 master发送 HUP, 向新 master 发送 quit

共享内存工具 , ngx_slab_stat 模块

官网

下载一个 tengine , 在里面找这个模块

./configure --add-module=../tengine-2.2.2/modules/ngx_slab_stat/

location = /slab_stat {
    slab_stat;
}

#######################

connection_pool_size 512; # 连接内存池, 512 字节
request_pool_size 4k; # 请求内存池, 通常是 connection_pool_size 8倍

nginx 请求

  • 精准匹配
  • 处理 *.liuhonghe.me
  • * 在后的泛域名
  • 按文件的顺序匹配正则表达式域名
  • default . listen 后面指定的 default
server {
    server_name first.liuhonghe.me second.liuhonghe.me;
    server_name_in_redirect on; # 默认是 off,  表示, 当访问 second.liuhonghe.me/redirect, 会转到 first.liuhonghe.me/redirect

    return 302 /redirect;
}
server {
    server_name .liuhonghe.me; # 匹配 liuhonghe.me  *.liuhonghe.me
    server_name _; # 匹配所有
    server_name ""; # 匹配没有传递 Host 头部的请求
}

nginx 处理的 11 个阶段

  1. post read. realip
  2. server_rewrite. rewrite
  3. find_config
  4. rewrite. rewrite
  5. post_rewrite
  6. preaccess. limit_conn, limit_req
  7. access. auth_basic, access, auth_request
  8. post_access
  9. precontent. try_files
  10. content. index, autoindex. concat
  11. log. access_log

realip 模块, 用户真实 ip

修改客户端地址, --with-http_realip_module , 提供 realip_remote_addrreal_remote_port 两个变量, 指令 set_real_ip_from real_ip_header real_ip_recursive

  • X-Forwarded-For 可以多个 IP
  • X-Real-IP 一个 IP

使用: 拿到真实 ip 后, 基于变量使用, 如 binary_remote_addr remote_addr 这样的的变量

───────┬────────────────────
       │ File: realip.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name realip.liuhonghe.me;
   3   │
   4   │         error_log logs/myerror.log debug;
   5   │         set_real_ip_from  192.168.1.107;  #  如果是这个 IP 连过来的, 进行以下操作
   6   │         #real_ip_header X-Real-IP;
   7   │         #real_ip_recursive off;
   8   │         real_ip_recursive on;
   9   │         real_ip_header    X-Forwarded-For;
  10   │
  11   │         location /{
  12   │                 return 200 "Client real ip: $remote_addr\n";
  13   │         }
  14   │ }
───────┴────────────────────

rewrite 模块

  • 444 关闭连接
  • 301 http1.0 永久重定向
  • 302 http1.0 临时重定向, 禁止被缓存
  • 303 http1.1 临时重定向, 允许改变方法, 禁止被缓存
  • 307 http1.1 临时重定向, 不允许改变方法, 禁止被缓存
  • 308 http1.1 永久重定向, 不允许改变方法

语法: rewrite regex replacement [flag];

  • regex 指定的 url 替换成 replacement 这个新的 url, 可以使用正则表达式及变量提取
  • replacementhttp:// 或者 https:// 或者 $schema 开头, 则返回 302 重定向
  • 替换后的 url 根据 flag 指定的方式进行处理
    replacement
    
───────┬────────────────────
       │ File: rewrite.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name rewrite.liuhonghe.me;
   3   │         rewrite_log on;
   4   │         error_log logs/rewrite_error.log notice;
   5   │
   6   │         root html/;
   7   │         location /first {
   8   │                 rewrite /first(.*) /second$1 last; # 这条会到 /second 中处理
   9   │                 return 200 'first!\n';
  10   │         }
  11   │
  12   │         location /second {
  13   │                 rewrite /second(.*) /third$1 break;
  14   │                 #rewrite /second(.*) /third$1;
  15   │                 return 200 'second!\n';
  16   │         }
  17   │
  18   │         location /third {
  19   │                 return 200 'third!\n';
  20   │         }
  21   │
  22   │
  23   │         location /redirect1 {
  24   │                 rewrite /redirect1(.*) $1 permanent;
  25   │         }
  26   │
  27   │         location /redirect2 {
  28   │                 rewrite /redirect2(.*) $1 redirect;
  29   │         }
  30   │
  31   │         location /redirect3 {
  32   │                 rewrite /redirect3(.*) http://rewrite.taohui.tech$1;
  33   │         }
  34   │
  35   │         location /redirect4 {
  36   │                 rewrite /redirect4(.*) http://rewrite.taohui.tech$1 permanent;
  37   │         }
  38   │
  39   │ }
───────┴────────────────────

rewrite if 指令

条件表达式

  • 检查变量为 或者值是否为 0 , 直接使用
  • 将变量与字符串做匹配, 使用 = 或者 !=
  • 将变量与正则表达式做匹配
    • 大小写敏感, ~ 或者 !~
    • 大小写不敏感, ~* 或者 !~*
  • 检查文件是否存在, 使用 -f!-f
  • 检查目录是否存在, 使用 -d!-d
  • 检查文件/目录/软连接是否存在, 使用 -e!-e
  • 检查是否为可执行文件, 使用 -x!-x

error_page

  1. error_page 404 /404.html;
  2. error_page 500 502 503 505 /50x.html
  3. error_page 404 =200 /empty.gif;
  4. error_page 404 = /404.php;
  5. location / { error_page 404 = @fallback; } location @fallback {proxy_pass http://backend;}
  6. error_page 403 http://example.com/forbidden.html;
  7. error_page 404 =301 http://example.com/notfound.htm;
───────┬────────────────────
       │ File: return.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name return.liuhonghe.me;
   3   │         listen 8080;
   4   │
   5   │         root html/;
   6   │         error_page 404 /403.html;
   7   │         return 405; # 最先执行
   8   │         location /{
   9   │                 return 404 "find nothing!\n"; # 后 return 执行, 不会执行上面的404
  10   │         }
  11   │ }
───────┴────────────────────

location 匹配规则

仅匹配 URI, 忽略参数

  • 常规
  • = 精准匹配
  • ^~ 匹配上后, 则不再进行正则表达式的匹配
  • merge_slashed on; 合并连续的斜杠 / 符号
  • @ 用于内部跳转的命名 location
  • ~ 大小写敏感的正则匹配
  • ~* 忽略大小写的正则匹配

匹配规则

= > ^~ > 顺序依次匹配正则表达式 location(如果没有, 就匹配最长的) > 最长匹配的 location

下面有 6个规则

/Test1
/Test1/
/Test1/Test2
/Test1/Test2/
/test1/Test2
───────┬────────────────────
       │ File: locations.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name location.liuhonghe.me;
   3   │         error_log  logs/error.log  debug;
   4   │         #root html/;
   5   │         default_type text/plain;
   6   │         merge_slashes off;
   7   │
   8   │         location ~ /Test1/$ { # 第一条
   9   │                 return 200 'first regular expressions match!\n';
  10   │         }
  11   │
  12   │         location ~* /Test1/(\w+)$ { # 第二条
  13   │                 return 200 'longest regular expressions match!\n';
  14   │         }
  15   │
  16   │         location ^~ /Test1/ { # 第三条
  17   │                 return 200 'stop regular expressions match!\n';
  18   │         }
  19   │
  20   │         location /Test1/Test2 { # 第四条
  21   │                 return 200 'longest prefix string match!\n';
  22   │         }
  23   │
  24   │         location /Test1 { # 第五条
  25   │                 return 200 'prefix string match!\n';
  26   │         }
  27   │
  28   │
  29   │         location = /Test1 { # 第六条
  30   │                 return 200 'exact match!\n';
  31   │         }
  32   │
  33   │ }
───────┴─────────────────────────

限制每个客户端并发连接数 && 限制每个客户端每秒请求数

───────┬────────────────────
       │ File: limit_conn.conf
───────┼────────────────────
   1   │ limit_conn_zone $binary_remote_addr zone=addr:10m; # 定义一个10m的共享内存, 用二进制IP 地址
   2   │ limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m; # 定义10m 共享内存和速率
   3   │
   4   │ server {
   5   │         server_name limit.liuhonghe.me;
   6   │         root html/;
   7   │         error_log logs/myerror.log info;
   8   │
   9   │         location /{
  10   │                 limit_conn_status 500; # 定义返回的 code
  11   │                 limit_conn_log_level  warn;
  12   │                 limit_rate 50; # 限制向用户返回的速度, 每秒钟 50个字节
  13   │                 limit_conn addr 1; # 限制并发连接数
  14   │                 #limit_req zone=one burst=3 nodelay;
  15   │                 limit_req zone=one;
  16   │         }
  17   │ }
───────┴─────────────────────

access 对 ip 地址做限制

location / {
    deny 192.168.1.100; # 顺序匹配执行
    allow 192.168.1.0/24;
    deny all;
}

用户名密码访问 auth_basic

生成账号密码文件

install httpd-tools htpasswd -c file -b user pass

───────┬────────────────────
       │ File: access.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name access.liuhonghe.me;
   3   │         error_log  logs/error.log  debug;
   4   │         #root html/;
   5   │         default_type text/plain;
   6   │         location /auth_basic {
   7   │                 satisfy any;
   8   │                 auth_basic "test auth_basic"; # 提示串
   9   │                 auth_basic_user_file examples/auth.pass; # 用户名密码文件
  10   │                 deny all;
  11   │         }
  12   │
  13   │         location / {
  14   │                 auth_request /test_auth;  # 生成一个子请求, 访问 /test_auth, 权限由这个自路由同一配置
  15   │         }
  16   │
  17   │         location = /test_auth {
  18   │                 proxy_pass http://127.0.0.1:8090/auth_upstream; # 反向代理
  19   │                 proxy_pass_request_body off;
  20   │                 proxy_set_header Content-Length "";
  21   │                 proxy_set_header X-Original-URI $request_uri;
  22   │         }
  23   │ }
───────┴────────────────────

auth_request

--with-http_auth_request_module 例子在上

satisfy

all | any

  • all 都满足条件
  • any 满足一个

try_files

───────┬────────────────────
       │ File: tryfiles.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name tryfiles.liuhonghe.me;
   3   │         error_log  logs/myerror.log  info;
   4   │         root html/;
   5   │         default_type text/plain;
   6   │
   7   │         location /first {
   8   │                 try_files /system/maintenance.html
   9   │                         $uri $uri/index.html $uri.html
  10   │                         @lasturl; # 依次找这几个文件, 如果没有, 范文 lasturl
  11   │         }
  12   │
  13   │         location @lasturl {
  14   │                 return 200 'lasturl!\n';
  15   │         }
  16   │
  17   │         location /second {
  18   │                 try_files $uri $uri/index.html $uri.html =404; # 都找不到时返回 404
  19   │         }
  20   │
  21   │ }
───────┴────────────────────

mirror 模块

处理请求时, 生成子请求访问其他服务, 对子请求的返回值不做处理

server {
    listen 800;
    error_log logs/error.log debug;

    location / {
        mirror /mirror; # copy 一份流量到 /mirror
        mirror_request_body off; # 测试, 不复制 body
    }

    location = /mirror {
        internal; # 只能内部请求
        proxy_pass http://127.0.0.1:10020$request_uri;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URL $request_uri;
    }
}
───────┬────────────────────
       │ File: mirror.conf
───────┼────────────────────
   1   │ server {
   2   │         listen 10020;
   3   │         location / {
   4   │                 return 200 'mirror response!';
   5   │         }
   6   │ }
───────┴────────────────────

alias & root

  • request_filename 访问文件的完整路径
  • document_root 由URI 和 root/alias 规则生成的文件夹路径
  • realpath_root 将 document_root 中的软连接等换成真实路径
───────┬────────────────────
       │ File: static.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name static.liuhonghe.me;
   3   │         error_log  logs/myerror.log  info;
   4   │
   5   │         location /root { # /html/root
   6   │                 root html;
   7   │         }
   8   │
   9   │         location /alias {
  10   │                 alias html;
  11   │         }
  12   │
  13   │         location ~ /root/(\w+\.txt) {
  14   │                 root html/first/$1;
  15   │         }
  16   │
  17   │         location ~ /alias/(\w+\.txt) {
  18   │                 alias html/first/$1;
  19   │         }
  20   │
  21   │         location  /RealPath/ {
  22   │                 alias html/realpath/;
  23   │                 return 200 '$request_filename:$document_root:$realpath_root\n';
  24   │         }
  25   │
  26   │ }
───────┴─────────────────────

static 模块对 url 不以斜杠结尾却访问目录的做法

nginx 访问一个 url, url 末尾没有加 /, 会返回 301

  • absolute_redirect on;
  • server_name_in_redirect off;
  • port_in_redirect on;
───────┬────────────────────
       │ File: dirredirect.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name return.liuhonghe.me dir.liuhonghe.me;
   3   │         server_name_in_redirect on;
   4   │         listen 8088;
   5   │         port_in_redirect on;
   6   │         #absolute_redirect off;
   7   │
   8   │         root html/;
   9   │ }
───────┴─────────────────────

index 和 autoindex

───────┬────────────────────
       │ File: autoindex.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name autoindex.liuhonghe.me;
   3   │         listen 8080;
   4   │         location / {
   5   │                 alias html/;
   6   │                 autoindex on;
   7   │                 index a.html;
   8   │                 autoindex_exact_size off; 
   9   │                 autoindex_format html; # 格式
  10   │                 autoindex_localtime on;
  11   │         }
  12   │ }
───────┴────────────────────

提升多个小文件性能的 concat

在一次请求, 访问多个小文件

alibaba https://github.com/alibaba/nginx-http-concat

--add-module=../nginx-http-concat/

使用, 在 URI 后加两个问好 ?? https://liuhonghe.me/??file01.js,js/file02.js,css/style.css

  • concat: on | off; 开关
  • concat_delimiter: string 分隔符
  • concat_types: MIME types 类型
  • concat_unique: on | off; 是否只对某一种类型进行合并
  • concat_ignore_file_error on | off; 发现某些文件不存在, 继续返回其他文件
  • concat_max_files: numberp 最多合并多少个文件
───────┬────────────────────
       │ File: concat.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name concat.liuhonghe.me;
   3   │
   4   │         error_log logs/myerror.log debug;
   5   │         concat on;
   6   │         root html;
   7   │
   8   │         location /concat {
   9   │                 concat_max_files 20;
  10   │                 concat_types text/plain;
  11   │                 concat_unique on;
  12   │                 concat_delimiter ':::';
  13   │                 concat_ignore_file_error on;
  14   │         }
  15   │
  16   │ }
───────┴────────────────────

access 日志模块 log

默认 combined 格式

log_format combined '$remote_addr - $remote_user [$time_local]' '"$request" $status $body_bytes_sent' '"$http_referer" "$http_user_agent"';

语法

  • access_log off;
  • access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

过滤模块

--with-http_sub_filter_module

  • sub_filter string replacement
  • sub_filter_last_modified off | on;
  • sub_filter_once on | off;
  • sub_filter_types mime-type;
───────┬────────────────────
       │ File: sub.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name sub.liuhonghe.me;
   3   │         error_log  logs/myerror.log  info;
   4   │
   5   │         location / {
   6   │                 sub_filter 'Nginx.oRg'  '$host/nginx';  # 忽略大小写的, 替换 html 字符串内容
   7   │                 sub_filter 'nginX.cOm' '$host/nginx';
   8   │                 #sub_filter_once on; # 只替换一个
   9   │                 sub_filter_once off;
  10   │                 #sub_filter_last_modified off;
  11   │                 sub_filter_last_modified on; # 头部的 last_modified
  12   │         }
  13   │ }
───────┴────────────────────

addition

可以在响应前后添加

--with-http_addition_module

  • add_before body
  • add_after_body
  • addition_types mime-type
───────┬────────────────────
       │ File: addition.conf
───────┼────────────────────
   1   │ server {
   2   │         server_name addition.liuhonghe.me;
   3   │         error_log logs/myerror.log info;
   4   │
   5   │         location / {
   6   │                 add_before_body /before_action;
   7   │                 add_after_body  /after_action;
   8   │                 addition_types *;
   9   │         }
  10   │         location /before_action {
  11   │                 return 200 'new content before\n';
  12   │         }
  13   │         location /after_action {
  14   │                 return 200 'new content after\n';
  15   │         }
  16   │
  17   │         location /testhost {
  18   │                 uninitialized_variable_warn on;
  19   │                 set $foo 'testhost';
  20   │                 return 200 '$gzip_ratio\n';
  21   │         }
  22   │
  23   │ }
───────┴─────────────────────

以上所述就是小编给大家介绍的《nginx 核心知识100讲笔记(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Seasoned Schemer

The Seasoned Schemer

Daniel P. Friedman、Matthias Felleisen / The MIT Press / 1995-12-21 / USD 38.00

drawings by Duane Bibbyforeword and afterword by Guy L. Steele Jr.The notion that "thinking about computing is one of the most exciting things the human mind can do" sets both The Little Schemer (form......一起来看看 《The Seasoned Schemer》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具