nginx安装
centos7安装nginx
nginx的常见命令
查看版本:nginx -v
启动:nginx
立即关闭:nginx -s stop
处理完请求后关闭:nginx -s quit
检查配置:nginx -t
输出配置:nginx -T
重新加载配置:nginx -s reload
nginx配置文件
默认配置文件位置:/usr/local/nginx/conf/nginx.conf
配置文件分成3大块
- main 全局配置,对全局生效
- events 配置影响 Nginx 服务器与用户的网络连接
- http 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
- server 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
- location 配置虚拟主机内请求地址应该映射到哪里
- upstream 用于被代理服务器有多个并且需要负载均衡的情况
- types
下面是nginx的配置文件例子
配置大全
- main 全局配置,对全局生效
- worker_processes_number worker进程的数量,一般1个或者等于cpu线程数量,可以指定为auto
- user 指定nginx允许worker进程的用户和用户组
- pid 指定进程id存放位置
- worker_rlimit_nofile_number 指定每个worker子进程最大文件句柄数
nginx作为静态资源服务器的时候每个连接都会对应一个磁盘文件,这时候worker_rlimit_nofile_number 不应该小于worker_connections的一半,并且这个值不应该大于linux ulimit -n指定的单进程文件限制。 - worker_rlimit_core 指定 worker 子进程异常终止后的 core 文件,用于记录分析问题。
- worker_cpu_affinity cpu亲和力,把cpu和worker进程绑定
将每个 worker 子进程与特定 CPU 物理核心绑定,优势在于,避免同一个 worker 子进程在不同的 CPU 核心上切换,缓存失效,降低性能。但其并不能真正的避免进程切换。
- worker_priority 设置worker线程优先级偏量-20到+19,越小优先级越高
- worker_shutdown_timeout 优雅关闭等待时间
- timer_resolution worker程和操作系统的对时精度,
调整时间间隔越大,系统调用越少,有利于性能提升;反之,系统调用越多,性能下降。
- daemon 指定 Nginx 的运行方式,前台还是后台,一般都是后台
- events 配置影响 Nginx 服务器与用户的网络连接
- use Nginx使用何种事件驱动模型
method 可选值为:select、poll、kqueue、epoll、/dev/poll、eventport
- worker_connections worker子进程能够处理的最大并发连接数。
受到 worker_rlimit_nofile_number 和 操作系统 ulimit -n限制
- accept_mutex 是否打开负载均衡互斥锁
- http 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
- server 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
- server_name 指定虚拟主机域名
server-name可以使用通配符
域名匹配的四种写法:
- 精确匹配: server_name http://www.nginx.com ;
- 左侧通配: server_name *. http://nginx.com ;
- 右侧通配: server_name www.nginx.* ;
- 正则匹配: server_name ~^www.nginx.*$ ; # ~是正则标记,^和$示开始结束标记
匹配优先级:精确匹配 > 左侧通配符匹配 > 右侧通配符匹配 > 正则表达式匹配
- location 配置虚拟主机内请求地址应该映射到哪里
- root 指定静态资源目录位置,它可以写在 http 、 server 、 location 等配置中
- alias
alias 和 root 的区别 在于alias时替换(不会加上匹配部分),root指定根目录(会加上匹配部分)
- proxy_pass 代理地址
proxy_pass 地址后面的 斜杆很关键,类似alias 和 root 的区别
- add_header 添加或者修改响应头
效果
- return 停止处理请求,直接返回响应码或重定向到其他 URL ;执行 return 指令后, location 中后续指令将不会被执行。
- rewrite 根据指定正则表达式匹配规则,重写 URL ,重写适用于复杂的转发场景,如果用到重写可以反过来思考设计是否合理,rewrite可使用ngixn内置变量,文档末尾有总结
flag 可选值的含义:
- last 重写后的 URL 发起新请求,再次进入 server 段,重试 location 的中的匹配;
- break 直接使用重写后的 URL ,不再匹配其它 location 中语句;
- redirect 返回302临时重定向;
- permanent 返回301永久重定向;
rewrite 例子
- if 指令,if可使用ngixn内置变量,文档末尾有总结
condition 判断条件:
- $variable 仅为变量时,值为空或以0开头字符串都会被当做 false 处理;
- = 或 != 相等或不等;
- ~ 正则匹配;
- ! ~ 非正则匹配;
- ~* 正则匹配,不区分大小写;
- -f 或 ! -f 检测文件存在或不存在;
- -d 或 ! -d 检测目录存在或不存在;
- -e 或 ! -e 检测文件、目录、符号链接等存在或不存在;
- -x 或 ! -x 检测文件可以执行或不可执行;
if例子
- autoindex 自动生成首页,用于ngxin作为文件服务器(映射指定硬盘目录)
效果
- upstream 用于被代理服务器有多个并且需要负载均衡的情况
- server 定义上游服务器地址;
parameters 可选值:
- weight=number 权重值,默认为1;
- backup 备份服务器,仅当其他服务器都不可用时才会启用;
- down 标记服务器长期不可用,离线维护;
- max_conns=number 上游服务器的最大并发连接数;
- fail_timeout=time 服务器不可用的判定时间;
- max_fails=numer 服务器不可用的检查次数,超过一定次数以后nginx会自动剔除这个子服务器
- keepalive 对上游服务启用长连接;
- keepalive_requests 一个长连接可以有多少个请求 HTTP请求;
- keepalive_timeout 空闲情形下,一个长连接的超时时长;
- 指定负载均衡算法可有下面值
- hash
- ip_hash
- least_conn
- least_time
- random
部分配置详解和示例
main配置
worker_processes
nginx工作时候work进程数量,nginx默认是一个master process,一个 work process,work process默认是1,可以设置为和cpu线程数想等,master接受请求,然后worker通过争抢的方式获取转发任务。每个worker是一个独立进程,他们可以部分重启(reload 的时候,不停机更新配置),如果单个worker异常退出不影响别的worker正常工作。
events配置
worker_connections
单个work porcess 可以允许同时建立外部连接的数量,默认1024,可以设置的很大
worker_connections的值和两个因素有关,一是内存,二是操作系统允许进程试用的最大文件数
- 内存
每个连接数分别对应一个read_event、一个write_event事件,一个连接数大概占用232字节,2个事件总占用96字节,那么一个连接总共占用328字节,通过数学公式可以算出100000个连接数大概会占用 31M = 100000 * 328 / 1024 / 1024,当然这只是nginx启动时,connections连接数所占用的nginx。 - 进程最大可打开文件数
进程最大可打开文件数受限于操作系统,可通过 ulimit -n 命令查询,以前是1024(centos 7 默认是 1024),现在是65535。
nginx提供了worker_rlimit_nofile指令,这是除了ulimit的一种设置可用的描述符的方式。 该指令与使用ulimit对用户的设置是同样的效果。此指令的值将覆盖ulimit的值,如:worker_rlimit_nofile 20960。
nginx一个请求占用2个或者4个链接(如果是反向2代理就是4个,作为静态资源服务器就是2个)。
如果ngixn配置为worker_processes=1,worker_connections=1024,用它做反向代理服务器最多只能同时承受256个请求。
http配置
server配置例子
location配置例举
location 配置 proxy_pass 以后 root 无效。
location 转发规则
- = 精确匹配
- 前缀匹配
/
通用匹配,任何请求都会匹配到
proxy-pass 地址后面的/:proxy_pass http://192.168.100.6;地址后面没有 / 所以匹配部分会附加到转发地址后面,如果有/结尾那么匹配部分就不会附加到转发地址后面。
匹配地址后面的/: (/log )没有/,匹配的时候优先找按照目录查找,如果有就查询下面的index.html文件,如果没j有找/log文件。(/log/)有/,匹配的时候只会按照目录查找,不考虑/log文件。
- ^~ 前缀匹配;和/的前缀匹配类似,感觉就是把 ^~ 省略了
- 正则匹配
- ~ 开头表示区分大小写的正则匹配
- ~* 开头表示不区分大小写的正则匹配
-
!~
和!~*
分别为区分大小写不匹配及不区分大小写不匹配的正则
location匹配优先级
- 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他location的匹配项
- ^~和通用匹配。使用前缀匹配,不支持正则表达式,如果有多个location匹配成功的话,不会终止匹配过程,前缀匹配会找到匹配表达式最长的那个
- 如果前缀匹配找到就不会使用正则匹配。
- 前缀匹配找不到才会使用正则匹配,继续匹配正则表达式,只要有一个正则成功,则使用这个正则的location,立即返回结果,并结束解析过程
location里面 root ,alias,proxy_pass区别
他们的区别在于要不要加上匹配的部分的地址
- root 加匹配串命中部分
如下配置,匹配部份是projectNameA,如果请求的projectNameA/a,那么实际访问的是html/projectNameA/a
root是指定根目录,匹配部分作为根目录里面的子目录
- alias 不加匹配串命中部分
如下配置,匹配部份是projectNameA,如果请求的projectNameA/a,那么实际访问的是html/a
alias的是用匹配到的部分替换 alias指定的别名部分
- proxy_pass适用于反向代理
- proxy_pass 地址后面没有/,加匹配串命中部分,和root类似
如下配置,匹配部份是projectNameA,,如果请求的projectNameA/a,那么实际访问的是http://192.168.1.6/projectNameA/a
- proxy_pass 地址后面有/, 不加匹配串命中部分,和alias类似
如下配置,匹配部份是projectNameA,,如果请求的projectNameA/a,那么实际访问的是http://192.168.1.6/a
location三个位置的/
- 匹配串的斜杆 如果不写可以精确匹配文件,如果写了只能是目录,除了精确匹配单个文件的时候,别的时候没区别
建议不写 - root,alias 映射目录后面的斜杆 ,这里的斜杆写不写几乎没区别,只有匹配串和映射目录都不写斜杆,并且在alias的情况有异常
建议写,因为alias时是直接替换,如果上面有斜杆,替换后没有地址就不对了。如果清楚alias的原理建议不写。
- proxy_pass 地址后面的斜杆
没有斜杆是子目录,有斜杆是替换,根据需要选择或者不写
检查匹配的时候可以参考nginx的logs目录下 access.log 和 error.log(路径不对的时候里面有真实访问的磁盘路径),nginx日志默认没有开启,需要手动开启。
负载均衡
nginx负载均衡策略
- random 轮询默认值 ,不写就是轮询
- weight 权重
- ip_hash 客户端ip
- url-hash(三方)
- fair(三方)
- least_conn 最小链接数
- least_time 最小响应时间
其他配置
nginx自动生成目录首页
location下面的配置 autoindex on 可以映射文件目录
nginx客户端协商缓存
用nginx作为静态资源服务器,默认就走的协商缓存,同一个资源再次访问状态码是304
多次访问http://192.168.100.66/50x.html的结果
访问日志:状态204 文件大小0
修改50x.html后再访问
nginx访问日志 200,文件大小 498
点击跳转:协商缓存过程详解
nginx客户端强制缓存
在放回的响应头指定了这个文件缓存一定时间,如果客户端浏览器是默认设置,那么指定时间内就会从客户端浏览器缓存中读取文件
通过地址点击:1.png
200 from disk cache 就是走的本地缓存,nginx访问记录里面也没有,max-age=86400 就是24h
强制缓存需要连接跳转才有小欧,如果是浏览器里面直接输入地址这样只会走协商缓存。有些时候即便没有配置强制缓存,只有协商缓存浏览器也会走强制缓存。
强制缓存服务器端没有记录,浏览器状态码是200 from disk
协商缓存服务器端有记录,浏览器状态码304,服务器不会真实的返回文件,返回的空文件
nginx代理缓存
效果类似CDN加速,nginx本地缓存了上游代理服务器的资源
下面定义了一个缓存名字是cache_zone的代理缓存,缓存目录在 /etc/nginx/cache_temp
代理缓存配置
- 定义代理缓存
- proxy_cache_path 定义缓存
注意定义代理缓存实在http下面定义的
参数含义:
- path 缓存文件的存放路径;
- level path的目录层级;
- keys_zone 设置共享内存;
- inactive 在指定时间内没有被访问,缓存会被清理,默认10分钟;
- 使用代理缓存
- proxy_cache 指定使用前面定义的代理缓存的名字,可以在 http,server,location三个级别使用
- proxy_cache_key 缓存key,命中缓存的标致,一般都是资源的uri
- proxy_cache_valid 指定什么状态的返回值才会被缓存(一般成功的我们才会缓存)
- proxy_no_cache 那些东西不缓存,proxy_cache 指定当前于开启缓存,proxy_no_cache 排除部分资源。
- proxy_cache_bypass 指定符合条件的就穿透缓存,不符合的就从缓存取
- $upstream_cache_status 变量
它存储了缓存是否命中的信息,会设置在响应头信息中,在调试中非常有用。
nginx黑白名单
可以指定ip指定资源是否能被访问,被拒绝的显示403 Forbidden
配置例子
nginx文件包含
nginx.conf文件
被包含文件
vhost/order.lomi.com.conf
nginx设置http证书
nginx日志文件位置
nginx代理前端页面跨域问题(CORS)
出现原因是前后端分离以后前端页面在一个域名A,然后后端接口放在另外一个域名B下面
- nginx解决方案1:ngixn接受域名A和域名B的请求,然后分别转发给前端页面和后端接口服务器,这时候浏览器请求的都是nginx服务对应的域名,浏览器不会识别为跨域。
- nginx决绝方案2:接口服务的转发过程中,添加响应头允许前端域名跨域。
- 解决办法3,:直接在接口程序那边加上允许指定前端页面跨域的响应头,这种办法不是很好,因为开发者不一定能确定后期部署时候前面页面允许跨域的域名。允许所有跨域只能出现在测试环境,或者说就不应该出现。
后端允许跨域参考
nginx内置变量
请求地址: http://192.168.100.66/showVar?a=1&b=2 本机IP: 192.168.1.6,
网关IP:192.168.100.1
在nginx配置类似下面的方式观察输出
location = /showVar {
return 200 "args = $args"
}
变量 | 例子 | 解析 |
$args | a=1&b=2 | |
$arg_pid | ||
$is_args | ? | |
$query_string | a=1&b=2 | 请求参数 |
$host | 192.168.100.66 | 主机地址 |
$scheme | http | 协议 |
$limit_rate | 0 | 需要nginx服务器配置limit_rate才能小时网络速率 |
$connection | 1 | |
$binary_remote_addr | 二进制数据 | |
$content_length | 响应内容长度(直接返回的纯文本,正常页面应该有长度) | |
$content_type | 响应内容类型(直接返回的纯文本,正常页面应该有类型) | |
$document_uri | /showVar | |
$document_root | /usr/local/nginx/html | 映射的文件夹 |
$http_user_agent | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 | 客户端代理 |
$http_cookie | cookie | |
$http_x_forwarded_for | forward来源 | |
$http_referer | ||
$http_via | ||
$https | ||
$remote_addr | 192.168.100.1 | 客户端公网ip(实际返回的网关IP) |
$remote_user | ||
$remote_port | 11681 | |
$request_body_file | 请求体文件 | |
$request_method | GET | 请求方式 |
$request_filename | /usr/local/nginx/html/showVar | 请求映射的文件目录 |
$request_length | 444 | 请求大小 |
$request_uri | /showVar?a=1&b=2 | 请求uri |
$request_time | 0.000 | 请求时间 |
$server_addr | 192.168.100.66 | 服务器IP |
$server_name | localhost | 服务器名 |
$server_port | 80 | 服务器端口 |
$server_protocol | HTTP/1.1 | 协议版本 |
nginx单节点故障问题
可以通过keepalived+vip来解决
keepalived+VIP 解决nginx单机故障