…
Nginx IO 多路复用技术。
CPU 亲和:每个进程绑定一个核心,减少Cache Miss。
Sendfile:Httpd要将静态文件从内核空间传输到用户空间再转义到内核空间Socket。而Sendfile只在内核中传输,实现零拷贝。对于静态网站速度快。
压测工具:
IO 多路复用 单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力。Linux 系统下的IO操作分为:阻塞IO
,非阻塞IO
,IO多路复用
,信号驱动IO
,异步IO
。其中IO多路复用
又分为Epoll
,Select
,Poll
。Windows下则使用IOCP
技术。
Select Epoll:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <sys/select.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) ;int pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) ;void FD_CLR (int fd, fd_set *set ) ;int FD_ISSET (int fd, fd_set *set ) ;void FD_SET (int fd, fd_set *set ) ;void FD_ZERO (fd_set *set ) ;
Select 有数量限制,而Epoll没有限制。Select阻塞等待记录就绪的文件描述符,并上报应用程序。Nginx采用Epoll。
1 2 3 4 #include <sys/epoll.h> int epoll_create (int size) ;int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event) ;int epoll_wait (int epfd, struct epoll_event * events, int maxevents, int timeout) ;
Nginx 目录 日志轮转/etc/logrotate.d/nginx
配置文件
/etc/nginx
/etc/nginx/nginx.conf
启动载入
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
旧版默认载入的网站
/etc/nginx/sites-enabled/default
新版默认载入的网站
CGI 配置
/etc/nginx/fastcgi_params
PHP
/etc/nginx/uwsgi_params
/etc/nginx/scgi_params
编码转化映射
/etc/nginx/koi-utf
/etc/nginx/koi-wih
/etc/nginx/win-utf
Mime Types
模块
/usr/lib64/nginx/modules
/etc/nginx/modules
命令
/usr/sbin/nginx
/usr/sbin/nginx-debug
帮助
缓存
日志
Nginx 变量 主要分为三类:HTTP请求响应变量,Nginx内置变量,自定义变量
1 2 3 4 5 6 7 8 9 10 11 12 13 $remote_addr $remote_user $time_local $request $status $http_user_agent $http_HEADER 请求头$send_http_HEADER 响应头
Nginx 目录匹配 location 匹配:
=
精确匹配,一旦匹配成功,停止搜索
^~
前缀匹配,一旦匹配成功,停止搜索
~
正则匹配,区分大小写
~*
正则匹配,不区分大小写
Rewrite:可以实现对url重写和重定向。使用正则表达式。用于访问跳转,SEO优化,后台维护,流量转发,伪静态。该功能依赖于 rewrite
模块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 location [=|~|~*|^~|@] /uri/ { ... } locaton / { rewrite ^(.*)$ /test/$1 break ; } locaton /test { root /var/www/html; try_files $uri @java_page ; } location @java_page { proxy_pass http://127.0.0.1:8080; } locaton /code/ { root /var/www/html/; } location /code { alias /var/www/html; } if($http_user_agent ~* Chrome) { rewrite ~(.*)$ /chrome/$1 break ; } rewrite ^(.*)$ /pages/maintain.html break ;location ~ \.jsp$ { proxy_pass http://mystream; include proxy_params; }
常用正则表达式:
^
匹配开始
$
匹配结束
~
区分大小写
~*
不区分大小写
!
不匹配
.
匹配除换行符之外的字符
?
0/1 次匹配
+
>=1 次匹配
*
任意次匹配
|
或操作
\d
匹配数字
{n}
重复n次
{n,}
重复n次或更多次
[c]
匹配字符c
[a-z]
匹配a-z
\
转义字符
()
提取内容,放到 $1 $2 中
Nginx 配置文件 /etc/nginx/nginx.conf
1 2 3 nginx -t -c /etc/nginx/nginx.conf nginx -s reload -c /etc/nginx/nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 user www-data;worker_processes auto;pid /run/nginx.pid;include /etc/nginx/modules-enabled/*.conf ;error_log /var/log/nginx/error .log warn ;events { worker_connections 768 ; } http { sendfile on ; tcp_nopush on ; tcp_nodelay on ; keepalive_timeout 65 ; types_hash_max_size 2048 ; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error .log; log_format main '$header_user_agent ' '$remote_addr - $remote_user ' include /etc/nginx/conf.d/*.conf ; include /etc/nginx/sites-enabled/*; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 server { listen 80 ; listen [::]:80 ; server_name example.com; root /var/www/example.com; index index.html; location / { root /var/www/example.com; index index.html index.htm; try_files $uri $uri / =404 ; } error_page 404 /404 .html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/example.com; } location ~ \.php$ { proxy_pass http://127.0.0.1; } }
Nginx 模块 分为:官方模块,第三方模块。
log_format 日志格式
stub_status Nginx 状态信息
random_index 返回随机页面
sub 替换HTTP内容
limit_conn 限制连接数量
limit_req 限制请求数量
access 基于IP的访问控制
auth_basic 用户登录控制
sendfile sendfile方式,加快读取速率
tcp_nopush 提高传输效率
tcp_nodelay 提高实时率
gzip 压缩
add_header 添加头字段
valid_referers 修改referer
proxy_pass 代理
upstream 负载均衡
rewrite 匹配url
格式化日志输出,支持error.log
access.log
。
语法规则:
1 2 3 Syntax: log_format name [escape=default|json] string ...; Defualt: log_format combined "..."; Context: http; # 表示只能配置在http模块下
例如:
1 2 3 4 5 6 http { ... log_format main '$header_user_agent ' '$remote_addr - $remote_user ' }
模块:stub_status
显示Nginx当前连接的信息。
语法规则:
1 2 3 Syntax: stub_status; Defualt: --; Context: server, location;
例如:
1 2 3 4 5 6 7 server { ... location /status { stub_status; } }
输出说明:
当前Nginx活跃的连接数;
握手总次数,总连接数,总请求数;
读写等的连接数。
模块:random_index
目录中随机选取一个文件作为主页,但是隐藏文件不会被选中。
语法规则:
1 2 3 Syntax: random_index on|off; Defualt: random_index off; Context: location;
例如:
1 2 3 4 5 6 7 8 server { ... location / { random_index on ; root /var/www/html/html_set } }
模块:sub
用于替换HTTP内容。
语法规则(替换字符串):
1 2 3 Syntax: sub_filter old_string new_string; Defualt: --; Context: http, server, location;
语法规则(判断页面是否有更新):
1 2 3 Syntax: sub_filter_last_modified on|off; Defualt: sub_filter_last_modified off; Context: http, server, location;
语法规则(匹配字符串,只匹配第一个,还是匹配所有):
1 2 3 Syntax: sub_filter_once on|off; Defualt: sub_filter_once off; Context: http, server, location;
例如:
1 2 3 4 5 6 7 8 server { ... location / { root /var/www/html/html_set index index.html sub_filter 'server' 'first_server' } }
模块:limit_conn
限制连接频率(完成三次握手后,建立连接)。
语法规则:
1 2 3 4 5 6 Syntax: limit_conn_zone key zone=name:size; Defualt: --; Context: http; # key 表示依据的变量,例如依据 $remote_addr 进行限制 # zone 空间名字 # size 空间大小
语法规则:
1 2 3 4 5 Syntax: limit_conn zone number; Defualt: --; Context: http, server, location; # 根据上一条定义的 zone 使用 # number 限制的个数
例如:
1 2 3 4 5 6 7 8 9 10 11 http { limit_conn_zone $binanry_remote_addr zone=my_zone:1m ; ... server { ... location / { ... limit_conn my_zone 3 ; } } }
模块:limit_req
限制请求频率(一次连接可以有多次请求,如果开启Keep-alive)。
语法规则:
1 2 3 4 5 6 7 Syntax: limit_req_zone key zone=name:size rate=rate; Defualt: --; Context: http; # key 表示依据的变量,例如依据 $remote_addr 进行限制 # zone 空间名字 # size 空间大小 # rate 以秒为单位的请求速率
语法规则:
1 2 3 4 Syntax: limit_conn zone=name [burst=number] [nodelay]; Defualt: --; Context: http, server, location; # burst 请求个数:对客户端限制速率,延迟返回
例如:
1 2 3 4 5 6 7 8 9 10 11 http { limit_req_zone $binanry_remote_addr zone=my_zone:1m rate=1r/s; ... server { ... location / { ... limit_req my_zone 3 ; } } }
模块:access
基于IP $remote_addr
的访问控制,不推荐使用,因为在使用CDN情况下会失效。如果使用
可以尝试使用http_x_forward_for
,但是不安全。
可以使用geo
模块。
可以自定义HTTP变量
传递。
语法规则:
1 2 3 Syntax: allow address|CIDR|unix:|all; Defualt: --; Context: http, server, location, limit_except;
语法规则:
1 2 3 Syntax: deny address|CIDR|unix:|all; Defualt: --; Context: http, server, location, limit_except;
例如:
1 2 3 4 5 6 7 8 server { ... location ~ ^/admin.html { ... deny ...; allow all; } }
模块:auth_basic
基于用户的信任登录。
语法规则:
1 2 3 Syntax: auth_basic string|off; Defualt: auth_basic off; Context: http, server, location, limit_except;
语法规则(认证用的用户信息文件):
1 2 3 4 5 Syntax: auth_basic_user_file file; Defualt: --; Context: http, server, location, limit_except; # 认证文件格式 # 用户名:密码:注释
例如:
1 2 3 4 5 6 7 8 server { ... location ~ ^/admin.html { ... auth_basic "Input your password." ; auth_basic_user_file /etc/nginx/auth/auth_a; } }
模块:sendfile
用于快速请求文件返回到客户端,其原理是利用sendfile技术,让内核直接读取文件,并通过网络发送出去,省去与用户空间的数据传输。
语法规则:
1 2 3 Syntax: sendfile on|off; Defualt: sendfile off; Context: http, server, location, if in location;
模块:tcp_nopush
在sendfile开启的情况下,提高网络包传输效率。多个数据包整合发送。
语法规则:
1 2 3 Syntax: tcp_nopush on|off; Defualt: tcp_nopush off; Context: http, server, location;
模块:tcp_nodelay
在keepalive开启的情况下,提高网络实时性。
语法规则:
1 2 3 Syntax: tcp_nodelay on|off; Defualt: tcp_nodelay off; Context: http, server, location;
模块:gzip
压缩传输。其他模块包含:
http_gzip_static_module 使用预压缩直接传输
http_gunzip_module 不支持gzip时,使用gunzip
语法规则:
1 2 3 Syntax: gzip on|off; Defualt: gzip off; Context: http, server, location, if in location;
语法规则(压缩比):
1 2 3 Syntax: gzip_comp_level level; Defualt: gzip_comp_level 1; Context: http, server, location;
语法规则(版本):
1 2 3 Syntax: gzip_http_version 1.0|1.1; Defualt: gzip_http_version 1.1; Context: http, server, location;
语法规则(文件类型):
1 2 3 Syntax: gzip_type type; Defualt: --; Context: http, server, location;
例如:
1 2 3 4 5 6 7 8 9 10 server { ... location ~ .*\.(jpg|gif|png)$ { gzip_on; gzip_http_version 1 .1 ; gzip_comp_level 2 ; gzip_type text/plain application/javascript text/css image/jpeg image/gif image/png; root /var/www/html/static; } }
MIME type 列表参考地址
添加头。
语法规则:
1 2 3 Syntax: add_header name value [always]; Defualt: --; Context: http, server, location, if in location;
HTTP Headers 参考文档
模块:valid_referers
用于防盗链。
语法规则:
1 2 3 Syntax: valid_referes none|blocked|server_names|string ...; Defualt: --; Context: server, location;
模块:proxy_pass
用于代理。可以实现正向代理,反向代理,负载均衡等。
语法规则:
1 2 3 Syntax: proxy_pass uri; Defualt: --; Context: location, if in location, limit_except;
语法规则(头信息):
1 2 3 Syntax: proxy_set_header field value; Defualt: proxy_set_header Host $proxy_host; proxy_set_header Connection close; Context: http, server, location;
语法规则(跳转重定向):
1 2 3 Syntax: proxy_redirect default|off|(redirect replacement); Defualt: proxy_redirect default; Context: http, server, location;
语法规则(超时):
1 2 3 Syntax: proxy_connect_timeout time; Defualt: proxy_connect_timeout 60s; Context: http, server, location;
语法规则(缓冲区,一次性加载完毕再转发):
1 2 3 Syntax: proxy_buffering on|off; Defualt: proxy_buffering off; Context: http, server, location;
参考文档
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 server { ... location / { proxy_pass http://localhost:8080; proxy_redirect default; proxy_set_header Host $http_host ; proxy_set_header X-Real-IP $remote_addr ; proxy_connect_timeout 30 ; proxy_send_timeout 60 ; proxy_read_timeout 60 ; proxy_buffering on ; proxy_buffer_size 32k ; proxy_buffers 4 128k ; proxy_busy_buffers_size 256k ; proxy_max_temp_file_size 256k ; } }
模块:upstream
负载均衡。
语法规则:
1 2 3 Syntax: upstream name {...}; Defualt: --; Context: http;
其他选项:
down 暂不参与负载均衡
backup 作为备份服务器
max_fails 允许失败次数
fail_timeout 达到max_fails后服务暂停时间
max_conns 最大连接数
调度算法:
轮询
加权轮询
ip_hash
least_conn
url_hash
hash关键数值 hash自定义key
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 http { ... upstream mystream1 { server xx.xx.xx.xx:8001 weight=5 ; server xx.xx.xx.xx:8002 ; server unix:/tep/backend; server xx.xx.xx.xx:8003 backup; server xx.xx.xx.xx:8004 backup; } upstream mystream2 { ip_hash; server xx.xx.xx.xx:8001 ; server xx.xx.xx.xx:8002 ; } upstream mystream3 { hash $request_uri ; server xx.xx.xx.xx:8001 ; server xx.xx.xx.xx:8002 ; } }
模块:rewrite
用于匹配URL。
语法规则:
1 2 3 Syntax: rewrite regex replacement [flag]; Defualt: --; Context: server, location, if;
flag可以是:
break 停止rewrite匹配,直接在root
指定的目录下查找,未找到则返回404
last 停止rewrite匹配,新建一个请求,再请求一次服务器
redirect 返回302临时重定向
permanent 返回301永久重定向,只要用户有缓存就会重定向
1 2 3 4 root /var/www/html location ~ ^/last { rewrite ^/last /test/ last; }
优先级为:
http
server
location
location 内部的规则
模块:security_link
用于防盗链。通过前后端加密传输防止盗链。例如客户端下载文件,服务端会生成带md5串和时间戳的链接返回给客户端,客户端再请求下载地址。
语法规则:
1 2 3 Syntax: security_link expression; Defualt: --; Context: http, server, location;
语法规则:
1 2 3 Syntax: security_link_md5 expression; Defualt: --; Context: http, server, location;
例如:
1 2 3 4 location / { security_link $arg_md5 , $arg_expires ; security_link_md5 "$security_link_expires $uri " ; }
模块:geoip
(默认不安装)
解析IP的地域。基于IP地址匹配MaxMind GEOIP
二进制文件得到地域信息。
包括的变量有:
$geoip_country_code
$geoip_country_name
$geoip_city
例如:
1 2 3 4 5 6 7 8 9 10 11 12 http { geoip_country /etc/nginx/geoip/GeoIP.dat; geoio_city /etc/nginx/geoip/GeoLiteCity.dat; server { ... location / { if ($geoip_country_code != CN){ return 403 ; } } } }
配置案例 访问控制 原理:利用http_x_forward_for
限制来访客户端。
1 2 3 4 5 6 7 8 9 10 server { ... location / { if($http_x_forward_for !~* "^xx\.xx\.xx\.xx") { return 403 ; } root /var/www/html; index index.html index.htm; } }
使用跨域限制 原理:在HTTP头部使用Access-Control-Allow-Origin
,限制前端跨域访问的域。
1 2 3 4 5 6 7 8 server { ... location ~ .*\.(htm|html)$ { add_header Access-Control-Allow-Origin http://localhost; add_header Access-Control-Allow-Method GET, POST, PUT, DELETE, OPTIONS; root /var/www/html; } }
防盗链 原理:在HTTP头部使用Referer
,防止盗链。
1 2 3 4 5 6 7 8 9 10 server { ... location ~ .*\.(htm|html)$ { valid_referers none blocked xx.xx.xx.xx; if($invalid_referer){ // 非0,表示被限制了 return 403 ; } root /var/www/html; } }
代理 可以代理HTTP,HTTPS,邮件,RTMP等,既可以正向代理,也可以反向代理。
反向代理:
1 2 3 4 5 6 server { ... location / { proxy_pass http://localhost:8080; } }
正向代理:
1 2 3 4 5 6 7 server { ... resolver 8.8.8.8 ; location / { proxy_pass http://$http_host $request_uri ; } }
然后配置浏览器配置代理服务器。
负载均衡 按照范围分为:GSLB(全国范围),SLB(地域范围)。
按照OSI模型分类分为:4层负载均衡(TCP/IP),7层负载均衡(应用层)。
配置 Upstream:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 http { ... upstream mystream { server xx.xx.xx.xx:8001 ; server xx.xx.xx.xx:8002 ; server xx.xx.xx.xx:8003 ; } server { ... location / { proxy_pass http://mystream; include proxy_params; } } }
HTTPS 首先生成CA证书:
生成密钥;
根据密钥生成证书签名的请求文件CSR;
将密钥,CSR打包发送给签名机构,进行CA签名,得到CA证书。1 2 3 4 5 6 openssl genrsa -out first.key 1024 openssl req -new -key first.key -out first.csr openssl x509 -req -days 3650 -in first.csr -signkey first.key -out first.crt
也可以直接到腾讯云上申请免费SSL认证。申请通过后,服务器直接返回CSR请求文件
,CRT证书
,私钥
。
配置Nginx SSL服务。
1 2 3 4 5 6 server { listen 443 ; ssl on ; ssl_certificate /etc/nginx/ssl_key/first.crt; ssl_certificate_key /etc/nginx/ssl_key/first.key; }
Tomcat 1 2 3 4 5 6 7 8 9 10 11 12 13 http { ... upstream java_api { server xx.xx.xx.xx:8080 ; } server { location ~ \.jsp$ { proxy_pass http://mystream; include proxy_params; } } }
Django 项目目录:
project
app1/
project/
manage.py
project_wsgi.ini
安装运行uwsgi:
1 2 sudo pip install uwsgi uwsgi --http :8001 --chdir /django/project/path/ --wsgi-file project.wsgi
注:Windows下需要自行下载源码编译,使用MinGW编译。
通过配置文件project_wsgi.ini
启动uwsgi:
1 2 3 4 5 6 7 [uwsgi] socket = :9090 chdir = /django/project/pathmodule = project.wsgi master = true processes = 4 vacuum = true
启用配置:
修改Nginx配置:
1 2 3 4 5 6 server { location / { uwsgi_pass xx.xx.xx.xx:port; include uwsgi_params; } }
PHP 默认使用fastcgi
调用PHP。
1 2 3 4 5 6 7 8 9 server { ... location ~ \.php$ { fastcgi_pass 127.0.0.1:9000 ; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root $fastcgi_script_name ; include fastcgi_params; } }