程序员L札记
2022/12/14阅读:32主题:橙心
Nginx入门与实践
Nginx入门与实践
@(随手记)
前言
这一篇是本人当时的学习笔记,分享给大家
基础篇
什么是Nginx
-
Nginx简述
Nginx是一个开源且高性能、可靠的HTTP中间件、代理服务
-
常见的HTTP服务
HTTPD-Apache基金会 IIS-微软 GWS-Google
Nginx特性
-
I/O多路复用epoll
1.1 I/O多路复用
多个描述符的I/O操作都能在一个线程内并发交替的顺序完成,这就叫I/O多路复用。这里的「复用」,指的是复用一个线程
1.2 什么是epoll
IO多路复用的实现方式:select、poll、epoll
-
轻量级
功能模块少 代码模块化
-
CPU亲和(affinity)
是一种吧CPU核心和Nginx工作进程绑定方式,把每个worker进程固定在一个CPU上执行,减少切换CPU的cache miss,获得更好的性能。
-
sendfile


Nginx安装(CentOS)
安装
-
创建 /etc/yum.repos.d/nginx.repo
-
添加如下内容
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
-
开始安装
yum list | grep nginx
yum install nginx
# 查看版本
nginx -v
# 查看配置参数
nginx -V
4.启动
# 检查配置是否正确
nginx -t -c /etc/nginx/nginx.conf
# 启动
nginx -s start -c /etc/nginx/nginx.conf
安装目录
-
查看安装目录
rpm -ql nginx
-
目录详解











nginx.conf配置文件


Nginx日志类型
-
error.log -
access_log
error.log指令
Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: main, http, mail, stream, server, location
access_log指令
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except
log_format指令
Syntax: log_format name [escape=default|json|none] string ...;
Default:
log_format combined "...";
Context: http
Nginx变量
-
HTTP请求变量 arg_PARAMETER、http_HEADER、send_http_HEADER -
内置变量 -
自定义变量 参考网址
Nginx默认模块
ngx_http_stub_status_module
Nginx的客户端状态
指令
Syntax: stub_status;
Default: —
Context: server, location
ngx_http_random_index_module
在主目录中随机选择一个主页
指令
Syntax: random_index on | off;
Default:
random_index off;
Context: location
ngx_http_sub_module
http响应内容替换
指令
Syntax: sub_filter string replacement;
Default: —
Context: http, server, location
ngx_http_limit_conn_module
http连接的限制(一次http请求建立在tcp连接的基础上)
指令
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http
Syntax: limit_conn zone number;
Default: —
Context: http, server, location
ngx_http_limit_req_module
http请求的限制
指令
Syntax: limit_req_zone key zone=name:size rate=rate [sync];
Default: —
Context: http
Syntax: limit_req zone=name [burst=number] [nodelay | delay=number];
Default: —
Context: http, server, location

ngx_http_access_module
基于ip的访问控制
指令
Syntax: allow address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
Syntax: deny address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
局限性
-
只能通过$remote_addr控制
解决办法
-
采用其它HTTP头信息控制访问,如HTTP_X_FORWARD_FOR -
结合geo模块 -
通过HTTP自定义变量传递
ngx_http_auth_basic_module
基于用户的安全认证的访问控制
指令
Syntax: auth_basic string | off;
Default:
auth_basic off;
Context: http, server, location, limit_except
Syntax: auth_basic_user_file file;
Default: —
Context: http, server, location, limit_except

局限性
-
用户信息依赖文件方式 -
操作管理机械,效率低下
解决方法
-
Nginx结合LUA实现高效验证 -
Nginx和LDAP打通,利用nginx-auth-ldap模块
场景实战篇
静态资源WEB服务
CDN场景
文件读取
-
sendfile 参考网址
Syntax: sendfile on | off;
Default:
sendfile off;
Context: http, server, location, if in location
-
tcp_nopush
sendfile
开启的情况下,提高网络包的传输效率。「大文件传输」 参考网址
Syntax: tcp_nopush on | off;
Default:
tcp_nopush off;
Context: http, server, location
-
tcp_nodelay
keepalive
连接下,提高网络包的传输实时性 参考网址
Syntax: tcp_nodelay on | off;
Default:
tcp_nodelay on;
Context: http, server, location
-
压缩「ngx_http_gzip_module」
压缩传输,对图片的压缩比不高。 参考网址
Syntax: gzip on | off;
Default:
gzip off;
Context: http, server, location, if in location
-
扩展Nginx压缩模块
-
ngx_http_gzip_static_module
预读
gzip
功能,需要提前使用gzip压缩源文件,占用额外的磁盘空间 参考网址
-
ngx_http_gunzip_module
支持
gunzip
的压缩方式,解决部分浏览器不支持gzip
参考网址
-
配置案例

浏览器缓存
ngx_http_headers_module模块 在HTTP response header中添加Cache-Control和Expires头信息 参考网址
流程图

指令
Syntax: expires [modified] time;
expires epoch | max | off;
Default:
expires off;
Context: http, server, location, if in location
跨域访问
ngx_http_headers_module模块 利用add_header指令,添加Access-Control-Allow-Origin和Access-Control-Allow-Methods头信息 参考网址
指令
Syntax: add_header name value [always];
Default: —
Context: http, server, location, if in location
防盗链
防止资源被盗用 区别哪些请求是非正常的用户请求 基于http_referer防盗链配置模块 参考网址
指令
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location
代理服务
参考网址 ngx_http_proxy_module模块
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
反向代理
正向代理
缓冲
proxy_buffer_size
设置用于读取从代理服务器接收的响应的第一部分的缓冲区的大小。这部分通常包含一个小的响应头。默认情况下,缓冲区大小等于一个内存页。这是4K还是8K,取决于平台。然而,它可以做得更小
Syntax: proxy_buffer_size size;
Default:
proxy_buffer_size 4k|8k;
Context: http, server, location
proxy_buffering
当缓冲被启用时,nginx会尽快从代理服务器接收响应,并将其保存到proxy_buffer_size和proxy_buffers指令设置的缓冲区中。如果整个响应无法装入内存,则可以将其中一部分保存到磁盘上的临时文件中。写入临时文件由proxy_max_temp_file_size和proxy_temp_file_write_size指令控制。
当缓冲被禁用时,响应会立即同步地传递到客户端。nginx不会尝试从代理服务器读取整个响应。nginx一次可以从服务器接收到的最大数据大小是由proxy_buffer_size指令设置的。
缓冲也可以通过在“X-Accel-Buffering”响应头字段中传递“yes”或“no”来启用或禁用。可以使用proxy_ignore_headers指令禁用此功能。
Syntax: proxy_buffering on | off;
Default:
proxy_buffering on;
Context: http, server, location
proxy_buffers
为单个连接设置用于从代理服务器读取响应的缓冲区的数量和大小。默认情况下,缓冲区大小等于一个内存页。这是4K还是8K,取决于平台。
Syntax: proxy_buffers number size;
Default:
proxy_buffers 8 4k|8k;
Context: http, server, location
proxy_busy_buffers_size
当启用代理服务器的响应缓冲时,将限制缓冲区的总大小,这些缓冲区在响应尚未完全读取时忙于向客户机发送响应。与此同时,剩余的缓冲区可以用于读取响应,如果需要,还可以将响应的一部分缓冲到临时文件中。默认情况下,大小由proxy_buffer_size和proxy_buffers指令设置的两个缓冲区的大小限制
Syntax: proxy_busy_buffers_size size;
Default:
proxy_busy_buffers_size 8k|16k;
Context: http, server, location
proxy_max_temp_file_size
当启用了来自代理服务器的响应的缓冲,并且整个响应不适合proxy_buffer_size和proxy_buffers指令设置的缓冲区时,可以将响应的一部分保存到临时文件中。这个指令设置临时文件的最大大小。每次写入临时文件的数据大小由proxy_temp_file_write_size指令设置。
Syntax: proxy_max_temp_file_size size;
Default:
proxy_max_temp_file_size 1024m;
Context: http, server, location
proxy_temp_file_write_size
在启用代理服务器对临时文件的响应缓冲时,限制一次写入临时文件的数据的大小。默认情况下,大小由proxy_buffer_size和proxy_buffers指令设置的两个缓冲区限制。临时文件的最大大小由proxy_max_temp_file_size指令设置。
Syntax: proxy_temp_file_write_size size;
Default:
proxy_temp_file_write_size 8k|16k;
Context: http, server, location
重定向
Syntax: proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
Default:
proxy_redirect default;
Context: http, server, location
负载均衡调度器SLB
GSLB

SLB

七层负载均衡

Nginx负载均衡

配置语法
Syntax: upstream name { ... }
Default: —
Context: http
例子
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
server参数
-
down
当前的server暂时不参与负载均衡
-
backup
将服务器标记为备份服务器。它将在主服务器不可用时传递请求。
-
max_fails
允许请求失败的次数
-
fail_timeout
经过max_fails次失败后,服务暂停的时间
-
max_conns
限制最大连接数
负载均衡算法
轮询
按时间顺序逐一分配到不同的后端服务器
加权轮询
weight值越大,分配到的访问几率越高
ip_hash
每个请求按访问ip的hash结果分配,这样来自同一个ip的请求固定访问同一个后端服务器
url_hash
按照访问的url的hash结果来分配请求,每个url定向到同一个后端服务器。「通过hash key实现」
least_conn
最少连接数,哪个server连接数少就分配到哪个
hash
hash自定义的key
动态缓存
缓存类型
-
客户端缓存 -
代理缓存 -
服务端缓存
代理缓存
ngx_http_proxy_module模块 参考网址
proxy_cache_path
设置缓存的路径和其他参数
Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default: —
Context: http
proxy_cache
定义用于缓存的共享内存区域。同一个区域可以用于多个地方。参数值可以包含变量(1.7.9)。off参数禁用从以前的配置级别继承的缓存。
Syntax: proxy_cache zone | off;
Default:
proxy_cache off;
Context: http, server, location
proxy_cache_valid
为不同的响应代码设置缓存时间
Syntax: proxy_cache_valid [code ...] time;
Default: —
Context: http, server, location
proxy_cache_key
定义用于缓存的键
Syntax: proxy_cache_key string;
Default:
proxy_cache_key $scheme$proxy_host$request_uri;
Context: http, server, location
补充
清理缓存
-
rm -rf 删除缓存目录内容 -
第三方扩展模块ngx_cache_purge
部分页面不缓存
-
proxy_no_cache
定义不将响应保存到缓存的条件。如果字符串参数中至少有一个值不为空且不等于“0”,则不会保存响应。
Syntax: proxy_no_cache string ...;
Default: —
Context: http, server, location
大文件的分片请求
-
ngx_http_slice_module
默认情况下不构建此模块,应该使用——with-http_slice_module配置参数启用它
-
配置示例
location / {
slice 1m;
proxy_cache cache;
proxy_cache_key $uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
proxy_cache_valid 200 206 1h;
proxy_pass http://localhost:8000;
}
slice指令设置分片的大小为1m。 这里使用了proxy_set_header指令,在取源时的HTTP请求中添加了Range头部,向源服务器请求文件的一部分,而不是全部内容。在proxy_cache_key中添加slice_range变量这样可以分片缓存
深度学习篇
动静分离
通过中间件将静态请求和动态请求分离。目的是减少不必要的请求消耗,减少请求延时。
Nginx的rewrite规则
实现url重写以及重定向
场景
-
URL访问跳转,支持开发设计 -
SEO优化 -
维护「后台维护,流量转发等」 -
安全
指令
参考网址 ngx_http_rewrite_module模块
Syntax: rewrite regex replacement [flag];
Default: —
Context: server, location, if
正则表达式
-
. 「匹配除换行符以外的任意字符」 -
? 「重复0次或1次」 -
+ 「重复1次或更多次」 -
* 「匹配前面的子表达式任意次,等价于{0,}」 -
\d 「匹配数字」 -
^ 「匹配输入字行首」 -
$ 「匹配输入行尾」 -
{n} 「重复n次」 -
{n,} 「重复n次或更多次」 -
[c] 「匹配单个字符c」 -
[a-z] 「字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符」 -
\
「转义字符」 -
( ) 「用于匹配括号之间的内容,通过** 2**调用」 -
pcretest 「终端测试命令」
flag参数
last
停止处理当前rewrite指令,并开始搜索与更改的URI匹配的新的location。服务端只会接收到一次请求。
break
停止处理当前rewrite指令,不会搜索与更改的URI匹配的其它location。
redirect
返回一个带有302状态码的临时重定向,地址栏会显示跳转后的地址。服务端会接收到多次请求。
permanent
返回带有301代码的永久重定向,地址栏会显示跳转后的地址。
案例

Nginx高级模块
ngx_http_secure_link_module
用于检查请求链接的真实性,保护资源不受未授权访问,并限制链接的生存期。 参考网址
指令
Syntax: secure_link expression;
Default: —
Context: http, server, location
Syntax: secure_link_md5 expression;
Default: —
Context: http, server, location
验证图示

案例
location /s/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
...
}
ngx_http_geoip_module
基于IP地址,匹配MaxMind GeoIP二进制文件,读取IP所在地域信息 默认没有安装此模块,使用yum install nginx-module-geoip安装 配置nginx.conf文件,在http上下文中添加:
load_module modules/ngx_http_geoip_module.so; load_module modules/ngx_stream_geoip_module.so; 需要下载MaxMind GeoIP库 GeoLiteCountry和GeoLiteCity过期了 参考地址
使用场景
-
区别国内外,做http访问规则 -
区别国内城市地域,做http访问规则
指令
Syntax: geoip_country file;
Default: —
Context: http
Syntax: geoip_city file;
Default: —
Context: http
ngx_http_ssl_module(https)
生成秘钥和CA证书
-
生成秘钥
openssl genrsa -des3 -out server.key 2048
-
生成证书签名请求文件(csr文件)
openssl req -new -key server.key -out server.csr
-
生成证书签名文件(crt文件)「自签」
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
指令
# 开关https,1.15.0版本之后过时,应该使用listen指令的ssl参数
Syntax: ssl on | off;
Default:
ssl off;
Context: http, server
# CA证书的路径
Syntax: ssl_certificate file;
Default: —
Context: http, server
# 秘钥key文件的路径
Syntax: ssl_certificate_key file;
Default: —
Context: http, server
生成苹果公司要求的openssl证书

-
nginx启动或停止时会要求输入密码,可以使用如下方法去除密码:
-
openssl x509 -req -days 365 -sha256 -nodes -newkey rsa:2048 -keyout server.key -out apple_server.crt -
-keyout server.key 会生成一个新的没有密码保护的key文件 -
或者使用这种方式,去除私钥中的密码openssl rsa -in server.pass.key -out server.key
https服务的优化
Nginx与Lua开发
Lua及基础语法
Lua
是一个简洁、轻量、可扩展的脚本语言
基础语法
-
安装lua 「yum install lua」 -
运行lua 「1.执行lua命令 2.lua文件」 -
语法
Nginx与Lua环境
-
luaJIT -
ngx_devel_kit和lua-nginx-module -
重新编译nginx -
参考文章
Nginx调用Lua模块指令
Nginx的可插拔模块化加载执行,共11个处理阶段
-
set_by_lua 设置nginx变量,可以实现复杂的赋值逻辑 -
set_by_lua_file -
access_by_lua -
access_by_lua_file 请求访问阶段处理,用于访问控制 -
content_by_lua -
content_by_lua_file 内容处理器,接收请求处理并输出响应
Nginx Lua Api
-
ngx.var nginx变量 -
ngx.req.get_headers 获取请求头 -
ngx.req.get_uri_args 获取url请求参数 -
ngx.redirect 重定向 -
ngx.print 输出响应内容体 -
ngx.say 同上,但是会最后输出一个换行符 -
ngx.header 输出响应头 -
更多
用Nginx结合Lua实现代码的灰度发布

连接不存在了
架构篇
Nginx常见问题
相同server_name多个虚拟主机的访问优先级
优先访问先读取到的server_name
location匹配优先级
-
= 进行普通字符精确匹配,也就是完全匹配 -
^~ 表示普通字符匹配,使用前缀匹配 -
~ \ ~* 表示执行一个正则匹配
try_files使用
按指定顺序检查文件是否存在,并使用第一个找到的文件进行请求处理;处理是在当前上下文中执行的。文件的路径是根据根和别名指令从文件参数构造的。可以通过在名称后面指定一个斜杠来检查目录是否存在,例如“$uri/”。如果没有找到任何文件,则对最后一个参数中指定的uri进行内部重定向。
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
Nginx的alias和root的区别
如果请求的uri是/1/2/3.html alias /a/b/c,将会查找/a/b/c/3.html root /a/b/c,将会查找/a/b/c/1/2/3.html
用什么方法传递用户的真实IP

常见错误码

Nginx性能优化
性能优化考虑点
-
当前系统结构瓶颈
观察指标,压力测试
-
了解业务模式
接口业务类型,系统层次化结构
-
性能与安全
ab接口压力测试工具
-
安装
yum install httpd-tools
-
使用
ab -n 200 -c 100 http://localhost -n 总的请求数 -c 并发数 -k 是否开启长连接
系统与Nginx的性能优化
-
网络 -
系统
-
服务
-
程序 -
数据库、底层服务
文件句柄
linux/unix 一切皆文件,文件句柄就是一个索引
设置方式
系统全局性修改、用户局部性修改、进程局部性修改 系统和用户级修改**/etc/security/limits.conf** 进程级别修改nginx.conf文件在添加worker_rlimit_nofile属性
CPU亲和
Syntax: worker_cpu_affinity cpumask ...;
worker_cpu_affinity auto [cpumask];
Default: —
Context: main
For example
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
# 查看系统的端口端口状态
netstat -luntp | grep 8080
# 查看系统cpu数
cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
# 查看但cpu核心数
cat /proc/cpuinfo | grep "cpu cores" | uniq
# 查看work进程与cpu绑定关系
ps -eo pid,args,psr | grep [n]ginx
基于Nginx架构的安全
常见的恶意行为
爬虫行为和恶意抓取、资源盗用
-
基础防盗链ngx_http_referer_module:目的是不让恶意用户轻易的爬取网站对外数据 -
secure_link_module:对数据安全性提供加密验证和时效性,适合核心重要数据 -
access_module:对后台、部分用户服务的数据提供IP防控
常见的应用层攻击手段
后台密码撞库
通过猜测密码字典,不断对后台系统进行尝试性登录,获取后台登录密码
-
密码复杂度 -
access_module对后台提供IP防控 -
预警机制
文件上传漏洞
利用这些可以上传的接口,将恶意代码植入到服务器中,再通过url去访问以执行代码
SQL注入
Nginx防攻击策略
Nginx+Lua防火墙
基于Nginx的中间件架构
了解需求
-
定义nginx在服务体系中的角色
-
静态资源服务 -
代理服务 -
动静分离服务
-
静态资源服务的功能设计
-
类型分类 -
浏览器缓存 -
防盗链 -
流量限制 -
防资源盗用 -
压缩
-
代理服务
-
协议类型 -
正向代理 -
反向代理 -
负载均衡 -
代理缓存 -
头信息的处理 -
proxypass -
lnmp
设计评估
-
硬件:cpu、内存、硬盘 -
系统:用户权限、日志目录存放 -
关联服务:LVS、keepalive、syslog、fastcgi
配置注意事项
-
合理配置 -
了解原理 -
关注日志
欢迎关注我的公众号:程序员L札记

作者介绍