nginx 学习4

您所在的位置:网站首页 nginx反向代理工作原理 nginx 学习4

nginx 学习4

#nginx 学习4| 来源: 网络整理| 查看: 265

1.uwsgi、fastcgi、scgi、http指令的差异

七层反向代理

CGI

全称通用网关接口 Commmon Gateway Interface。CGI描述了服务器和请求处理程序之间传输数据的一种标准。

是HTTP服务器和动态脚本语言间通信的接口或者工具

fastcgi : php

Fast Common Gateway Interface,早期 CGI的增强版本

差异:

CGI 对 Web 服务器的每个请求均建立一个进程进行请求处理 FastCGI 服务进程接收 Web 服务器的请求后,由自己的进程自行创建线程完成请求处理。

php的实现fastcgi是 PHP-FPM

wsgi usgi

多用于 python web开发 , django或flask

scgi

Simple Common Gateway Interface 简单通用网关接口 fastCGI类型 但更容易实现,性能比 FastCGI 要弱

2.memcached反向代理的用法

ngx_http_memcached_module 安装

例子 server { server_name localhost; listen 8319; #root html/; default_type text/plain; location /get { # 通过get转发 set $memcached_key "$arg_key"; #memcached_gzip_flag 2; memcached_pass localhost:11211; # 代理的memcahed 服务器地址 } } # 写入变量 curl 127.0.0.1:8319/get?key=hello telnet 127.0.0.1 11211 # set hello 0 0 5 # get hello # VALUE hello 0 5 curl 127.0.0.1:8319/get?key=hello -I #显示不压缩 # 通过加入 gzipkey 告诉浏览器开启gzip压缩 curl 127.0.0.1:8319/get?key=gzipkey -I #Content-Encoding: gzip 复制代码 3.websocket反向代理

安装 ngx_http_proxy_module

# 需要升级协议才能使用 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 复制代码 数据分片 :有序 不支持多路复用 A Multiplexing Extension for WebSockets 不支持压缩 Compression Extensions for WebSocket 扩展头部 Sec-WebSocket-Version: 客户端发送,表示它想使用的WebSocket 协议版本 (13表示RFC 6455)。如果服务器不支持这个版本,必须回应自己支持的版本。 Sec-WebSocket-Key: 客户端发送,自动生成的一个键,作为一个对服务器的“挑战”,以验证服务器支持请求的协议版本; Sec-WebSocket-Accept: 服务器响应,包含Sec-WebSocket-Key 的签名值,证明它支持请求的协议版本 Sec-WebSocket-Protocol: 用于协商应用子协议: 客户端发送支持的协议列表,服务器必须只回应一个协议名- - Sec-WebSocket-Extensions: 用于协商本次连接要使用的WebSocket扩展: 客户端发送支持的扩展,服务器i同的首部确认自己支持一或多个扩展。 例子 server { server_name localhost; #root html/; default_type text/plain; listen 8320; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass ws://121.40.165.18:8800/; } } ## 在线调试 http://www.websocket-test.com/ 在网址里输入 本地的的 ws://xx.xx.xx.xx:8320 服务,点击连接 然后发送消息 # 本地监听转发的地址 tcpdump -i eth0 port 8800 and host 121.40.165.18 # 可以监听各种输出 复制代码 4.用分片提升缓存效率 slice模块

Nginx的slice模块可以将一个请求分解成多个子请求,每个子请求返回响应内容的一个片段,让大文件的缓存更有效率。同时配合http的range 提供客户端下载的速度。

通过range协议将大文件分解为多个小文件,更好的用缓存为客户端的range协议服务模块. http_slice_module,通过--with-http_slice_module启用功能 例子 # 上游服务器 server { server_name localhost; listen 8012; default_type text/plain; root html; location /{ return 200 ; } } # 下游服务器 proxy_cache_path /data/nginx/tmpcache3 levels=2:2 keys_zone=three:10m loader_threshold=300 loader_files=200 max_size=200m inactive=1m; server { server_name localhost; listen 8321; error_log logs/cacherr.log debug; location ~ /purge(/.*) { proxy_cache_purge three $1$is_args$args$slice_range; } location /{ proxy_cache three; # 通过制定切割大小实现 缓存优化,slice proxy_cache_key proxy_set_header 需要同时打开 #slice 1m; #proxy_cache_key $uri$is_args$args$slice_range; #proxy_set_header Range $slice_range; proxy_cache_valid 200 206 1m; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://localhost:8012; } } # 在没打开 slice ; 时候 # 按指定切片访问nginx 的大文件,虽然只访问了一小部分,但nginx考虑到后面其他链接也会使用,所以会发起完整的请求。 curl -r 5000010-5000019 127.0.0.1:8321/test.mp4 -I # nginx会切割成多个 小请求,通过range方式请求上游服务器,通过日志可以看到 tail -f../logs/access.log # 日志显示 请求了完整的文件/test.mp4 #127.0.0.1 23/Dec/2023:14:30:19+08001/video .mp4"HEAD/video.mp4 HTTP/10" 206 curl/7.29.0" # 当打开了 slice ; 时候 curl -r 5000010-5000019 127.0.0.1:8321/test.mp4 -I tail -f../logs/access.log # 只请求的切片的大小 #127.0.0.1 23/Dec/2023:14:30:19+08001/video .mp4"HEAD/video.mp4 HTTP/10" 206 57381757 curl/7.29.0" 复制代码 5.open_file_cache提升系统性能

直接把文件缓存到内存里,检查问价open的开销

open_file_cache_errors on | off; 复制代码 例子 server { listen 8092; root html; location / { open_file_cache max=10 inactive=60s; open_file_cache_min_uses 1; open_file_cache_valid 60s; open_file_cache_errors on; } } # 安装strace strace常用来跟踪进程执行时的系统调用和所接收的信号, 是一个强大的工具 yum install strace -y # 获取当前nginx的 worker id ps -ef | grep nginx strace -p 4669 # 监听指定id # 可以看到 nginx是否 复制代码 6. http2协议介绍 HTTP2主要特性 传输数据量的大幅减少 : 以二进制方式传输,标头压缩 多路复用及相关功能: 消息优先级 服务器消息推: 并行推送 HTTP2.0核心概念 连接Connection:1个TCP连接,包含一个或者多个Stream 数据流Stream:一个双向通讯数据流,包含多条Message 消息Message:对应HTTP1中的请求或者响应包含一条或者多条Frame 数据帧Frame:最小单位,以二进制压缩格式存放HTTP1中的内容 传输中无序,接收时组装 数据流优先级 每个数据流有优先级(1-256) 数据流间可以有依赖关系 标头压缩 Frame格式 TYPE类型: HEADERS:顿仅包含HTTP 标头信息 DATA:顿包含消息的所有或部分有效负载 PRIORITY:指定分配给流的重要性。 RST STREAM: 错误通知:一个推送承诺遭到拒绝。终止流 SETTINGS:指定连接配置。 PUSH PROMISE: 通知一个将资源推送到客户端的意图 PING: 检测信号和往返时间。 GOAWAY:停止为当前连接生成流的停止通知 WINDOW UPDATE: 用于管理流的流控制。 CONTINUATION: 用于延续某个标头碎片序列。 服务器推送PUSH 7.搭建http2服务并推送资源 ngx_http_v2_module,通过--with-http_v2_module编译nginx加入http2协议的支持 功能:对客户端使用http2协议提供基本功能 前提: 开启TLS/SSL协议 使用方法: listen 443 ssl http2; nginx推送资源 http2_push_preload on | off; http2 push uri | off; 如: http2 push/image.png

测试nginx http2协议的客户端工具 github.com/nghttp2/ngh…

centos下使用yum安装:yum install nghttp2

例子 server { server_name localhost; listen 4430 ssl http2; # managed by Certbot ssl_certificate ./cert/a.crt; ssl_certificate_key ./cert/a.key; root html; location / { # 当请求 根目录,则会推送 mirror.txt和video.mp4回去 http2_push /mirror.txt; http2_push /video.mp4; } location /test { add_header Link "; as=style; rel=preload"; http2_push_preload on; } } nghttp -ns https://localhost:4430/ # 返回 返回html同时,也会推送 mirror.txt和video.mp4回去 nghttp -ns https://localhost:4430/test # 同时返回 css 复制代码 ## 最大并行推送数 http2_max_concurrent_pushes 10; ## 超时控制 http2_recv_timeout 30s; http2_idle_timeout 3m; ## 并发请求控制 http2_max_concurrent_pushes 10; http2_max_concurrent_streams 128; http2_max_field_size 4k; ## 连接最大处理请求数 http2_max_requests 1000; http2_chunk_size 8k; ## 设置响应包体的分片大小 http2_chunk_size 8k; ## 缓冲区盅椽大小设置 http2_recv_buffer_size 256k; http2_max_header_size 16k; http2_body_preread_size 64k 复制代码 8.grpc反向代理 gRPC是一种进程间通信技术。在 gRPC 中,客户端可以直接调用不同机器上的服务端的方法,就像调用本地函数一样。 RPC是远程过程调用(Remote Procedure Call)的缩写形式 grpc协议:grpc.io/ ngx_http_grpc_module,通过--without-http_grpc_module禁用依赖ngx_http_v2_module模块 例子 server { server_name localhost; root html; location / { grpc_pass localhost:50051; # 50051是本地的python服务 } listen 4431 http2; ssl_certificate ./cert/a.crt; ssl_certificate_key ./cert/a.key; } with grpc.insecure channel( localhost:50051') as channel: python greeter client.py # 这里的python 是grpc example提供 复制代码 9.stream四层反向代理(TCP) stream模块7个阶段 POST_ACCEPT realip PREACCESS limt_conn ACCESS access SSL ssl PREREAD ssl_preread CONTENT return, stream_proxy LOG access_log 传输层相关的变量 binary_remote_addr 客户端地址的整型格式,对于IPv4是4字节,对于 IPV6是16字节 connection 递增的连接序号 remote_addr 客户端地址 remote_port 客户端端口 proxy_protocol_addr 若使用了proxy_protocol协议则返回协议中的地址,否则返回空 proxy_protocol_port 若使用了proxy_protocol协议则返回协议中的端口,否则返回空 protocol 传输层协议,值为TCP或者UDP server_addr 服务器端地址 server_port 服务器端端口 bytes_received 从客户端接收到的字节数 bytes_sent 已经发送到客户端的字节数 传输层相关的变量 status 200: session成功结束 400:客户端数据无法解析,例如proxy protocol协议的格式不正确 403:访问权限不足被拒绝,例如access模块限制了客户端IP地址 500:服务器内部代码错误 502:无法找到或者连接上游服务 503:上游服务不可用 Nginx 系统变量 time_local 以本地时间标准输出的当前时间,例如14/Nov/2018:15:55:37 +0800 time_iso8601 使用ISO 8601标准输出的当前时间,例如2018-11-14T15:55:37+08:00 nginx_version Nginx 版本号 pid 所属worker 进程的进程id pipe 使用了管道则返回 p,否则返回 hostname 所在服务器的主机名,与hostname 命令输出一致 msec 1970年1月1日到现在的时间,单位为秒,小数点后精确到毫秒 content阶段: return模块

returm value;

例子 stream { log_format basic '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time'; error_log logs/stream_error.log debug; access_log logs/stream_access.log basic; server { listen 10004; set_real_ip_from 127.0.0.1; allow 202.112.144.236; deny all; return '10004 vars: bytes_received: $bytes_received bytes_sent: $bytes_sent proxy_protocol_addr: $proxy_protocol_addr proxy_protocol_port: $proxy_protocol_port remote_addr: $remote_addr remote_port: $remote_port realip_remote_addr: $realip_remote_addr realip_remote_port: $realip_remote_port server_addr: $server_addr server_port: $server_port session_time: $session_time status: $status protocol: $protocol '; } } # 测试 telnet localhost 10004 复制代码 10.proxy protocol协议与realip模块 proxy_protocol协议 v1协议 v2协议 stream处理proxy_protocol流程 连接建立成功,是否携带listen proxy protocol? 是 加入读定时器proxy_protocol timeout(默认30秒) 读取107字节(proxy protocol最大长度) 判断前12字节是否匹配V2协议的头部? 否 读取v1协议头部的真实IP地址 读取v2协议头部的真实IP地址 进入7个阶段的stream模块处理 读取proxy_protocol协议的超时控制

proxy_protocol_timeout 30s;

post_accept阶段: realip模块

通过proxy_protocol协议取出客户端真实地址,并写入remote_addr及remote_port变量。同时使用realip remote_addr和realip_remote_port保留TCP连接中获得的原始地址。

模块:ngx_stream_realip_module ,通过--with-stream_realip_module启用功能

set_real_ip_from address | CIDR | unix:;

例子 stream { log_format basic '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time'; error_log logs/stream_error.log debug; access_log logs/stream_access.log basic; server { listen 10002 proxy_protocol; return '10002 server get ip: $remote_addr!\n'; } server { listen 10003 proxy_protocol; return '10003 server get ip: $remote_addr!\n'; } server { listen 10004 proxy_protocol; set_real_ip_from 127.0.0.1; allow 202.112.144.236; deny all; return '10004 vars: bytes_received: $bytes_received bytes_sent: $bytes_sent proxy_protocol_addr: $proxy_protocol_addr proxy_protocol_port: $proxy_protocol_port remote_addr: $remote_addr remote_port: $remote_port realip_remote_addr: $realip_remote_addr realip_remote_port: $realip_remote_port server_addr: $server_addr server_port: $server_port session_time: $session_time status: $status protocol: $protocol '; } } # 测试 telnet localhost 10004 复制代码 11.限并发连接、限IP、记日志 PREACCESS阶段的limit_conn模块

功能: 限制客户端的并发连接数。使用变量自定义限制依据,基于共享内存所有worker进程同时生效。 模块: ngx_stream_limit_conn_module,通过--without-stream_limit_conn_module禁用模块 limit_conn_zone key zone=name:size;

ACCESS阶段的access模块

功能:根据客户端地址 (realip模块可以修改地址)决定连接的访问权限

模块:ngx_stream_access_module,通过--without-stream_access_module禁用模块

allow address | CIDR | unix: | all deny address | CIDR | unix: | all;

log阶段: stream log模块 access_log path format [buffer=size] [gzip[=level]] [flush=time] [if=condition]; log_format name [escape=default|json|none] string ...; open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time]; open_log_file_cache off; 复制代码 12.stream四层反向代理 SSL下游流量 stream模块TLS/SSL应用场景 客户端 nginx 上游服务 客户端 nginx 上游服务 客户端 nginx 上游服务 stream中的ssl

功能: 使stream反向代理对下游支持TLS/SSL协议 模块: ngx_stream_ssl_module,默认不编译进nginx,通过--with-stream_ssl_module

stream ssl模块提供的变量 (1) #安全套件 ssl_cipher #本次通讯选用的安全套件,例如ECDHE-RSA-AES128-GCM-SHA256 ssl_ciphers #客户端支持的所有安全套件 ssl_protocol #本次通讯选用的TLS版本,例如TLSv1.2 ssl_curves #客户端支持的圆曲线,例如secp384rl:secp521rl #证书 ssl_clicnt_raw_cert #原始客户端证书内容 ssl_client_escaped_cert #返回客户端证书做urlencode编码后的内容 ssl_client_cert #对客户端证书每一行内容前加tab制表符空白,增强可读性 ssl_clicnt_fingerprint #客户端证书的SHA1指纹 复制代码 STREAM SSL模块实战

客户端 nginx 上游服务

注意:nginx使用stream四层反向代理的stream ssl module模块解析TLS协议

例子 server { listen 4433; resolver 114.114.114.114; resolver timeout 60s; proxy_pass $ssl_preread_server_name:443; ssl_preread on; } server { server_name localhost; listen 4434 ssl; # 设置自己的服务器证书 a 证书 ssl_certificate ./cert/a.crt; ssl_certificate_key ./cert/a.key; proxy_pass localhost:80; } server { server_name localhost; #root html/; default_type text/plain; listen 8320; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass ws://121.40.165.18:8800/; } } # 通过浏览器访问 http://xx.xx.xx.xx:8320: # 测试 tcpdump -i lo port 8320 -A -s 0 # 通过tcpdump 抓包查看日志 复制代码 13.stream_preread 模块取出SSL关键信息 SSL PREREAD模块

模块 : stream_ssl_preread_module,使用--with-stream_ssl_preread_module启用模块 功能 :解析下游TLS证书中信息,以变量方式赋能其他模块

提供变量 $ssl_preread_protocol :客户端支持的TLS版本中最高的版本,例如TLSv1.3 $ssl_preread_server name : 从SNI中获取到的服务器域名 $ssl_preread_alpn_protocols : 通过ALPN中获取到的客户端建议使用的协议,例如h2,http/1.1 流程 POST_ACCEPT realip PREACCESS limt_conn ACCESS access SSL ssl PREREAD ssl_preread CONTENT return, stream_proxy LOG access_log preread阶段: ssl preread模块

preread_buffer_size 16k; preread_timeout 30s; ssl_preread off;

STREAM SSL PREREAD模块实战 STREAM SSL模块实战

客户端 nginx 上游服务

基于stream_ssl_preread_module模块中取得的证书中域名,选择上游的服务

14.stream proxy四层反向代理的用法 反向代理stream_proxy模块

模块 ngx_stream_proxy_module,默认在Nginx中

功能 提供TCP/UDP协议的反向代理 支持与上游的连接使用TLS/SSL协议 支持与上游的连接使用proxy protocol协议 proxy模块对上下游的限速指令 proxy_download_rate 0; # 限制读取上游服务数据的速度( 客户端 -> nginx ) proxy_upload_rate 0; # 限制读取客户端数据的速度 ( nginx


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3