Nginx
运行环境
系统:Ubuntu20.04 LTS
Nginx版本:
Nginx介绍
传统的 Web 服务器,每个客户端连接作为一个单独的进程或线程处理,需在切换任务时将 CPU 切换到新的任务并创建一个新的运行时上下文,消耗额外的内存和 CPU 时间,当并发请求增加时,服务器响应变慢,从而对性能产生负面影响。
Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持高达 5w 个并发连接数,最重要的是,Nginx 是免费的并可以商业化,配置使用也比较简单。
Nginx 的最重要的几个使用场景:
- 静态资源服务,通过本地文件系统提供服务;
- 反向代理服务,延伸出包括缓存、负载均衡等;
- API 服务,OpenResty ;
对于前端来说 Node.js 不陌生了,Nginx 和 Node.js 的很多理念类似,HTTP 服务器、事件驱动、异步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以实现,但 Nginx 和 Node.js 并不冲突,都有自己擅长的领域。Nginx 擅长于底层服务器端资源的处理(静态资源处理转发、反向代理,负载均衡等),Node.js 更擅长上层具体业务逻辑的处理,两者可以完美组合,共同助力前端开发。
作者:SHERlocked93
链接:https://juejin.cn/post/6844904144235413512
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
正向代理和反向代理
什么是代理?
代理(proxy):代理可以理解成中介,根据字意思我们也可以明白代理就是代替某人处理某事的意思。比如,我们买东西,本来可以直接去厂家购买,但是如果我们需要买很多东西就不可能一个一个厂家去买了,太过于麻烦,有头脑的人就开了超市,从厂家进货,我们直接从超市购买就可以了,当然,一般情况下,厂家也会切断直销渠道。
直接购买单人情况
直接购买复炸情况
增加代理
可以看到增加代理后逻辑清晰了许多。那么什么时候应该使用代理呢?
我把使用代理的情况分为两种:
- 多对多关系时,需要解决逻辑紊乱问题。
- 当客户端(顾客)与服务端(厂家)不能直连时,也就是厂家不能直销时。
正向代理
正向代理类似一个跳板机,代理访问外部资源
比如我们国内访问谷歌,直接访问访问不到,我们可以通过一个正向代理服务器,请求发到代理服,代理服务器能够访问谷歌,这样由代理去谷歌取到返回数据,再返回给我们,这样我们就能访问谷歌了
正向代理的用途:
(1)访问原来无法访问的资源,如google
(2) 可以做缓存,加速访问资源
(3)对客户端访问授权,上网进行认证
(4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
反向代理
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器
反向代理的作用:
(1)保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网
(2)负载均衡,通过反向代理服务器来优化网站的负载
正向代理和反向代理的区别
看图理解一:
看图理解二:
总结:
- 正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端.
反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端 - 正向代理中,proxy和client同属一个LAN,对server透明;
反向代理中,proxy和server同属一个LAN,对client透明。
实际上proxy在两种代理中做的事都是代为收发请求和响应,不过从结构上来看正好左右互换了下,所以把后出现的那种代理方式叫成了反向代理 - 正向代理: 买票的黄牛,反向代理: 租房的代理
- 一个代表的是顾客, 一个是厂家代表。
- 正向代理隐藏的是请求的客户端,反向代理隐藏的是服务器端。
负载均衡
请求爆发式增长的情况下,单个机器性能再强劲也无法满足要求了,这个时候集群的概念产生了,单个服务器解决不了的问题,可以使用多个服务器,然后将请求分发到各个服务器上,将负载分发到不同的服务器,这就是负载均衡,核心是「分摊压力」。Nginx 实现负载均衡,一般来说指的是将请求转发给服务器集群。
举个具体的例子 🌰,晚高峰乘坐地铁的时候,入站口经常会有地铁工作人员大喇叭“请走 B 口,B 口人少车空….”,这个工作人员的作用就是负载均衡。
动静分离
为了加快网站的解析速度,可以把动态页面(动态资源)和静态页面(静态资源)由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。
Nginx安装
安装之前需要确定 gcc、make、zlib、pcre、openssl已经安装。
安装编译工具及库文件
apt install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
首先要安装pcre
百度百科介绍:https://baike.baidu.com/item/PCRE/7401536?fr=aladdin
PCRE 作用是让 Nginx 支持 Rewrite 功能。
官网:http://www.pcre.org/
箭头部分都可以找到下载地址。
我们把它弄到系统中,解压:tar zxvf pcre-8.35.tar.gz
进入安装包目录cd pcre-8.35
编译安装./configure
make && make install
查看pcre版本pcre-config --version
如果需要卸载,在pcre的解压目录下,sudo make uninstall
Nginx下载安装
nginx下载地址:https://nginx.org/en/download.html
将其下载到/usr/local/src
或者/opt
目录。
- 解压安装包
tar -zxvf nginx-1.20.0.tar.gz
- 进入安装包
cd nginx-1.20.0/
- 编译安装
./configure
make && make install
- 查看nginx版本
1 | root@VM-12-10-ubuntu:/usr/local/nginx/sbin# ./nginx -v |
- 启动nginx
1 | root@VM-12-10-ubuntu:/usr/local/nginx/sbin# ./nginx |
- 浏览器直接访问 ip:80
如果无法访问,注意防火墙的配置
Nginx 操作常用命令
Nginx 的命令在控制台中输入 nginx -h 就可以看到完整的命令,这里列举几个常用的命令:
- 查看nginx 版本号
1 | nginx -v |
- 启动nginx
1 | nginx |
- 关闭nginx
1 | nginx -s stop |
- 重加载
1 | nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启 |
- 其它
1 | nginx -s reopen # 重启 Nginx |
nginx的配置
nginx的配置文件/usr/local/nginx/conf/nginx.conf
。
1 | #user nobody; |
nginx.conf 结构图可以这样概括:
1 | main # 全局配置,对全局生效 |
我们把nginx配置文件分为三部分:
- 第一部分 全局块
worker_processes 1;
值越大,可以支持的并发处理器也越多,一般设置为CPU核心数或两倍。 - 第二部分 events块
events块涉及的指令主要影响nginx服务器与用户的网络连接。 - 第三部分 http块
http块是nginx配置最频繁的部分。代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
需要注意的是:http又包含http全局块,server块。
①http全局块
②server块
典型配置
1 | user nginx; # 运行用户,默认即是nginx,可以不进行设置 |
server 块可以包含多个 location 块,location 指令用于匹配 uri,语法:
1 | location [ = | ~ | ~* | ^~] uri { |
指令后面:
=
精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;^~
用于不含正则表达式的 uri; 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;~
表示用该符号后面的正则去匹配路径,区分大小写;~*
表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;
如果 uri 包含正则表达式,则必须要有 ~
或 ~*
标志。
全局变量
Nginx 有一些常用的全局变量,你可以在配置的任何位置使用它们,如下表:
全局变量名 | 功能 |
---|---|
$host | 请求信息中的 Host,如果请求中没有 Host 行,则等于设置的服务器名,不包含端口 |
$request_method | 客户端请求类型,如 GET、POST |
$remote_addr | 客户端的 IP 地址 |
$args | 请求中的参数 |
$arg_PARAMETER | GET 请求中变量名 PARAMETER 参数的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer.. |
$content_length | 请求头中的 Content-length 字段 |
$http_user_agent | 客户端agent信息 |
$http_cookie | 客户端cookie信息 |
$remote_addr | 客户端的IP地址 |
$remote_port | 客户端的端口 |
$http_user_agent | 客户端agent信息 |
$server_protocol | 请求使用的协议,如 HTTP/1.0、HTTP/1.1 |
$server_addr | 服务器地址 |
$server_name | 服务器名称 |
$server_port | 服务器的端口号 |
$scheme | HTTP 方法(如http,https) |
还有更多的内置预定义变量,可以直接搜索关键字「nginx内置预定义变量」可以看到一堆博客写这个,这些变量都可以在配置文件中直接使用。
nginx配置反向代理
如图所示:
Nginx负载均衡
1 | http { |
Nginx 提供了好几种分配方式,默认为轮询,就是轮流来。有以下几种分配方式:
- 轮询,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;
- weight,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;
- ip_hash,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;
- fair(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装;
Nginx动静分离
通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 expires 来缓存),我这里设置 3d,表示在这 3 天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化。则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。
1 | server { |
Nginx配置高可用集群(双机热备)
如果Nginx宕机了,请求就无法使用了,保证Nginx宕机仍然能够使用,叫高可用。
当主 Nginx 服务器宕机之后,切换到备份 Nginx 服务器
配置高可用的准备工作:
- 需要两台服务器A和B
- 两台服务器安装nginx
- 两台服务器安装keepalived
前面两个条件已经准备好了,安装 keepalived,
1 | apt install keepalived |
然后编辑 /etc/keepalived/keepalived.conf 配置文件,并在配置文件中增加 vrrp_script 定义一个外围检测机制,并在 vrrp_instance 中通过定义 track_script 来追踪脚本执行过程,实现节点转移:
1 | global_defs{ |
复制代码其中检测脚本 nginx_check.sh,这里提供一个:
1 | #!/bin/bash |
复制代码复制一份到备份服务器,备份 Nginx 的配置要将 state 后改为 BACKUP,priority 改为比主机小。
设置完毕后各自 service keepalived start 启动,经过访问成功之后,可以把 Master 机的 keepalived 停掉,此时 Master 机就不再是主机了 service keepalived stop,看访问虚拟 IP 时是否能够自动切换到备机 ip addr。
再次启动 Master 的 keepalived,此时 vip 又变到了主机上。
Nginx基本原理
一个master和多个worker有什么好处呢?
- 可以使用nginx -s reload 热部署
- 每个worker是一个独立的进程,如果一个worker出现问题,其它的worker继续进行争抢,实现请求过程,不会造成服务中断。
- 设置worker才是最合适的呢?worker设置和CPU核心数相同最为适宜。
- 连接数worker_connection
第一个:发送请求,占用了worker的几个连接数?
答案:2或者4个
第二个:nginx有一个master,有四个worker,每个woker支持最大的连接数1024,支持的最大并发数是多少?
普通的静态访问最大并发数是:worker_connections*worker_processes/2
而如果HTTP作为反向代理来说,最大并发数量应该是worker_connections*worker_processes/4。