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 stop
kill -TERM `cat logs/nginx.pid`
./sbin/nginx -s reload
kill -HUP `cat logs/nginx.pid`
./sbin/nginx -s reopen
kill -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_user
10.211.55.2 - -
[$time_local]
[02/Feb/2020:18:59:54 +0800]
$request
"GET /favicon.ico HTTP/1.1"
$status $body_bytes_sent
404 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/bash
LOGPATH=/usr/local/nginx/logs/zcom.access.log
BASEPATH=/data/$(date -d yesterday +%Y%m)
mkdir -p $BASEPATH
bak=$BASEPATH/$(date -d yesterday +%d%H%M).zcom.access.log
mv $LOGPATH $bak
touch $LOGPATH
kill -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 #跳出rewrite
rewrite #重写
条件怎么写?
= #判断相等,用于字符串比较
~ #用正则匹配,区分大小写
~* #正则匹配,不区分大小写
-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: gzip
Accept-Encoding: gzip,deflate
二进制文件如图片,不需要使用压缩,耗费CPU资源,压缩效果也不好。
#开启gzip压缩输出,减少网络传输。
gzip on;
#IE6及以前版本禁用压缩,不支持gzip
gzip_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 获取用户真实 IP
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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}