1、nginx基本概念
(1) nginx是什么,做什么事情
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务.
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。
(2) 反向代理
① 正向代理
需要在客户端配置代理服务器进行指定网站访问。

② 反向代理
我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的时代理服务器地址,隐藏了真实的服务器IP地址。

(3) 负载均衡
增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。

(4) 动静分离
为了加快网站的解析速度,可以把动态页面和静态页面有不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。

2、nginx安装和常用命令和配置文件
(1) 在linux安装nginx
① 安装pcre依赖 (注:注意区分Ubuntu和CenterOs)
官网下载 pcre2-10.36.tar.gz,复制到Linux上
tar -xvf pcre2-10.36.tar.gz,解压文件
进入到解压后的文件夹,执行./configure
如果提示 configure: error: Invalid C++ compiler or C++ compiler flags,请安装 gcc-c++ 库
Ubuntu:
apt install build-essential
CentOs:
yum -y install gcc-c++
最后执行make && make install,编译并且安装
② 安装openssl,zlib (注:注意区分Ubuntu和CenterOs)
Ubuntu:
apt install ruby
apt install make
apt install gcc zlib1g zlib1g.dev libpcre3 libpcre3.dev openssl libssl-dev
CentOs:
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
③ 安装nginx
tar -xvf nginx-1.18.0.tar.gz,解压文件
进入到解压后的文件夹,执行./configure
执行make && make install,编译并且安装
安装完成后,在/usr会多出来一个文件夹/local/nginx,在nginx/sbin下有启动脚本,输入./nginx启动nginx
启动后,nginx默认监听80端口,浏览器输入主机IP地址即可访问到nginx

(2) nginx常用命令
前提条件:使用nginx命令,进入nginx的目录(Ubuntu可不进入nginx目录下,以及可不加 ./ 。对于CentOs,则必须进入到nginx安装目录下,加上 ./
/usr/local/nginx/sbin
① 查看nginx版本号
nginx -v
② 关闭nginx
nginx -s stop
若出现nginx: [alert] kill(11, 1) failed (3: No such process)
需要重新绑定nginx配置文件,用 kill -9 pid 强制停止nginx进程后,进入到 /usr/local/nginx/sbin/
输入nginx -c /usr/local/nginx/conf/nginx.conf,后面就是nginx的配置文件的地址
然后就可以正常关闭nginx了
③ 启动nginx
nginx
④ 重新加载nginx
nginx -s reload,不需要关闭nginx
(3) nginx配置文件
配置文件地址: /usr/local/nginx/conf/nginx.conf
nginx配置文件由三部分组成
第一部分:全局块
从配置文件开始到events块之间的内容,主要会设置一些影响 Nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数、进程PID存放路径、日志存放路径和类型以及配置文件的引入等
eg:worker_processes 1;,表示支持的并发处理量的值
第二部分:events块
主要影响Nginx服务器与用户的网络连接,常用的设置包括是否开启多 work precess下的网络连接进行序列化,是否允许同时接受多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 worker process 可以同时支持的最大连接数等
eg:worker_processes 1;,表示每个 worker process 支持的最大连接数
第三部分:http块
Nginx服务器配置中最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里
http块包括 http全局块 和 http server块
http全局块:
http全局块配置的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、但链接请求数上限等
http server块:
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机
而每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块
全局 server 块:
最常见的配置时本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。
location 块:
一个 server 块可以配置多个 location 块
这块的主要作用时基于 Nginx 服务器接收到的请求字符串(例如:server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如 uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
3、nginx配置实例1——反向代理
(1) 实现流程
打开 nginx 的配置文件 nginx.conf,找到server块,将 server_name 后面改成主机的ip地址,在 localtion 块下增加proxy_pass属性,值就是你需要转发到的url地址(例如 http://127.0.0.0:8080)

注:如果location 使用了正则表达式,proxy_pass 的值后面不能包含URl Part
配置静态文件举个栗子:
location /test/ {
alias /home/test/; #文件目录地址
index index.html index.htm; #初始页
autoindex on; # 开启目录文件列表
autoindex_exact_size on; # 显示出文件的确切大小,单位是bytes
autoindex_localtime on; # 显示的文件时间为文件的服务器时间
charset utf-8,gbk; # 避免中文乱码
}
这有个CSDN大佬的博客,可以借鉴看下,以防入坑,location 之 index 详解
location正则表达式:
① =:用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
② ~:用于表示 uri 包含正则表达式,并且区分大小写
③ ~*:用于表示 uri 包含正则表达式,并且不区分大小写
④ ^~:用于不含正则表达式的 uri 前,要求 Nginx服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配
注:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。
location = / {
# 只匹配 / 的查询.
[ configuration A ]
}
location / {
# 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。
[ configuration D ]
}
# 各请求的处理如下例:
# ·/ -> configuration A
# ·/documents/document.html -> configuration B
# ·/images/1.gif -> configuration C
# ·/documents/1.jpg -> configuration D
# 注意你可以以任何顺序定义这4个配置并且匹配结果是相同的,但当使用嵌套的location结构时可能会将配置文件变的复杂并且产生一些比较意外的结果。
# 标记“@”指定一个命名的location,这种location并不会在正常请求中执行,它们仅使用在内部重定向请求中
4、nginx配置实例2——负载均衡
(1) 实现流程
在 nginx.conf 中配置添加
http{
......
upstream myserver{
server ip:port weight=1; #ip:port即为服务1运行地址,weight=1 可不写(权重)
server ip:port weight=1; #ip:port即为服务2运行地址
# upstream参数说明
# down 表示单前的server暂时不参与负载.
# weight 默认为1.weight越大,负载的权重就越大.
# max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误.
# fail_timeout : max_fails次失败后,暂停的时间,
# backup: 其它所有的非backup机器down或者忙的时候,请求backup机器. 所以这台机器压力会最轻.
}
......
server{
......
location /{
root html;
index index.html index.htm;
proxy_pass http://myserver; # myserver 即为 upstream 后面 所起的名字
proxy_connect_timeout 10;
}
}
}
Nginx 提供的几种分配策略:
① 轮询:
每个请求按时间顺序之一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除
② weight:
weight 表示权重,默认为1,权重越高被分配的客户端越多。
指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况
③ ip_hash:
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决session问题
eg:
upstream myserver{
ip_hash;
server ip:port; #ip:port即为服务1运行地址
server ip:port;
}
④ fair(第三方):
按后端服务器的响应时间来分配请求,响应时间段的优先分配
eg:
upstream myserver{
server ip:port; #ip:port即为服务1运行地址
server ip:port;
fair;
}
5、nginx配置实例4——动静分离
(1) 实现原理

动静分离:
动态请求和静态请求分开,可以理解为使用 Nginx 处理静态页面,tomcat等服务器处理动态页面
目前从实现角度分为两种:
① 纯粹把静态文件独立成单独的域名,放在独立的服务器上,这种方式较为主流
② 动态跟静态文件混合在一起发布,通过nginx 来分开
通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。
具体 Expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 Expires 来缓存),这里设置 3d,表示在这 3 天之内访问这个 URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。
(2) 实现流程
# 类似于上面的配置访问静态文件
server{
...
location /www/ {
root /dir/; #访问文件路径
index index.html index.htm;
}
location /test/ {
root /dir/;
autoindex on; #自动开启目录
}
}
6、nginx配置高可用集群
(1) 实现原理

(2) 实现流程
① 准备两台服务器,且两台服务器上都安装了nginx,且nginx配置相同
② 两台服务器安装keepalived
Ubuntu:apt install keeplived
输入dpkg --get-selections | grep keepalived或者dpkg -s keepalived查看包是否安装
CentOs:yum -y install keeplive
输入rpm -q -a keepalived查看包是否安装和软件包的版本
安装之后会在/etc下生成keepalived目录,里面有一个keepalived.conf文件(Ubuntu不会自动生成,可以自己创建该文件)
③ 两台服务器都需要修改 keepalived 配置文件
输入vi /etc/keepalived/keepalived.conf
修改为:
# 全局配置
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.1.102
smtp_connect_timeout 30
router_id LVS_DEVEL #一个没重复的名字即可,主副服务器区别开
# vrrp_skip_check_adv_addr
# vrrp_strict
# vrrp_garp_interval 0
# vrrp_gna_interval 0
}
vrrp_script chk_http_port {
script "/usr/local/src/nginx_check.sh" #脚本路径
interval 2 # 检测脚本执行的间隔
weight 2
}
vrrp_instance VI_1 {
state BACKUP # 备份服务器上将 MASTER 改为 BACKUP
interface eth0 # 网卡名称
virtual_router_id 51 # 主、备用机的virtual_router_id必须相同
priority 100 # 主、备用机不同的优先级,主机值较大,备用机值较小
advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
authentication {
auth_type PASS
auth_pass 1111
}
# 如果两节点的上联交换机禁用了组播,则采用vrrp单播通告的方式
# 本机ip
unicast_src_ip 192.168.1.101
unicast_peer {
# 其他机器ip
192.168.1.102
}
# 通常如果master服务死掉后backup会变成master,但是当master服务又好了的时候 master此时会抢占VIP
# 这样就会发生两次切换对业务繁忙的网站来说是不好的。
# 所以我们要在配置文件加入 nopreempt 非抢占,但是这个参数只能用于state 为backup
# 故我们在用HA(Highly Available)的时候最好 MASTER 和 BACKUP 的 state 都设置成 BACKUP 让其通过priority来竞争。
# 设置nopreempt防止抢占资源
nopreempt
track_script {
chk_http_port # 调用检测脚本
}
virtual_ipaddress {
192.168.1.100 # VRRP H虚拟地址,输入虚拟ip
}
}
脚本放在 /usr/local/src/ 下,其内容为:
#!/bin/bash
A=`pa -C nginx -no-header |wc -l`
if [ $A -ef 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0];then
killall keepalived # nginx停了停止所有keepalived进程
fi
fi
④ 启动 nginx 和 keepalived
systemctl start keepalived.service
此时访问虚拟ip地址,主服务器停止之后就会自动访问备用服务器( 两台不在同一内网的服务器貌似不行 )
7、nginx原理
(1) 原理


请求先发送到 master ,master 把任务交给下面的 worker,至于交给谁,worker 通过争抢机制获取任务,然后通过反向代理等访问 tomcat 或者其他
(2) master-worker机制好处
① 可以使用nginx -s reload 热部署,利用nginx 进行热部署操作 ② 每个woker 是独立的进程,如果有其中的一个woker 出现问题,其他woker 独立的,继续进行争抢,实现请求过程,不会造成服务中断。
(3) 需要设置多少个worker
Nginx 同 redis 类似都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。
worker 数和服务器的cpu 数相等是最为适宜的
# 设置 worker 数量
worker_processes 4;
# work 绑定cpu(4 work 绑定4cpu)。
worker_cpu_affinity 0001 0010 0100 1000;
# work 绑定cpu (4 work 绑定8cpu 中的4 个) 。
worker_cpu_affinity 0000001 00000010 00000100 00001000;
(4) 连接数 worker_connections
这个值是表示每个worker 进程所能建立连接的最大值,所以一个 nginx 能建立的最大连接数,应该是 worker_connections * worker_processes
当然,这里说的是最大连接数,对于HTTP请求本地资源来说 ,能够支持的最大并发数量是 worker_connections * worker_processes
如果是支持 http1.1 的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes / 2

而如果是HTTP作为反向代理来说,最大并发数量应该是 worker_connections * worker_processes / 4

因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接