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

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

内容简介: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讲笔记(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

可爱的Python

可爱的Python

哲思社区 / 电子工业出版社 / 2009-9 / 55.00元

本书的内容主要来自CPyUG社区的邮件列表,由Python的行者根据自身经验组织而成,是为从来没有听说过Python的其他语言程序员准备的一份实用的导学性质的书。笔者试图将优化后的学习体验,通过故事的方式传达给读者,同时也分享了蟒样(Pythonic式)的知识获取技巧,而且希望将最常用的代码和思路,通过作弊条(Cheat Sheet,提示表单)的形式分享给有初步基础的Python 用户,来帮助大家......一起来看看 《可爱的Python》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试