Nginx入门学习
一、Nginx介绍与安装
1、Nginx简介
Nginx (engine x) 是一个高性能的HTTP和反向代理的轻量级web服务器,同时也提供了IMAP/POP3/SMTP服务。由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。其他web服务器对比
Nginx有以下一些特点
-
反向代理
-
集群与负载均衡
-
动静分离(静态资源虚拟化)
-
限流
上图基本上说明了当下流行的技术架构。
2、常见特点简介
2.1 反向代理
再讲反向代理之前首先要知道什么叫正向代理,正向代理相当于当你要访问一个资源时,你需要一个代理服务器进行资源访问
反向代理,客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器的地址,隐藏了真实服务器的ip
2.2 负载均衡
简单来说,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡
2.3 动静分离
动静分离就是讲动态资源和静态资源相互分离,把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。
3、Nginx的安装
3.1 软件安装
PCRE库支持正则表达式。如果我们在配置文件nginx.conf中使用了正则表达式,那么在编译Nginx时就必须把PCRE库编译进Nginx,因为Nginx的HTTP模块需要靠它来解析正则表达式。
1 | #检测是否安装,若没有安装,则需要安装 |
安装nginx,首先需要安装相应的依赖,这里我用的是Centos操作做系统,从Nginx下载地址下载最新nginx
1 | #首先安装前置依赖 |
nginx常见配置解释如下
命令 | 解释 |
---|---|
–prefix | 指定nginx安装目录 |
–pid-path | 指向nginx的pid |
–lock-path | 锁定安装文件,防止被恶意篡改或误篡改 |
–error-log | 错误日志 |
–http-log-path | http日志 |
–with-http_gzip_static_module | 启用gzip模块,在线实时压缩输出数据流 |
–http-client-body-temp-path | 设定客户端请求的临时目录 |
–http-proxy-temp-path | 设定http代理临时目录 |
–http-fastcgi-temp-path | 设定fastcgi临时目录 |
–http-uwsgi-temp-path | 设定uwsgi临时目录 |
–http-scgi-temp-path | 设定scgi临时目录 |
1 | #自定义配置,可以自行修改 |
3.2 环境与端口配置
注意端口的开放,配置成功即可访问
1 | #查看开放的端口号 |
为了更方便启动,需要配置环境变量
1 | vim /etc/profile |
当然Nginx安装如果不想这么麻烦,可以直接在宝塔面板进行快速安装(傻瓜式安装,不过我装了有点问题,折腾了好久还是选择了安装包安装)
二、Nginx原理
1、nginx工作原理图
Nginx只有一个主线程,可以有多个worker线程,ps -ef |grep nginx
可以查看活着的线程。而多个worker可以进行热部署,而且提高了服务的可靠性,另外worker数一般和cpu核心数相等,这样能最大限度发挥性能。对于连接数worker_connection,访问静态资源占用2个(请求和返回),动态资源占用4个(另外再加上tomcat的请求)。nginx在linux默认采用epoll的io线程处理模型,采用的是==异步非阻塞==的机制来完成线程的处理,所以上面的tomcat1如果发生了阻塞,并不会影响tomcat2的执行。
-
nginx的worker工作采用的抢占式的机制
-
nginx采用的是epoll的异步非阻塞的io模型,也就是多路复用的io线程模型。
2、nginx默认配置
访问http:ip
,Nginx–>监听80端口–>找到对应server---->映射路由/----> html中的index.html
1 | # 设置worker进程的用户,指的linux中的用户,会涉及到nginx操作目录或文件的一些权限,默认为 nobody。 |
3、常见错误与进程退出
问题
在启动的过程中,如果出现了"/var/run/nginx.pid failed "错误信息的时候,一般是文件目录不存在,或者文件被误删
解决方案
- 重新创建此目录即可
1 | mkdir -p /var/run/nginx/ |
- 如果重启过程中报错如下异常,则指定nginx.conf文件进行启动和重启
1 | nginx -c /usr/local/nginx/conf/nginx.conf |
- 然后在重启启动nginx服务
1 | nginx -s reload |
Nginx退出方式
1 | # 强制关闭 |
三、Nginx常见功能
1、Location语法
1.1 基本语法
location指令语法如下:
1 | location [ = | ~ |~* |^~] uri{ |
-
= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
-
~ :用于表示 uri 包含正则表达式,并且区分大小写。
-
~ *:用于表示 uri 包含正则表达式,并且不区分大小写。
-
^~ :用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。
注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。
1 | # 服务虚拟主机配置 |
1.2 匹配顺序与匹配优先级
匹配顺序如下:
=
是精准匹配,优先级最高,如果精确匹配,那么就会停止搜索匹配并根据精确匹配的配置处理请求- 普通字符串匹配,按匹配的长度来取匹配结果,取匹配最长的。即请求
/blog/detail
,如果有location /blog
和location /blog/detail
,那么会匹配location /blog/detail
- 进行
^~
前缀匹配,如果匹配,那么就会停止匹配 - 对于正则匹配,从上到下进行匹配,如果有匹配,nginx就停止搜索其他匹配
- 通配location,如
location /
,最后兜底匹配 - (location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (location /)
- (精确匹配)> (最长字符串匹配,但完全匹配) >(非正则匹配)>(正则匹配)>(最长字符串匹配,不完全匹配)>(location通配)
优先级说明:
- 第一优先级:等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
- 第二优先级:^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
- 第三优先级:正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
- 第四优先级:常规字符串匹配类型。按前缀匹配。
1 | location = / { |
1.3 location和proxy_pass斜杠区别
1 | # ===========location斜杠=============== |
2、反向代理
首先准备两台tomcat服务器,修改端口号(有三处需要修改,文件位置在conf/server.xml),一个修改成8081,另一个8082,然后分别在Webapp中创建文件夹edu和udp并在目录下创建a.html,里面随便可以写任何东西。然后修改nginx的配置文件(文件位置在/usr/local/nginx/conf/nginx.conf) server部分如下,浏览器输入
服务器ip/udp/a.html
后就会自动访问,并不需要输入端口号。
若一个Nginx服务器需要代理多个应用,则需要创建多个server。
1 | location ~ /edu/ { |
3、负载均衡
3.1 简介
分配策略有以下几点
-
轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 -
weight
weight代表权,默认为 1, 权重越高被分配的客户端多。weight指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。可以与least_conn和ip_hash结合使用 -
ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。ip_hash不能与backup同时使用;当有服务器需要剔除,必须手动down掉。 -
least_conn
把请求转发给连接数较少的后端服务器,适合请求处理时间长短不一造成服务器过载的情况。 -
fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。 -
url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。
3.2 upstream
官网参考:http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html
- max_conns
可以限制一台服务器的最大访问连接数。默认值是:0,代表不限制。可以用来限流
1 | upstream tomcatservers { |
- down
如果用down进行服务器标记就告诉当前服务器不可用的状态,这样就可以停用8080服务
1 | upstream tomcatservers { |
- backup
backup 表示当前服务器节点是备用机,只有在其他的服务器都宕机以后,自己才会加入到集群中,被用户访问到;可以用于灰度部署时候的一种更替效果。
1 | upstream tomcatservers { |
- max_fails 和 fail_timeout
max_fails 表示失败几次,则标记server已宕机,剔出上游服务;fail_timeout 表示失败的重试时间。max_fails默认值1,fail_timeout的默认值是10
1 | upstream tomcatservers { |
3.3 简单实例
负载均衡指的是当访问相同路径的资源,nginx按照设置好的分配策略,自动进行某一个tomcat的访问,比如我直接输入服务器ip/edu/a.html
,我服务器中有两台tomcat并且同时有路径/edu/a.html,当访问时会按照固定分配策略选择一台tomcat进行服务,若其中一台挂了,另一台还可以正常工作。
1 | http{ |
4、动静分离
相当于一个静态资源服务器,通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 Expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。
我在我的文件夹data下分别创建了www和image文件夹,里面分别存放了图片和一个html,当浏览器访问时就会自动寻找对应的静态资源(expires参数也可配置),部分配置如下
1 | server{ |
alias与root的区别
-
root 实际访问文件路径会拼接URL中的路径;alias 实际访问文件路径不会拼接URL中的路径
-
在一个location中,alias可以存在多个,但是root只能有一个
-
alias只能存在与location中,但是root可以用在server、http和location中
-
alias后面必须要“/”结束,否则会找不到文件,而root的“/”可有可无
5、nginx其他情况
使用Nginx做代理的时候,有时需要把请求原封不动的转发给下一个服务。比如,访shawn.com/test/a/b.html
, 要求转发到localhost:8088/test/a/b.html
,请求只会替换域名。
简单配置如下:
1 | upstream user { |
但很多时候,我们需要根据url的前缀转发到不同的服务。比如
shawn.com/user/profile.html转发到 用户服务 localhost:8089/profile.html
shawn.com/order/details.html转发到 订单服务 localhost:8090/details.html
即,url的前缀对下游的服务是不需要的,除非下游服务添加context-path, 但很多时候我们并不喜欢加这个。如果Nginx转发的时候,把这个前缀去掉就好了。
一个种方案是proxy_pass后面加根路径 / .
1 | server { |
^~/user/
表示匹配前缀是user
的请求,proxy_pass的结尾有/
, 则会把/user/*
后面的路径直接拼接到后面,即移除user.
另一种方案是使用 rewrite
1 | upstream user { |
注意到proxy_pass结尾没有/
, rewrite
重写了url。
last 和 break关键字的区别
只用到了break,即匹配到此处后不会继续跳。
permanent 和 redirect关键字的区别
rewrite … permanent 永久性重定向,请求日志中的状态码为301
rewrite … redirect 临时重定向,请求日志中的状态码为302
另一种就是location和proxy_pass有无“/”的几种区别探究,具体可以参考
https://mp.weixin.qq.com/s/im--XoNkomtdC1wJwedTlw
四、Nginx常见配置
Nginx可视化配置:https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN
1、gzip压缩配置
1 | # 配置网络传输的模块 |
2、跨域配置与防盗链
跨域配置完若发现无效果,试试清除缓存;而防盗链配置后只允许当前域名可以访问,否则会报错
1 | # 静态资源服务器 |
3、Keepalived
3.1 简介
nginx底层是用tcp/ip完成的服务器的通信。Httpd守护进程,一般都提供了keep-alive timeout时间设置参数。比如nginx的keepalive_timeout,和Apache的KeepAliveTimeout。这个 keepalive_timout时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住 keepalive_timeout秒后,才开始关闭这个连接。
keepalived配置
1 | http { |
-
keepalive_timeout:设置keep-alive客户端连接在服务器端保持开启的超时值(默认65s);值为0会禁用keep-alive客户端连接;对于一些请求比较大的内部服务器通讯的场景,适当加大为120s或者300s;
-
keepalive_requests:设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭。默认是100。这个参数的真实含义,是指一个keep alive建立之后,nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。高QPS可以提高以减少连接TIME_WAIT时间
3.2 保持与server的长连接
为了让nginx和后端server(nginx称为upstream)之间保持长连接,同时也可以http请求组,典型设置如下。
1 | http { |
header相关可以参考:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
4、expires缓存
expires指令控制HTTP应答中的“Expires”和“Cache-Control”Header头部信息,启动控制页面缓存的作用
time可以使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定time值来设定。
time值还控制"Cache-Control"的值:
-
负数表示no-cache
-
正数或零表示max-age=time
-
epoch:指定“Expires”的值为 1 January,1970,00:00:01 GMT
-
max:指定“Expires”的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年。
-
-1:指定“Expires”的值为当前服务器时间-1s,即永远过期。
-
off:不修改“Expires”和"Cache-Control"的值
1 | location /static { |
5、日志文件分割
现有的日志都会存在 access.log以及error.log 文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维人员查看,所以我们可以通过把文件切割为多份不同的小文件作为日志,切割规则可以以 天 为单位,如果每天有几百G或者几个T的日志的话,则可以按需以 每半天 或者 每小时 对日志切割
5.1 创建脚本
创建一个shell可执行文件 cutlogs.sh
。USR1亦通常被用来告知应用程序重载配置文件;例如,向Apache HTTP服务器发送一个USR1信号将导致以下步骤的发生:停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。
1 |
|
1 | #为 cutlogs.sh 添加可执行的权限 |
5.2 创建定时任务
1 | #安装定时任务,安装过了就不需要了 |
常用定时任务命令
1 | service crond start #启动服务 |
定时任务表达式
Cron表达式是,分为5或6个域,每个域代表一个含义,定时参考:https://crontab.guru/
分 | 时 | 日 | 月 | 周几 | 年(可选) | |
---|---|---|---|---|---|---|
取值范围 | 0-59 | 0-23 | 1-31 | 1-12 | 1-7 | 2019/2020/… |
常用表达式
1 | #每分钟执行 |
五、Nginx配置高可用集群
原理如上,相信大家的水平应该都能看懂,在配置时需要一些准备工作
-
两台服务器
-
两台服务器都需要安装好Nginx
-
两台服务器需要安装keepalived
1 | #安装命令 |
安装安成后在/etc/keepalived下有配置文件,原理详看keepalived原理
主从配置(还有双主模式自行学习)
1、修改keepalived配置文件
1 | global_defs { |
2、在/usr/local/src
添加检测脚本
1 |
|
3、启动两台服务器的nginx和keepalived,其中备份机的keepalived配置需要简单修改,根据注释应该能看懂了。
注意:keepalived一般是在内网段进行,要公网服务器进行的话,需要至少三个公网ip(现阶段没这么多资金于是就没试验了),还有如果是虚拟机进行试验的话防火墙需要注意
六、Nginx配置ssl提供https访问
1、介绍与环境准备
1.1 https配置作用
HTTP (HyperText Transfer Protocol:超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息。
HTTP 默认工作在 TCP 协议 80 端口,用户访问网站 http:// 打头的都是标准 HTTP 服务。
HTTP 协议以明文方式发送内容,==不提供任何方式的数据加密,==如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTPS (Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
1.2 配置步骤
-
要有个域名,并且要有服务器(提供ip)并且服务器ip和域名要进行解析。
-
购买ssl安全证书或者免费领取一个ssl安全证书。
-
把域名和ssl安全证书进行绑定授权
-
授权成功以后,然后把证书安装到nginx中。
2、阿里云下载SSL
2.1 前提准备
-
一台服务器(ECS和轻量云服务器都可以)
-
一个域名
-
域名已经实名认证以及解析完毕
-
服务器已备案
2.2 SSL证书申请
进入阿里云平台,认领免费证书,之后进行申请签发,很快就能审核通过,下载nginx证书到本地。这里注意一个证书只能对应一个具体的域名。
3、Nginx配置https
这里只需要ssl_certificate、ssl_certificate_key
,另外配置server为443,并且将http重定向到443端口。配置完成后重启即可。
1 | # 这个服务器是http://www.itbooking.net的服务 |
注:宝塔面板可能会有问题,可能需要重装
参考:
https://www.cnblogs.com/woshimrf/p/nginx-config-location.html