nginx介绍及编译安装
nginx安装 nginx: [emerg] getpwnam(“www”) failed 错误
解决方法1:
在nginx.conf中 把user nobody的注释去掉既可
解决方法2:
错误的原因是没有创建www这个用户,应该在服务器系统中添加www用户组和用户www,如下命令:
/usr/sbin/groupadd -f www/usr/sbin/useradd -g www www
常用模块
ngx_http_core_module
ngx_http_access_module
ngx_http_fastcgi_module
ngx_http_proxy_module
ngx_http_auth_basic_module
ngx_http_gzip_module
ngx_http_limit_conn_module
ngx_http_limit_req_module
ngx_http_log_module
ngx_http_rewrite_module
ngx_http_upstream_module
ngx_http_stub_status_module
ngx_http_ssl_module
常用变量
常用于输出日志文件使用
| $uri | 当前请求的uri,不带参数 |
|---|---|
| $request_uri | 请求的uri,带完整参数 |
| $host | http请求报文中host首部,如果没有则以处理此请求的虚拟主机的主机名代替 |
| $hostname | nginx服务运行在主机的主机名 |
| $remote_addr | 客户端IP |
| $remote_port | 客户端端口 |
| $remote_user | 使用用户认证时客户端用户输入的用户名 |
| $request | 请求行,GET等方法、http协议版本 |
| $request_filename | 用户请求中的URI经过本地root或alias转换后映射的本地文件路径 |
| $request_method | 请求方法,GET POST PUT |
| $server_addr | 服务器地址 |
| $server_name | 服务器名称 |
| $server_port | 服务器端口 |
| $server_protocol | 服务器向客户端发送响应时的协议,http/1.1 http/1.0 |
| $scheme | 在请求中使用scheme,如http://xxx.com中的http |
| $http_HEADER | 匹配请求报文中指定的HEADER |
| $http_host | 匹配请求报文中的host首部 |
| $http_user_agent | http头部信息,客户端访问设备 |
| $http_x_forwarded_for | http请求携带的http信息 |
| $http_referer | http上一级页面,防盗链、用户行为分析 |
| $document_root | 当前请求映射到的root配置 |
| $time_local | nginx时间 |
| $status | response返回状态码 |
| $body_bytes_sent | 服务端响应给客户端body信息大小 |
nginx信号量
信号与命令对应关系:
./sbin/nginx./sbin/nginx -s stopkill -TERM `cat logs/nginx.pid`./sbin/nginx -s reloadkill -HUP `cat logs/nginx.pid`./sbin/nginx -s reopenkill -USR1 `cat logs/nginx.pid`
nginx虚拟主机配置
配置文件
- 全局区
工作进程=CPU数*核数
- Event区
配置nginx连接的特性
- http段
配置http服务器的主要段
- Server
虚拟主机
- 监听哪个端口——port- 监听哪个域名——server_name- location 映射到对应文件夹处理- root 目录名称/绝对路径- index 默认主页
nginx日志管理
access_log logs/access.log main;
使用的格式是main格式。
main格式?
main格式是我们定义好的一种日志格式,并赋予名字,便于引用。
log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';$remote_addr $remote_user10.211.55.2 - -[$time_local][02/Feb/2020:18:59:54 +0800]$request"GET /favicon.ico HTTP/1.1"$status $body_bytes_sent404 555$http_referer"http://10.211.55.6/"$http_user_agent"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"
$http_x_forwarded_for
在经过代理时,代理把你的本来IP加在此头信息中,传输你的原始IP
针对不对的server做不同的log
只需要在对应的Server添加一条指令
#log_format mylog '$remote_addr - ...'access_log logs/newserver.access.log mylog;
nginx定时任务完成日志切割
date命令
$ date -d yesterday +%Y%m%d#更改时间$ date -s '2020-02-02 20:00:00'$ clock -w
编写脚本runlog.sh
# /bin/bashLOGPATH=/usr/local/nginx/logs/zcom.access.logBASEPATH=/data/$(date -d yesterday +%Y%m)mkdir -p $BASEPATHbak=$BASEPATH/$(date -d yesterday +%d%H%M).zcom.access.logmv $LOGPATH $baktouch $LOGPATHkill -USR1 `cat /usr/local/nginx/logs/nginx/pid`
设置定时任务
$ crontab -e# 分 时 日 月 周 命令*/1 * * * * sh /data/runlog.sh
nginx location正则匹配
Location处理逻辑
- 用uri测试所有的prefix string;
- uri精确匹配到=定义的location,使用这个location,停止搜索;
- 匹配最长prefix string,如果这个最长prefix string带有^~修饰符,使用这个location,停止搜索,否则:
- 存储这个最长匹配;
- 然后匹配正则表达式;
- 匹配到第一条正则表达式,使用这个location,停止搜索;
- 没有匹配到正则表达式,使用#4步存储的prefix string的location。
nginx rewrite语法详解
指令
if (条件){#设定条件,再进行重写}set #设置变量return #返回状态码break #跳出rewriterewrite #重写
条件怎么写?
= #判断相等,用于字符串比较~ #用正则匹配,区分大小写~* #正则匹配,不区分大小写-f -d -e 判断是否为文件、为目录、是否存在
例子
if ($remote_addr = 192.168.1.100) {return 403;}if ($http_user_agent ~ MSIE) {rewrite ^.*$ /ie.html;break;#避免循环重定向}
fastcgi运行方式:nginx把http请求变量(如get,user_agent等)转发给php进程,即php独立进程,与nginx进行通信。
编译安装,如果不知道都有什么参数,可以进行如下操作,并类推
./configure --help | grep mysql
正则匹配的反向引用$1
location /ecshop {rewrite "goods-(\d{1,7})\.html" /ecshop/goods.php?id=$1;#rewrite goods-(\d+)\.html /ecshop/goods.php?id=$1;rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d\.]+)\.html category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5}
nginx gzip
Content-Encoding: gzipAccept-Encoding: gzip,deflate
二进制文件如图片,不需要使用压缩,耗费CPU资源,压缩效果也不好。
#开启gzip压缩输出,减少网络传输。gzip on;#IE6及以前版本禁用压缩,不支持gzipgzip_disable "MSIE [1-6].";#设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。#默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大。gzip_min_length 1k;#设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。#4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存。#gzip_buffers number size;gzip_buffers 4 16k;#用于识别 http 协议的版本gzip_http_version 1.1;#gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)gzip_comp_level 6;#匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。gzip_types text/html text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;#和http头有关系,会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。gzip_vary on;#Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。gzip_proxied any;
expires缓存提升网站负载
location ~ .*.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {root /html/static;expires 7d;}
配置后,浏览器重复请求同一图片,应该不会向服务器发送请求,查看Cache-Control 与 expires 字段
查看控制台,确认是不是from cache
304 Not Modified
也是一种很好的缓存手段
原理:服务器响应文件内容时,同时响应etag标签(内容的签名,内容改变,它也改变)和last_modified_since标签。浏览器下次请求时,头信息发送这两个标签,服务器检测文件有无发生变化,如无,直接头信息返回上两个标签。浏览器知道内容未改变,于是直接调用本地缓存。这个过程请求了服务器,但是传输的内容较少,对于变化周期较短的文件如html,js,css比较适于用这个方式。
nginx实现负载均衡
upstream
#设定负载均衡后台服务器列表upstream backend {ip_hash;server 192.168.50.100:8080 max_fails=2 fail_timeout=30s;server 192.168.50.101:8080 max_fails=2 fail_timeout=30s;}location \ {proxy_pass http://backend;#反向代理导致了后端服务器的IP取代了前端服务器的真实IP,需要用header传递客户真实IP#后端的Web服务器可以通过 X-Forwared-For 获取用户真实 IPproxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;}
