• 正文
  • 相关推荐
申请入驻 产业图谱

Nginx | 核心知识150讲,百万并发下性能优化之其它HTTP框架下反向代理场景

01/07 10:33
160
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

大家好,我是 WeiyiGeek,一名深耕安全运维开发(SecOpsDev)领域的技术从业者,致力于探索DevOps与安全的融合(DevSecOps),自动化运维工具开发与实践,企业网络安全防护,欢迎各位道友一起学习交流、一起进步 ,若此文对你有帮助,一定记得点个关注⭐与小红星❤️或加入到作者知识星球『 全栈工程师修炼指南』,转发收藏学习不迷路  。

前言简述

描述:上一章《Nginx | 核心知识150讲,百万并发下性能优化之前端静态缓存、后端动态缓存实践笔记》,作者介绍了 Nginx 在 HTTP 反向代理中缓存相关的指令,并实践了通过缓存机制优化了网站的访问速度,以及在上游服务器异常时,通过缓存机制,避免了上游服务器网络波动所带来的影响。

本章节将继续介绍 Nginx 在其它反向代理场景(例如:uwsgi、fastcgi、scgi、memcached)下的指令,分别实践在 Memcached 反向代理场景下,如何通过 nginx 转发请求到 Memcached 服务上,和在 Websocket 反向代理场景下,如何通过 nginx 实现 Websocket 协议的转发,最后在 gRPC 反向代理场景下,如何通过 nginx 实现 gRPC 协议的转发。

好了,废话不多说,让我们开始今天的旅程吧。

温馨提示:若文章代码块中存在乱码或不能复制,请联系作者,也可通过文末的阅读原文链接,加入知识星球中阅读,原文链接:https://articles.zsxq.com/id_7wc0af7viwqr.html


0x01 反向代理指令功能对照表

本小节将主要提供 http 反向代理与uwsgi、fastcgi、scgi 反向代理的相关指令功能对照表,方便运维开发人员对 nginx 不同场景下反向代理指令的快速查阅,有助于提提运维开发人员的工作效率。

下述,作者将按照指令功能进行分类、归纳,并以表格的形式呈现 nginx 反向代理指令的功能对照表。

1.构造请求内容

功能类别 http uwsgi fastcgi scgi
指定上游服务 proxy_pass uwsgi_pass fastcgi_pass scgi_pass
是否传递请求头部 proxy_pass_request_headers uwsgi_pass_request_headers fastcgi_pass_request_headers scgi_pass_request_headers
是否传递请求包体 proxy_pass_request_body uwsgi_pass_request_body fastcgi_pass_request_body scgi_pass_request_body
指定请求方法 proxy_method - - -
指定请求协议 proxy_http_version - - -
增改请求头部 proxy_set_header - - -
更高请求包体 proxy_set_body - - -
是否缓存请求包体 proxy_request_buffering uwsgi_request_buffering fastcgi_request_buffering scgi_request_buffering

2.建立连接与请求发送

功能类别 http uwsgi fastcgi scgi
连接绑定地址 proxy_bind uwsgi_bind fastcgi_bind scgi_bind
连接超时时间 proxy_connect_timeout uwsgi_connect_timeout fastcgi_connect_timeout scgi_connect_timeout
是否使用TCP会话保持 proxy_socket_keepalive uwsgi_socket_keepalive fastcgi_socket_keepalive scgi_socket_keepalive
忽略客户端中断连接 proxy_ignore_client_abort uwsgi_ignore_client_abort fastcgi_ignore_client_abort scgi_ignore_client_abort
设置HTTP头部哈希表桶大小 proxy_headers_hash_bucket_size - - -
设置HTTP头部哈希表最大大小 proxy_headers_hash_max_size - - -
发送请求超时时间 proxy_send_timeout uwsgi_send_timeout fastcgi_send_timeout scgi_send_timeout

3.接收处理上游响应

功能类别 http uwsgi fastcgi scgi
是否缓存上游响应包体 proxy_buffering uwsgi_buffering fastcgi_buffering scgi_buffering
存放上游响应的临时目录 proxy_temp_path uwsgi_temp_path fastcgi_temp_path scgi_temp_path
临时文件写缓存大小 proxy_temp_file_write_size uwsgi_temp_file_write_size fastcgi_temp_file_write_size scgi_temp_file_write_size
临时文件最大大小 proxy_max_temp_file_size uwsgi_max_temp_file_size fastcgi_max_temp_file_size scgi_max_temp_file_size
接收响应头部缓存大小 proxy_buffer_size uwsgi_buffer_size fastcgi_buffer_size scgi_buffer_size
接收响应包体缓存大小 proxy_buffers uwsgi_buffers fastcgi_buffers scgi_buffers
缓存完成前转发包体 proxy_busy_buffers_size uwsgi_busy_buffers_size fastcgi_busy_buffers_size scgi_busy_buffers_size
是否持久化包体文件 proxy_store uwsgi_store fastcgi_store scgi_store
设置持久化包体文件权限 proxy_store_access uwsgi_store_access fastcgi_store_access scgi_store_access
读取响应超时时间 proxy_read_timeout uwsgi_read_timeout fastcgi_read_timeout scgi_read_timeout
读取响应速率限制 proxy_limit_rate uwsgi_limit_rate fastcgi_limit_rate scgi_limit_rate

4.转发处理上游响应

功能类别 http uwsgi fastcgi scgi
是否隐藏上游响应头部 proxy_hide_header uwsig_hide_header fastcgi_hide_header scgi_hide_header
是否忽略指定上游响应头部 proxy_ignore_headers uwsig_ignore_headers fastcgi_ignore_headers scgi_ignore_headers
替换Set-Cookie头部域名 proxy_cookie_domain - - -
替换Set-Cookie头部路径 proxy_cookie_path - - -
指定重定向响应头部 proxy_redirect - - -
传递指定上游响应头部 proxy_pass_header uwsig_pass_header fastcgi_pass_header scgi_pass_header
上游错误时自动切换上游 proxy_next_upstream uwsgi_next_upstream fastcgi_next_upstream scgi_next_upstream
自动切换上游超时时间 proxy_next_upstream_timeout uwsgi_next_upstream_timeout fastcgi_next_upstream_timeout scgi_next_upstream_timeout
自动切换上游尝试次数 proxy_next_upstream_tries uwsgi_next_upstream_tries fastcgi_next_upstream_tries scgi_next_upstream_tries
拦截上游错误响应 proxy_intercept_errors uwsgi_intercept_errors fastcgi_intercept_errors scgi_intercept_errors

5.处理缓存类指令

功能类别 http uwsgi fastcgi scgi
是否启用缓存 proxy_cache uwsgi_cache fastcgi_cache scgi_cache
缓存存储路径 proxy_cache_path uwsgi_cache_path fastcgi_cache_path scgi_cache_path
那些请求不使用缓存 proxy_cache_bypass uwsgi_cache_bypass fastcgi_cache_bypass scgi_cache_bypass
开启子请求更新陈旧缓存 proxy_cache_background_update uwsgi_cache_background_update fastcgi_cache_background_update scgi_cache_background_update
缓存关键字自定义 proxy_cache_key uwsgi_cache_key fastcgi_cache_key scgi_cache_key
使用 range 协议偏移 proxy_cache_max_range_offset uwsgi_cache_max_range_offset fastcgi_cache_max_range_offset scgi_cache_max_range_offset
指定缓存的请求方法 proxy_cache_methods uwsgi_cache_methods fastcgi_cache_methods scgi_cache_methods
指定请求多少次后请求 proxy_cache_min_uses uwsgi_cache_min_uses fastcgi_cache_min_uses scgi_cache_min_uses
缓存那些响应及时长 proxy_cache_valid uwsgi_cache_valid fastcgi_cache_valid scgi_cache_valid
强制使用 range 协议 proxy_force_ranges uwsgi_force_ranges fastcgi_force_ranges scgi_force_ranges
启用缓存期内返回304响应 proxy_cache_revalidate uwsgi_cache_revalidate fastcgi_cache_revalidate scgi_cache_revalidate
返回陈旧缓存内容 proxy_cache_use_stale uwsgi_cache_use_stale fastcgi_cache_use_stale scgi_cache_use_stale
指定那些响应不写缓存 proxy_no_cache uwsgi_no_cache fastcgi_no_cache scgi_no_cache
将HEAD请求转为GET proxy_cache_convert_head - - -
缓存失效时合并回源请求 proxy_cache_lock uwsgi_cache_lock fasctgi_cache_lock scgi_cache_lock
控制单个请求生成缓存的时间 proxy_cache_lock_age uwsgi_cache_lock_age fastcgi_cache_lock_age scgi_cache_lock_age
控制全部请求生成缓存超时时间 proxy_cache_lock_timeout uwsgi_cache_lock_timeout fastcgi_cache_lock_timeout scgi_cache_lock_timeout

5.反向代理 SSL 证书相关指令

功能类别 http uwsgi fastcgi scgi
指定用于上游通讯的证书 proxy_ssl_certificate uwsgi_ssl_certificate - -
指定用于上游通讯的私钥 proxy_ssl_certificate_key uwsgi_ssl_certificate_key - -
指定于上游通讯的私钥密码文件 proxy_ssl_password_file uwsgi_ssl_password_file - -
指定SSL协议版本 proxy_ssl_protocols uwsgi_ssl_protocols - -
指定安全加密套件 proxy_ssl_ciphers uwsgi_ssl_ciphers - -
指定吊销证书链文件验证上游证书 proxy_ssl_crl uwsgi_ssl_crl - -
指定域名验证上游证书域名 proxy_ssl_name uwsgi_ssl_name - -
指定传递SNI信息到上游 proxy_ssl_server_name uwsgi_ssl_server_name - -
指定是否重用 SSL 连接 proxy_ssl_session_reuse uwsgi_ssl_session_reuse - -
指定用于验证上游证书的CA文件 proxy_ssl_trusted_certificate uwsgi_ssl_trusted_certificate - -
指定验证上游服务的证书 proxy_ssl_verify uwsgi_ssl_verify - -
指定验证证书链的深度 proxy_ssl_verify_depth uwsgi_ssl_verify_depth - -

6.独有配置指令

功能类别 http uwsgi fastcgi scgi
设置数据包头中modifier1字段的值 - uwsgi_modifier1 - -
设置数据包头中modifier2字段的值 - uwsgi_modifier2 - -
设置应传递给上游服务器的参数 - uwsgi_param fastcgi_param scgi_param
设置首页索引路径 - - fastcgi_index -
捕捉后端相应错误流 - - fastcgi_catch_stderr -

Nginx 反向代理 Memcached 指令浅析与实践

上一章,我们对照 http 七层反向代理指令,介绍了其它三个功能完善的反向代理模块的指令,相信大家通过前面 http 反向代理相关的指令学习,举一反三后也可轻松掌握其它三个模块的指令。这一小节,作者将介绍一个功能相对简单的应用层反向代理模块,即 memcached 反向代理。

由 ngx_http_memcached_module 模块提供了 memcached 应用层反向代理,该模块默认已经编译在 Nginx 中,目前仅支持 memcached 协议格式中的GET请求。其转换流程为将客户端传来的HTTP GET请求根据参数转换为 memcached 协议命令,获取对应key的值并返回给用户。

协议格式

# get 命令格式, 可跟多个K, 以 rn 结尾
get <K>

# set 命令格式:温馨提示由于 set 命令反向代理不支持,这里介绍其主要是为了在 memcached 命令行中演示使用,同样是以 rn 结尾
set <key> <flags> <exptime> <bytes>

- key: 存储的键值。
- flags: 标志位,通常设置为0,表示key所属标签或类别。
- exptime: 过期时间,单位为秒,其中 0 表示永久不过期。
- bytes: 存储数据的字节数。

工作原理

    1.使用变量 $memcached_key 捕获客户端请求中相关值,作为关键字2.然后将构造后的命令发送至上游 Memcached 服务中3.接受上游 Memcached 服务返回的数据,并将其作为 HTTP 响应体传递给客户端

指令参数

memcached_pass:指定上游 Memcached 服务器地址,可以是 IP:PORT 或者 socket 路径。

Syntax: memcached_pass address;
Default: —
Context: location, if in location

memcached_bind:绑定本地连接地址。

Syntax: memcached_bind address [transparent ] | off;
Default:—
Context:  http, server, location

# 参数说明:
transparent: 启用透明代理模式,即客户端IP地址将被传递给上游服务器。

memcached_buffer_size:设置用于读取从memcached服务器接收响应缓冲区大小,与 proxy_buffer_size 指令类似一致。

Syntax: memcached_buffer_size size;
Default: memcached_buffer_size 4k|8k;
Context: http, server, location

memcached_connect_timeout:设置连接上游 Memcached 服务器超时时间。

Syntax: memcached_connect_timeout time;
Default: 
memcached_connect_timeout 60s;
Context: http, server, location

memcached_socket_keepalive:设置是否开启与上游 Memcached 服务器间开启 TCP keepalive 模式。

Syntax: memcached_socket_keepalive on | off;
Default: memcached_socket_keepalive off;
Context: http, server, location

memcached_gzip_flag:启用 memcached 服务器响应中压缩标志,如果设置了标志,则将“Content-Encoding”响应头字段设置为“gzip”。

Syntax: memcached_gzip_flag flag;
Default: —
Context: http, server, location

memcached_next_upstream:定义在何种情况下将请求转发至下一台上游服务器,同样与 proxy_next_upstream 指令类似。

memcached_next_upstream_timeout:定义限制请求可以传递到下一个服务器的时间,其中 0 值表示关闭此限制,同样与 proxy_next_upstream_timeout 指令类似。

memcached_next_upstream_tries:定义请求可以传递到下一个服务器的最大次数,其中 0 值表示关闭此限制。

Syntax: memcached_next_upstream error | timeout | denied | invalid_response | not_found | off ...;
Default: memcached_next_upstream error timeout;
Context: http, server, location

# 参数说明:
error: 如果上游服务器返回错误,则自动切换到下一个可用上游(若只有一个后端上游则无法自动切换)。
timeout: 如果上游服务器响应超时,则转发请求。
denied: 如果上游服务器返回403,则转发请求。
invalid_response: 如果上游服务器返回无效响应,则转发请求。
not_found: 如果上游服务器返回404,则转发请求。
off: 禁用自动转发请求。

Syntax: memcached_next_upstream_timeout time;
Default: memcached_next_upstream_timeout 0;
Context: http, server, location

Syntax: memcached_next_upstream_tries number;
Default: memcached_next_upstream_tries 0;
Context: http, server, location

memcached_read_timeout:定义从 memcached 服务器读取响应的超时时间。

memcached_send_timeout:设置向 memcached 服务器发送请求的超时时间。

Syntax: memcached_read_timeout time;
Default: memcached_read_timeout 60s;
Context: http, server, location

Syntax: memcached_send_timeout time;
Default: memcached_send_timeout 60s;
Context: http, server, location

memcached_allow_upstream:定义是否允许转发请求的上游服务器地址,其中非空字符串以及非 0 值表示允许。

Syntax: memcached_allow_upstream string ...;
Default: —
Context: http, server, location

# 使用示例
geo $upstream_last_addr$allow {
  volatile;
  10.10.0.0/24        1;
}

server {
    listen 127.0.0.1:8080;

    location / {
      set                      $memcached_key"$uri?$args";
      memcached_pass           host:11211;
      memcached_allow_upstream $allow;
      ...
    }
}

另外,前面提到过,其内置变量名为 $memcached_key,定义用于从 memcached 服务器中获取其存储的键。

示例演示

为了演示 memcached 反向代理模块,我们先搭建一个 Memcached 服务。由于作者测试环境使用的是国产操作系统 OpenEuler 24.03 LTS ,因此这里将以其在软件源方式安装 Memcached 为例进行演示。

步骤 01. 更新软件源列表,并安装 python3-memcached 依赖软件包

yum update
yum install memcached python3-memcached

步骤 02. 配置 Memcached 服务,根据实际需求进行配置,注意将其 OPTIONS 配置为允许外部访问,例如:作者添加了允许外部访问的 IP 地址 10.20.172.214

$ vim /etc/sysconfig/memcached
PORT="11211"     # 监听端口
USER="memcached" # 运行用户
MAXCONN="1024"   # 最大连接数
CACHESIZE="128"  # 缓存大小(MB为单位)
OPTIONS="-l 127.0.0.1,::1,10.20.172.214"  # 其它参数:-l 允许外部访问的 IP 地址列表,使用逗号分隔

步骤 03. 并设置为开机自启,并启动 Memcached 服务

systemctl enable memcached.service
systemctl start memcached.service

步骤 04.查看 Memcached 服务状态

# 查看 Memcached 服务状态
systemctl status memcached.service

# 使用其命令行工具查看 Memcached 状态信息,缺省断开 11211 
memcached-tool 10.20.172.214 stats

# 显示 Memcached slabs 信息
memcached-tool 10.20.172.214:11211
#  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
1      96B      2111s       1       2      no        0        0    0

weiyigeek.top-查看验证 Memcached 服务状态图

步骤 05. 使用 telnet 测试 Memcached 服务是否正常运行,并添加后续 Nginx 在 Memcached 反向代理中所需的 Key 值。

$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

# 添加 Key
> set name 0 0 9
weiyigeek
STORED

# 获取 Key
> get name
VALUE name 0 9
weiyigeek
END

# 添加一个压缩 key
> set url 2 0 13
weiyigeek.top
STORED

# 获取压缩 key
> get url
VALUE url 2 13
weiyigeek.top
END

温馨提示:在Memcached中,数据压缩不是通过一个显式的命令参数来直接开启的,而是由客户端在发送数据到Memcached服务器时自动完成的(需要客户端支持并配置),且通常只对超过一定大小的值有效,例如上述例子中。

> set url 2 0 13
# 命令解释:
set : 命令,表示存储键值对,如果键已存在则覆盖。
url : 键名。
2 : 标志位(flags)。这是一个16位的无符号整数,由客户端自由定义,用于存储关于该值的一些元数据。服务器会原样存储并返回它,但本身不解释它。客户端可以用它来标记数据类型(如JSON、序列化数据、是否压缩等)。
0 : 过期时间(expiration time),单位为秒。0 表示永不过期。
13 : 数据块的长度(字节数)。这告诉服务器后面将接收13个字节的数据。

 

步骤 06. 配置 Nginx,并启用 memcached 反向代理模块

# 虚拟主机配置,反向代理到上游服务器组
server {
  listen 80;
  server_name test.weiyigeek.top;
  charset utf-8;
  default_type text/plain;

# 启用 HTTP/2 支持
  http2 on;

# 日志文件
  access_log /var/log/nginx/test.log main;
  error_log /var/log/nginx/test.err.log debug;

# 获取常规键
  location /get {
    set$memcached_key"$arg_key";
    memcached_bind 10.20.172.214;
    memcached_socket_keepalive on;
    memcached_read_timeout 60s;
    memcached_send_timeout 60s;
    memcached_pass 127.0.0.1:11211;
  }

# 获取压缩键
  location /getgzip {
    set$memcached_key"$arg_key";
    memcached_gzip_flag 2;
    memcached_bind 10.20.172.214;
    memcached_pass 10.20.172.214:11211;
  }
}

 

步骤 07.同样,配置完成后,验证并重启 Nginx 服务,之后使用 curl 命令测试反向代理是否正常工作。

# 验证并重启
nginx -t && nginx -s reload

# 获取在 Memcached 中存储的非压缩键 name
curl -i http://test.weiyigeek.top/get?key=name;echo

# 获取在 Memcached 中存储的压缩键 url
curl -i http://test.weiyigeek.top/getzip?key=url;echo

weiyigeek.top-验证Nginx中反向代理Memcached图

至此,我们就完成了 Nginx 反向代理 Memcached 的配置和测试。

 

加入:作者【全栈工程师修炼指南】知识星球

相关推荐