持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
Nginx功能介绍
来自百科: Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,公开版本1.19.6发布于2020年12月15日。
Nginx功能丰富,可作为web应用服务器,也可作为反向代理服务器,邮件服务器。
支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能, 并且支持很多第三方的模块扩展, 如之前文章中介绍的OpenResty。
配置文件大致结构
- 全局配置
- events模块
- http模块
... http模块配置
- upstream模块
- server模块
- location模块
- stream模块(1.90版本后)
全局配置
配置影响Nginx全局的参数, 一般有日志存放路径, 配置文件引入, 允许生成worker process数等
#运行用户
user nobody;
# 启动进程,通常设置成和cpu的数量相等
worker_processes 4;
#全局错误日志及PID文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
worker_rlimit_nofile 1024;
# 引入其他配置文件
include /etc/nginx/conf.d/*.conf;
events模块
配置影响nginx服务器或与用户的网络连接
events {
# epoll是多路复用IO(I/O Multiplexing)中的一种方式,
# 仅用于linux2.6以上内核,可以大大提高nginx的性能,配置指定了线程轮询的方法(如果是BSD如Mac请使用Kqueue)
use epoll;
# 单个后台worker process进程的最大并发链接数
worker_connections 1024;
}
http模块
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 日志文件路径
access_log logs/access.log main;
# sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
# 对于普通应用,必须设为 on,
# 如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
# 以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
# 连接超时时间(秒)
keepalive_timeout 300;
# 接口响应超时时间
# 不配置默认60s, 超时会404
proxy_read_timeout 600;
proxy_send_timeout 600;
# Nginx使用该大小申请read_buf,即大小指定了 upstream header 最大长度,
# 如果响应头超过了这个长度,Nginx会报upstream sent too big header错误,
# 然后客户端收到的是502。
proxy_buffer_size 4k;
# 开启gzip
gzip on;
# 设置对数据启用压缩的最少字节数
gzip_min_length 1000;
# 设置数据的压缩等级
# 这个等级可以是1-9之间的任意数值, 9是最慢但是压缩比最大的,
# 我们设置为4, 这是一个比较折中的设置
gzip_comp_level 4;
# 指定客户端禁用gzip功能, 要兼容恶心的ie浏览器
gzip_disable msie6;
# 设置需要压缩的数据格式
gzip_types text/plain application/x-javascript text/css text/html application/xml;
# server模块配置
server {
# 监听80端口
listen 80;
# 指定ip地址或者域名,多个配置之间用空格分隔
server_name localhost;
# web资源根目录
root /html/test;
# 默认首页
index index.html index.html;
# 日志
access_log logs/access.log;
error_log logs/error.log;
# location模块
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_pass 127.0.0.1:8080;
}
}
}
反向代理
location / {
proxy_pass 127.0.0.1:8080;
}
负载均衡 upstream的5种负载方式:
- 轮询(默认)
- 权重
upstream test {
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=2;
# backup 其它所有的非backup机器down或者忙的时候, 请求backup机器
server 127.0.0.1:8082 backup;
server 127.0.0.1:8083;
}
- ip_hash
upstream test {
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
- url_hash
upstream test {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
hash $request_uri;
# 指定hash算法
hash_method crc32;
}
- fair(服务器响应时间短的优先分配)
upstream test {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
fair;
}
健康检查机制
upstream backend {
# max_fails=3 请求失败超过3次暂停服务
# fail_timeout=30s 请求失败暂停30s之后重新发起请求
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
}
https代理 查看nginx是否安装了ssl模块, 没有需要安装了ssl模块, 注意证书的有效期, 失效后不可用
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /opt/nginx/conf/nssl/xx.pem;
ssl_certificate_key /opt/nginx/conf/nssl/xx.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
}
流量复制 查看nginx是否安装了ngx_http_mirror_module模块, 没有需要安装ngx_http_mirror_module模块, 将生产环境的流量拷贝到预上线环境或测试环境
location / {
mirror /mirror;
proxy_pass http://prod;
}
location = /mirror {
internal;
proxy_pass http://test$request_uri;
}
白名单
在http和stream模块下以及在server和location都可以 进行控制
http {
# allow 允许访问的ip
allow 10.0.0.0/8;
allow 123.124.15.6;
allow 123.45.67.128/28;
# 其余的都不允许访问
deny all;
}
访问频率控制
- ip控制
limit_req_zone $binary_remote_addr zone=one:10m rate=100r/s;
- server_name控制
limit_req_zone $server_name zone=serverrequestlimit:10m rate=500r/s;
upstream limit-server {
server 127.0.0.1:8090;
server 127.0.0.1:8091;
server 127.0.0.1:8092;
}
server {
listen 18090;
server_name limit-server;
location / {
limit_req zone=serverrequestlimit burst=1 nodelay;
limit_req_log_level warn;
limit_req_status 429;
proxy_pass http://limit-server ;
}
}
访问速度控制
# 是对每个连接限速100k, 而不是对IP限速
limit_rate 100k;
跨域处理
server {
listen 80;
charset utf-8;
location /api {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
return 204;
}
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
proxy_pass http://127.0.0.1:8080;
}
}
日志配置
server {
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
}
listen 80;
access_log /data/logs/$year$month$day-app.access.log main;
error_log /data/logs/error.log error;
}
location 语法
location [=|~|~*|^~] /uri/ {… }
nginx内置很多参数, 如$host , $remote_addr, $http_cookie 等等
如我们可以通过获取$http_cookie参数, 通过cookie区分不同环境实现灰度发布功能
location / {
set $root_path "/home/web/prod";
set $flag "";
if ($http_cookie ~* "app-env=(.+?)(?=;|$)") {
set $flag $1;
}
if ($flag = "env-gray"){
set $root_path "/home/web/gray";
}
root $root_path;
index index.html index.htm;
}
stream模块
nginx从1.9.0开始,新增加了一个stream模块,用来实现四层协议的转发、代理或者负载均衡等, 用法和http模块一样
# 使用stream反向代理mysql
stream {
upstream mysql {
server 192.168.1.100:3306 weight=5 max_fails=3 fail_timeout=60s;
server 192.168.1.101:3306 weight=5 max_fails=3 fail_timeout=60s;
}
server {
listen 3306;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffer_size 256k;
proxy_pass mysql;
}
}