目录
nginx 基础命令
1 2
| nginx -t // 检查配置文件 查看当前nginx 配置路径 nginx -s reload // 重载nginx配置文件
|
nginx location 路由规则
1
| location [=|~|~*|^~|@] pattern { ... }
|
1 2 3 4 5
| = : 表示精确匹配后面的url ~ : 表示正则匹配,但是区分大小写 ~* : 正则匹配,不区分大小写 ^~ : 表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录 @ : "@" 定义一个命名的 location,使用在内部定向时,例如 error_page
|
demo 后缀名匹配
1 2 3
| location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css|woff|ttf|map|woff2|json|manifest|svg|eot)$ { root /Users/sunqixiong/project/crm-cerm/ecrm-mobile/www; }
|
就是正则匹配,其中.*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css|woff|ttf|map|woff2|json|manifest|svg|eot)$
就是一串匹配后缀名的正则表达式
demo2匹配规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| location = /world { return 600; }
location = /hello { return 600; }
location ~ /hellowo { return 602; }
location ^~ /hello { return 601; }
|
1 2 3 4 5 6 7 8
| - 请求 localhost/world 返回600 - 请求 localhost/world2 localhost/test/world 返回其他 - 请求 localhost/hello 返回600 - 请求 localhost/hello/123 返回601 - 请求 localhost/hellow 返回601 - 请求 localhost/hellowo 返回601 - 请求 localhost/test/hellowo 返回602 - 请求 localhost/test/hello 返回其他
|
- = 是精确完整匹配, 且优秀最高
- 匹配时,如果 ~ 和 ^~ 同时匹配规则,则 ^~ 优先
- ^~ 这个不会匹配请求url中后面的路径, 如上面的 /test/hello 没有匹配上
- ^~ 不支持正则,和=相比,范围更广, hellowo 是可以被^~匹配,但是 = 不会匹配
- ~ 路径中只要包含就可以匹配,如上面的 /test/hellowo 返回了602
demo3匹配顺序
1 2 3 4 5 6 7
| location ~ /hello { return 602; }
location ~ /helloworld { return 601; }
|
1 2
| - 请求 localhost/world/helloworld 返回 602 - 请求 localhost/helloworld 返回 602
|
1 2 3 4 5 6 7
| location ~ /helloworld { return 601; }
location ~ /hello { return 602; }
|
1 2 3
| - 请求 localhost/helloworld 返回601 - 请求 localhost/world/helloworld 返回601 - 请求 localhost/helloWorld 返回602
|
所以同时正则匹配时
- 放在前面的优先匹配
- 注意如果不区分大小写时,使用~*
- 尽量将精确匹配的放在前面
demo4无符号匹配
1 2 3 4 5 6 7
| location ^~ /hello/ { return 601; }
location /hello/world { return 602; }
|
1 2 3 4
| - http://localhost/hello/wor 返回601 - http://localhost/hello/world 返回602 - http://localhost/hello/world23 返回602 - http://localhost/hello/world/123 返回602
|
nginx编译安装
首先下载依赖包
nginx,penSSL、PCRE、zlib
1
| mv openssl-1.1.0g pcre-8.41 zlib-1.2.11 /usr/local/bin
|
执行配置命令,几个依赖包的路径对就可以,官方文档提示要写到一行
1
| ./configure --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre=../pcre-8.00 --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.1.0k
|
编译
之后安装
配置nginx 环境变量
1
| ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx(做软链,添加到环境变量)
|
然后就可以执行 nginx -v
看依赖了
如何使用命令查看一次http请求
1
| curl -v http://www.baidu.com >/dev/null
|
nginx 日志
error.log
错误日志的存放位置 级别,放在最外面
1
| error_log /usr/local/etc/nginx/log/error.log warn;
|
access.log
首先第一条 log_format要放在 http之下,其次后面的main 指的是 log_format对应的名字
1 2 3
| log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
|
1
| access_log /var/log/nginx/access.log main;
|
按日期生成访问日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| user root owner; http{ log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 'zhuang tai m$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; ... server{ if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") { set $year $1; set $month $2; set $day $3; }
access_log /usr/local/etc/nginx/log/access_$year-$month-$day.log main; } }
|
有个缺点,访问日志和错误日志生成的代码只能放在server下面
还有其他的方法如编写定时sh脚本
nginx模块配置
nginx编译安装以后想要再加nginx模块只能重新配置再编译安装。
查看nginx已安装模块
nginx 大V看模块 小v看版本
查看nginx可以安装的包
进入nginx 编译安装前的包的目录
1
| cat auto/options | grep YES
|
模块介绍
- 连接频率限制
ngx_http_limit_conn_module
在nginx配置文件中的(http, server, location) 下配置
1 2 3 4 5 6 7 8 9 10 11 12
| http { limit_conn_zone $binary_remote_addr zone=addr:10m; server { ... location /download/ { limit_conn addr 1; } } }
|
- 请求频率限制
ngx_http_limit_req_module
在nginx配置文件中的(http, server, location) 下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { ... location /search/ { limit_req zone=one; } } }
|
- 基于IP的访问控制
ngx_http_access_module
1 2 3 4 5 6 7
| 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
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server { location ~ ^/index_1.html { root /usr/share/nginx/html; deny 151.19.57.60; allow all; } location ~ ^/index_2.html { root /usr/share/nginx/html; allow 151.19.57.0/24; deny all; } }
|
ngx_http_access_module 的局限性
当客户端通过代理访问时,nginx的remote_addr获取的是代理的IP
基于nginx的中间件架构
静态资源web服务
mime.type 资源的媒体类型
这玩意看起来不显眼,但是如果没了它,文件资源下载了浏览器却没法识别
1
| include /etc/nginx/mime.types;
|
sendfile 配置
1 2 3
| 语法: sendfile on | off; 默认值: sendfile off; 上下文: http,server,location,if in location
|
1 2 3 4 5
| http { sendfile on; }
|
指定是否使用sendfile系统调用来传输文件。
sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝。
所以当 Nginx 是一个静态文件服务器的时候,开启 SENDFILE 配置项能大大提高 Nginx 的性能。 但是当 Nginx 是作为一个反向代理来使用的时候,SENDFILE 则没什么用了
gzip压缩
注:开启 gzip_static on 指令需要 http_gzip_static_module 模块
1 2 3 4 5 6 7
| http { gzip on; gzip_static on; gzip_buffers 4 16k; gzip_comp_level 5; gzip_types text/plain application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; }
|
http缓存
- 先校验是否过期 Expires[http1.0]、Cache-Control(max-age)[http1.1]
- 再校验协议中etag头信息校验
- 再校验Last-Modified 头信息校验
注意:
有时候请求到的缓存文件,明明请求头没有加 cache-control
,但请求头会有 Cache-Control: max-age=0
经测试发现chrome会对html、png等格式自带,而对css、js文件不自带,这个机制很好,这是因为浏览器会自带这个请求头让服务器去检查这个文件的etag或者Last-Modified是否过期
expires(http1.0)
1 2 3 4
| location ~ .*\.(jpg|png)$ { expires 24h; root /Users/sunqixiong/Pictures; }
|
第一次请求就会返回 response
1 2
| Expires: Thu, 15 Aug 2019 07:47:54 GMT Cache-Control: max-age=86400
|
第二次请求返回304,返回 response 除了一样以外,它的request header 还是带上了 Cache-Control: max-age=0
,文件来源还是other,并没有从cache memory 来,因为它是图片chrome自带Cache-Control:max-age=0
expires(http1.1)
1 2 3 4 5 6 7 8 9 10 11 12 13
| location /zjmobile { if ($request_filename ~ .*\.(htm|html)$) { add_header Cache-Control no-cache; } if ($request_filename ~ .*\.(js|css|png|jpg|ttf|eot|svg|jpeg|woff)$) { add_header Cache-Control max-age=86400; } alias /app/app/enrollment; index index.html; try_files $uri $uri/ /index.html last; }
|
nginx 跨域访问
1 2 3 4
| add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS
|
nginx 防盗链
http_refer 上一级页面的地址
1 2 3 4 5 6
| location / { valid_referers none blocked 127.0.0.1; if($invalid_referer){ return 403; } }
|
测试防盗链接
1 2
| curl -e "http://www.baidu.com" -I http://localhost:7676/refer curl -e 127.0.0.1 -I http://localhost:7676/refer
|
nginx 代理
发向代理/正向代理
1 2 3 4 5 6 7 8
| location /zjmobile/service { proxy_pass http://tomcat_pool/zjcm/service }
location / { proxy_pass http://$http_host$request_uri }
|
常用代理的配置
1 2 3 4
| location / { proxy_pass http://127.0.0.1:8080; include proxy_params; }
|
proxy_params
注意:proxy buffer这一块具体数值,看服务器数值决定。虽然可以通用,但如果不熟悉,还是不建议使用。
1 2 3 4 5 6 7 8 9 10 11
| proxy_redirect default; proxy_set_header HOST $http_host; proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 30;
proxy_buffering on; proxy_buffer_size 32k; proxy_buffers 4 128k; proxy_busy_buffers_size 256k; proxy_max_temp_file_size 128m;
|
nginx 轮询
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
1 2 3 4 5 6
| upstream tomcats { server 10.1.1.107:88 max_fails=3 fail_timeout=3s weight=9; server 10.1.1.132:80 max_fails=3 fail_timeout=3s weight=9; server 10.1.1.137:82 backup; Server 10.1.1.136:86 backup; }
|
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session(cookie)的问题
1 2 3 4 5
| upstream tomcats { ip_hash; server 10.1.1.107:88; server 10.1.1.132:80; }
|
根据请求的$request_uri,一致的话会请求同一台服务器,这个应用场景很少
1 2 3 4 5
| upstream tomcats { hash $request_uri; server 10.1.1.107:88; server 10.1.1.132:80; }
|
nginx 变量解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $http_host --localhost:7676(域名加端口) $host --localhost(域名) $request_uri -- /zjmobile/css/app.956b573.css $http_content_type --text/css
$request_method $remote_addr $request_uri $server_port $remote_port $query_string $args $http_user_agent $server_protocol $server_addr $server_name
|
nginx缓存(代理服务器端缓存,减少后端压力,提高网站并发延时)
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| upstream node { server 192.9.191.31:8081; server 192.9.191.31:8082; } proxy_cache_path /cache levels=1:2 keys_zone=xcache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name www.test.com; index index.html; location / { proxy_pass http://node; proxy_cache xcache; proxy_cache_valid 200 304 12h; proxy_cache_valid any 10m; add_header Nginx-Cache "$upstream_cache_status"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; } }
|
1 2 3 4 5 6 7
| proxy_cache_path /soft/cache levels=1:2 keys_zone=cache:10m max_size=10g inactive=60m use_temp_path=off;
|
1 2 3 4 5 6 7 8 9 10
| proxy_cache cache; proxy_cache_valid 200 304 12h; proxy_cache_valid any 10m; add_header Nginx-Cache "$upstream_cache_status"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
注意:值得一提的是nginx代理服务器缓存,多是为了缓存服务器的资源文件,如果只是反向代理服务的话就不用配置
部分页面不缓存
某些页面如登陆注册,不能使用缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| upstream node { server 192.9.191.31:8081; server 192.9.191.31:8082; } proxy_cache_path /cache levels=1:2 keys_zone=cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name www.test.com; index index.html; if ($request_uri ~ ^/(static|login|register|password)) { set $cookie_nocache 1; } location / { proxy_pass http://node; proxy_cache cache; proxy_cache_valid 200 304 12h; proxy_cache_valid any 10m; add_header Nginx-Cache "$upstream_cache_status"; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_no_cache $cookie_nocache $arg_nocache $arg_comment; proxy_no_cache $http_pargma $http_authorization; } }
|