为解决 C10K(concurrent 10000 connection)问题而编写,与传统的服务器不同,Nginx 不依赖线程来处理请求,使用更具可伸缩性的事件驱动(异步)体系结构。是一款高性能的 HTTP 和反向代理服务器。
#启动 nginx
nginx -c /etc/nginx/nginx.conf
#关闭 nginx
nginx -s stop
#查看版本号
nginx -v
#重新加载
nginx -s reload
#优雅停止
nginx -s quit
#测试配置文件是否正确
nginx -t
文件结构
#全局配置块
...
#events 配置块
events
{
...
}
#http 配置块
http
{
#http 全局配置块
...
#server 配置块
server
{
#server 全局配置块
...
#location 配置块
location [PATTERN]
{
...
}
#location 配置块
location [PATTERN]
{
...
}
}
#server 配置块
server
{
...
}
#http 全局配置块
...
}
-
全局配置块 配置影响 nginx 全局的指令。一般有运行 nginx 服务器的用户组,nginx 进程 pid 存放路径,日志存放路径,配置文件引入,允许生成 worker process 数等。 -
events 配置块 配置影响 nginx 服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。 -
http 配置块 可以嵌套多个 server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type 定义,日志自定义,是否使用 sendfile 传输文件,连接超时时间,单连接请求数等。 -
server 配置块 配置虚拟主机的相关参数,一个 http 中可以有多个 server。 -
location 配置块 配置请求的路由,以及各种页面的处理情况。 语法规则: = 开头表示精确匹配 ^~ 开头表示 uri 以某个常规字符串开头,理解为匹配 url 路径即可(非正则) ~ 开头表示区分大小写的正则匹配 ~* 开头表示不区分大小写的正则匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不匹配的正则 / 通用匹配,任何请求都会匹配到 优先级: a. 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他 location 的匹配项 b. ^~和通用匹配。使用前缀匹配,不支持正则表达式,如果有多个 location 匹配成功的话,不会终止匹配过程,会匹配表达式最长的那个 c. 如果上一步得到的最长的 location 为^~类型,则表示阻断正则表达式,不再匹配正则表达式 d. 如果上一步得到的最长的 location 不是^~类型,继续匹配正则表达式,只要有一个正则成功,则使用这个正则的 location,立即返回结果,并结束解析过程
正则配置举例:# 优先级 1,精确匹配,根路径 location =/ { return 400; } # 优先级 2,以某个字符串开头,以 av 开头的,优先匹配这里,区分大小写 location ^~ /img { root /data/img/; } # 优先级 3,区分大小写的正则匹配,匹配/media*****路径 location ~ /media { alias /data/static/; } # 优先级 4 ,不区分大小写的正则匹配,所有的****.jpg|gif|png 都走这里 location ~* .*.(jpg|gif|png|js|css)$ { root /data/img/; } # 优先 7,通用匹配 location / { return 403; }
Nginx 配置文件示例 nginx.conf
#全局配置块
worker_processes 1;
#events 配置块
events
{
worker_connections 1024;
}
#http 配置块
http
{
#http 全局配置块
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#通过访问 http://192.168.1.167/a.html,实现负载均衡,平均分摊到 8080 和 8081 端口中。
upstream myserver
{
#每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
ip_hash;
#按后端服务器的响应时间来分配请求,响应时间短的优先分配
#fair;
#weight 代表权重,默认为 1,权重越高被分配的客户端越多。
#指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
server 192.168.1.167:8080 weight=1;
server 192.168.1.167:8081 weight=2;
}
#设定一个速率限制域,限制单位时间内的请求数,只允许每 200 毫秒一个请求
limit_req_zone $binary_remote_addr zone=mylimit:20m rate=5r/s;
#设定一个单个 IP 请求数限制域
limit_conn_zone $binary_remote_addr zone=IPAddr:10m;
#限流白名单设置(如压测场景)
geo $limit {
default 1;
10.0.0.0/8 0;
192.168.0.0/24 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=keylimit:20m rate=10r/s;
#geo 指令可以根据 IP 创建变量 $limit。$limit 的默认值是 1,如果匹配到了下面的 IP,则返回对应的值(这里返回的是 0)。
#之后通过 map 指令,将 $limit 的值映射为 $limit_key:在白名单内的,$limit_key 为空字符串,不在白名单内的,则为 $binary_remote_addr。
#当 limit_req_zone 指令的第一个参数是一个空字符串,限制不起作用,因此白名单的 IP 地址(在 10.0.0.0/8 和 192.168.0.0/24 子网中)没有被限制,其它 IP 地址都被限制为 5r/s。
#server 配置块
server
{
#server 全局配置块
listen 80;
server_name 192.168.1.167;
#location 配置块
#前端网站地址:http://localhost:8080
#服务端网址:http://localhost:8081
#前端跨域问题解决,当前端网站 8080 去访问服务端接口时,就产生了跨域问题
location / {
#指定静态文件的根目录为 Nginx 服务器上的 html 目录
root html;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080';
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
return 204;
}
if ($request_method != 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
add_header Access-Control-Allow-Credentials 'true';
}
#将 Nginx 服务器上的请求代理转发到另一个服务器上,
#并将该服务器返回的结果返回给客户端
proxy_pass http://localhost:8081;
#地址重写,重新定向跳转
if ($host = 'knowledgecat.cn') {
rewrite ^/(.*) http://www.knowledgecat.cn redirect;
}
#设置代理连接超时时间为 10 秒
proxy_connect_timeout 10;
#设置默认的索引文件为 index.html 或 index.htm。
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#动静分离
location /www/ {
root /data/;
index index.html index.htm;
}
#网站静态化处理的核心思路:动态资源、静态资源分离,是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,
#动静资源做好了拆分以后我们就可以根据静态资源的特点将其做缓存操作。
location /image/ {
root /usr/local/static/;
autoindex on;
}
location /login/ {
#使用速率限制,可缓存 5 个请求
#多条 limit_req 的指令,会匹配最严格那条
limit_req zone=mylimit burst=5 nodelay;
limit_req zone=keylimit burst=10 nodelay;
#自定义返回值
limit_req_status 666;
#更改 Nginx 的日志记录级别
limit_req_log_level warn;
proxy_pass http://myserver;
}
#拒绝某个指定 URL 地址的所有请求
location /foo.jsp {
deny all;
}
location /download/ {
#一次只允许一个连接
#当 request header 被后端 server 处理后,这个连接才进行计数
limit_conn IPAddr 1;
}
#根据访问路径不同跳转到不同服务
location ~/edu/ {
proxy_pass http://127.0.0.1:8080;
}
location ~/cat/ {
proxy_pass http://127.0.0.1:9090;
}
#location 配置块
location [PATTERN]
{
...
}
}
#server 配置块
server
{
#基于虚拟主机位置域名
#当客户端访问 www.knowledgecat.cn, 监听端口号为 8080,直接跳转到 data/www 目录下文件
listen 8080;
server_name www.knowledgecat.cn;
#防盗链类型(请求服务器或目录)
#root /server/file/;
location ~* ^.+.(gif|jpg|png|swf|flv|rar|zip)$ {
#白名单,Referer 头域中必须是含有白名单地址的访问
valid_referers none blocked www.knowledgecat.cn *.knowledgecat.cn;
if ($invalid_referer) {
rewrite ^/ www.knowledgecat.cn/images/forbidden.png;
}
}
location / {
root data/www;
#或者跳转到真实地址
#proxy_pass http://127.0.0.1:8080;
#高可用配置 指定上游服务器负载均衡服务器
proxy_pass http://backServer;
#nginx 与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间 _ 发起握手等候响应超时时间
proxy_connect_timeout 1s;
#nginx 发送给上游服务器(真实访问的服务器)超时时间
proxy_send_timeout 1s;
#nginx 接受上游服务器(真实访问的服务器)超时时间
proxy_read_timeout 1s;
index index.html index.htm;
}
}
#http 全局配置块
...
}
Nginx 的一些优化配置,对网络性能,response 的 header 进行优化。</
网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)
Nginx 按请求速率限速模块使用的是漏桶算法,能够强行保证请求的实时处理速度不会超过设置的阈值。Nginx 官方版本限制 IP 的连接和并发分别有两个模块:
limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。
- limit_req_conn 用来限制同一时间连接数,即并发限制。
- limit_req_zone $binary_remote_addr zone=mylimit:20m rate=1r/s;
- 第一个参数:$binary_remote_addr 表示通过 remote_addr 这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端 ip 地址。
- 第二个参数:zone=mylimit:20m 表示生成一个大小为 20M,名字为 mylimit 的内存区域,用来存储访问的频次信息。
- 第三个参数:rate=1r/s 表示允许相同标识的客户端的访问频次,这里限制的是每秒 1 次,还可以有比如 30r/s 的。
- limit_req zone=mylimit burst=5 nodelay;
- 第一个参数:zone=mylimit 设置使用哪个配置区域来做限制,与上面 limit_req_zone 里的 name 对应。
- 第二个参数:burst=5,burst 爆发的意思,这个配置使得限流具备了缓存处理突发流量的能力, 设置一个大小为 5 的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内,缓冲区满后的请求被拒绝,向客户端返回 503。
- 第三个参数:nodelay,允许请求在排队的时候就立即被处理(标记占据位置),也就是说只要请求能够进入 burst 队列,就会立即被后台 worker 处理。设置 burst 和 nodelay 能够降低突发请求的处理时间,但是长期来看并不会提高吞吐量的上限,长期吞吐量的上限是由 rate 决定的,因为 nodelay 只能保证 burst 的请求被立即处理,但 Nginx 会限制队列元素释放的速度,就像是限制了令牌桶中令牌产生的速度,当然加了 nodelay 参数的限速算法,依旧是漏桶算法。
负载均衡(Load Balance)
- 客户端层 -> 反向代理层 的负载均衡。通过 DNS 轮询;
- 反向代理层 -> Web 层 的负载均衡。通过 Nginx 的负载均衡模块;
- Web 层 -> 业务服务层 的负载均衡。通过服务治理框架的负载均衡模块;
- 业务服务层 -> 数据存储层 的负载均衡。通过数据的水平分布,数据均匀了,理论上请求也会均匀。比如 Range 、 时间、hash 取模,订单根据店铺 ID 等。
© 版权声明
博主的文章没有高度、深度和广度,只是凑字数。利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章!如若有侵权,请联系博主删除。
喜欢就点个赞吧