Nginx 集群部署(Keepalived)

复制代码
# Nginx集群部署
# 当我们的用户同时访问量达到一定量的时候,一台服务器是不够用的
# 这个时候我们需要解决这个问题肯定是要添加新的服务器去处理用户访问
# 多台服务器处理用户访问就需要我们集群部署
# 通过Nginx反向代理是实现服务器集群部署的一种方法

# 一台服务器不够用的时候我们有很多方案可以去优化它
# 方案一:将不同的数据分布到不同的服务器上处理,通过反向代理将他们整合起来
# 方案二:多台服务器去处理同样的业务,通过反向代理负载均衡去控制用户访问由哪个服务器去处理,这样哪怕用户再多,只要一直增加服务器就能保证用户访问速度在一定范围。
# 方案三:将动态数据和静态页面分布到不同的服务器去处理。
# 不管哪种方案,你部署的时候一定要考虑部分服务器当机当机情况。

# Nginx高可用解决方案
# 也就是当Nginx代理服务器当机了,我们怎么去处理该问题
# Keepalived:Keepalived软件由C编写的,最初是专为LVS负载均衡设计的,Keepalived主要是通过VRRP协议实现高可用功能。
# VRRP介绍:
# VRRP协议是将多台路由器虚拟成一台路由器,它会有自己的ip,当客户访问虚拟路由器IP的时候,再由虚拟路由器分发到一台路由器去处理,
# 多台路由器具体由路由器设置的级别来决定用哪台路由器去处理,级别最高的为master主路由器,其他路由器都为backup备份路由器。
# 虚拟路由器只会将用户访问分发给master路由器去处理。
# 当master路由器当机后,多个backup路由器级别最高的那个成为master路由器。
# master路由器和backup路由器之间的关系:master路由器采用心跳机制发送状态码给Backup路由器以确保Backup路由器知道master路由器在正常运行;心跳机制停止后,Backup路由器就会竞争成为master路由器。

# Keepalived的安装
# 1.下载Keepalived源码包,官网地址:https://keepalived.org/
# 2.将压缩包上传到服务器
# 3.创建Keepalived目录
# 4.解压Keepalived-2.0.20.tar.gz
tar -zxf Keepalived-2.0.20.tar.gz -c Keepalived/
# 5.对keepalived进行配置,编译和安装。sysconf配置文件存放路劲。prefix安装路劲。
cd keepalived/keepalived-2.0.20
./configure --sysconf=/etc --prefix=/usr/local
make && make install 
# 安装完成后会生成/etc/keepalived/keepalived.conf配置文件
# 和/usr/local/sbin/leepalived系统脚本文件用来启动和关闭keepalived
# Keepalived.conf配置文件介绍
# Keepalived配置分为三部分,第一部分是global全局配置、第二部分是VRRP相关配置、第三部分是LVS相关配置
# 现在主要是使用keepalived实现高可用部署,没有用到LVS。
# global全局部分
global_defs {
  # 通知邮件,当keepalived发生切换时需要发送email给具体邮箱地址
  notification_email {
    abc@abc.com
    77325496***@qq.com
  }
  # 设置发件人的邮箱信息
  notification_email_from zzz@abc.com
  # 指定smtp服务地址
  smtp_server 192.168.1.1
  # 指定smpt服务链接超时时间
  smtp_connect_timeout 30
  # 运行keepalived服务器的一个标识(填写主机名就行),可以作用发送邮件的主题信息
  router_id LVS_DEVEL

  # 检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思时,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)。默认不跳过检查。
  vrrp_skip_check_adv_addr
  # 严格遵守VRRP协议
  vrrp_strict
  # 在一个接口发送的两个免费ARP之间的延迟。可以精确到毫秒级。默认是0
  vrrp_garp_interval 0
  # 在一个网卡上每组na消息之间的延迟时间,默认为0
  vrrp_gna_interval 0
}

# vrrp实例部分VI_1是实例的名称
vrrp_instance VI_1{
  # 设置当前实例时master还是backup路由器
  state MASTER
  # 用哪个网卡来发送消息包
  interface eth0
  # VI_1实例的唯一标识值  0-255之间任意值
  virtual_router_id 51
  # 优先级,数值越高级别越高
  priority 100
  # 定时向外发送arrp通告信息,主要用于心跳机制。1秒
  advert_int 1
 
  # 认证相关
  authentication {
    # 认证类型
    auth_type PASS
    # 认证密码
    auth_pass 1111
  }
  # 配置虚拟IP地址,可以配置多个供用户访问
  virtual_ipaddress {
    192.168.1.1
    192.168.1.2
  }
}

# 如何配置Keepalived当机自动重启
# 1.在Keepalived.conf全局位置增加配置
vrrp_script 脚本名称
{
  script "脚本位置"
  interval 3 # 执行间隔
  weight -20 # 动态调整vrrp_instance的优先级。master路由的优先级调低了也是优先master路由。所以要想master路由也参与该机制,就别设置master路由,只要将所有的路由都设置为backup路由就行。
}
# 2.编写脚本
ck_nginx.sh
#!/bin/bash
num =`ps -C nginx --no-header | wc -l`
if [ $num -eq 0 ];then
  /usr/local/nginx/sbin/nginx
  sleep 2
  if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then
    killall keepalived
  fi
fi
# ps指令中的参数
# -C(command):指定命令的所有进程
# --no-header 排除标题

# 例子:
# 这里是加载声明脚本
vrrp_script ck_nginx {
  script "/etc/keepalived/ck_nginx.sh"
  interval 2
  weight -20
}
vrrp_instance VI_1{
  state MASTER
  interface eth0
  virtual_router_id 51
  priority 100
  advert_int 1
 
  authentication {
    auth_type PASS
    auth_pass 1111
  }
  virtual_ipaddress {
    192.168.1.1
    192.168.1.2
  }
  track_script{
    # 这里可以指定多个脚本
    ck_nginx   
    ck_nginx
  }
}


# 配置两个Keepalived
# virtual_router_id、authentication、virtual_ipaddress要一样
# 启动服务
./keepalived

Nginx 缓存配置

# Buffer和Cache
# Buffer(缓冲):
# 客户端访问服务器某个资源文件的时候,因为服务器的性能远远比客户端机子的性能好,所以服务器要返回客户端所访问的资源的时候,服务器发送的速度远比客户端读取的速度要快,所以服务器先把资源放到缓冲中,让客户端慢慢读取。
# Cache(缓存):
# 客户端频繁访问服务器某个资源的时候,服务器上的资源没有改动,每次客户端访问的时候都需要从硬盘中读取到内存,然后返回到客户端。Cache缓存就减少了读取硬盘的频率,它是把频繁访问的文件一直放到缓存中,当客户端访问的时候直接从缓存中返回。

# nginx缓存流程
# 1.生成一个资源对应的唯一值key:URL + .[其他标识] = key
# 2.然后根据key进行MD5运算生成一个密文:key + MD5 = 字符串(密文)
# 3.缓存目录:/usr/local/proxy_cache
# 4.因为如果将所有缓存的资源都存放在同一个目录的话,缓存文件一多的话将会影响缓存检索速度。所以解决方案是:
# 根据字符串密文来创建目录进行存放:/usr/local/proxy_cache/a/d5/...
# 5.判断缓存目录有没有所访问的数据,有的话就从缓存中返回
# Nginx缓存的时候会将404、301、302也进行缓存
# 那么问题来了,缓存资源和服务器资源不一致怎么办?
# Nginx可以设置缓存资源的有效期来控制。

# Nginx缓存设置的相关指令
# Nginx的web缓存服务主要是使用ngx_http_proxy_module模块相关指令集来完成
# proxy_cache_path指令:用于设置缓存文件的存放路劲
# 语法:proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size]
# 默认值:无
# 位置:http
# path:缓存路劲地址,如:/usr/local/proxy_cache
# levels:指定该缓存控件对应的目录层次,最多可以设置3层,每层取值为1|2。具体这个目录名怎么来的,上面讲了nginx缓存流程,该目录名是根据第2步中key + MD5 = 字符串(密文)的字符串密文来创建的;假设有一个密文为:e10adc3949ba59abbe56e057f20f883e。
# 如果设置:level=1:2,那么该密文资源缓存存放在/usr/local/proxy_cache/e/83目录下。
# 如果设置:level=2:1:2,那么该密文资源缓存存放在/usr/local/proxy_cache/3e/8/f8目录下。
# 注意最多只能设置3层
# keys_zone:用来为这个缓存区设置名称和指定大小,这里设置的大小指的是存放keys的大小,如:keys_zone=itcast:200m   缓存区的名称是itcast,大小为200M,1M大概能存储8000个keys。
# inactive:指定缓存的数据多久时间未被访问就会被删除,如:inactive=1d   缓存数据在1天内没有被访问就会被删除
# max_size:设置最大缓存空间,如果缓存空间存满,默认覆盖缓存时间最长的资源,如:max_size=20g
# 实例配置
http {
  proxy_cache_path /usr/local/proxy_cache keys_znoe=itcast:200m levels=1:2:2 inactive=1d max_size=20g;
}

# proxy_cache:该指令用来开启或关闭代理缓存,如果开启则自定使用哪个缓存区来进行缓存
# 语法:proxy_cache zone_name|off;    # zone_name就是上面proxy_cache_path配置的keys_zone中的name
# 默认:off
# 位置:http、server、location

# proxy_cache_key:该指令用来设置web缓存的key值,Nginx会根据key值MD5哈希存缓存,也就是“nginx缓存流程”中的第1步,key生成的参数配置
# 语法:proxy_cache_key key;
# 默认:proxy_cache_key $scheme$proxy_host$request_uri;
# 位置:http、server、location

# proxy_cache_valid:该指令用来对不同返回响应状态码的URL设置不同的缓存时间
# 语法:proxy_cache_valid [code ...] time
# 默认值:无
# 位置:http、server、location
# 如:为200和302的响应URL设置10分钟缓存,为404的响应URL设置1分钟缓存
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;  # 对所有响应状态码的URL都设置1分钟缓存。这里具体哪个生效:从上往下找到,满足就不往下找了。


# proxy_cache_min_uses:该指令用来设置资源被访问多少次后被缓存
# 语法:proxy_cache_min_uses number;
# 默认值:1;  
# 位置:http、server、location

# proxy_cache_methods:该指令用户设置缓存哪些HTTP方法
# 语法:proxy_cache_methods GET | HEAD | POST;
# 默认值:GET HEAD;
# 位置:http、server、location

# 例子:
http {
  proxy_cache_path /usr/local/proxy_cache levels=2:2:1 keys_zone=itcast:200m inactive=1d max_size=20g;
  upstream backend {
    server 192.168.100.1:8080;
  }
  server {
    listen 8080;
    server_name: localhost;
    location / {
      proxy_cache itcast;
      #proxy_cache_key itheima;  # 这里设置的固定值,当前目录有多个文件的话,缓存就会出问题
      proxy_cache_key $scheme$proxy_host$request_uri;  # 协议+主机名+资源uri,这样每个资源都能有自己的key
      proxy_cache_min_uses 5;
      proxy_cache_valid 200 5d;
      proxy_cache_valid 404 30s;
      proxy_cache_valid any 1m;
      add_header ngin-cache "$upstream_cache_status";
      proxy_pass http://backend/js/;
    }
  }
}

# 删除相关缓存
# 方式一:直接删除目录
# 方式二:使用第三方扩展模块 ngx_cache_purge
# 安装方式之前也有安装过
# 七层负载均衡 安装过fair:https://www.cnblogs.com/watermeloncode/p/15497613.html
# 下载:ngx_cache_purge-2.3.tar.gz然后压缩配置configure……
http {
  proxy_cache_path /usr/local/proxy_cache levels=2:2:1 keys_zone=itcast:200m inactive=1d max_size=20g;
  upstream backend {
    server 192.168.100.1:8080;
  }
  server {
    listen 8080;
    server_name: localhost;
    location / {
      proxy_cache itcast;
      proxy_cache_key itheima;  
      proxy_cache_min_uses 5;
      proxy_cache_valid 200 5d;
      proxy_cache_valid 404 30s;
      proxy_cache_valid any 1m;
      add_header ngin-cache "$upstream_cache_status";
      proxy_pass http://backend/js/;
    }
    location ~ /purge(/.*) {
      proxy_cache_purge itcast itherma;  # 删除缓存
    }
  }
}

# proxy_no_cache:该指令定义不将数据进行缓存的条件
# 语法:proxy_no_cache string ...;
# 默认值:无
# 位置:http、server、location
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;  # 这里每一个变量都是条件,当变量的值为0或者空,则代表不成立,否则就是成立。这里只有当$cookie_nocache $arg_nocache $arg_comment只要其中有一个条件成立就不会缓存

# proxy_cache_bypass:该指令是用来设置不从缓存中获取数据的条件
# 语法:proxy_cache_bypass string ...;
# 默认值:无
# 位置:http、server、location
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;

http {
  proxy_cache_path /usr/local/proxy_cache levels=2:2:1 keys_zone=itcast:200m inactive=1d max_size=20g;
  upstream backend {
    server 192.168.100.1:8080;
  }
  server {
    listen 8080;
    server_name: localhost;
    location / {
      if ($request_uri ~ /.*\.js$){
        set $mychoise 1;
      }
      proxy_cache itcast;
      proxy_cache_key itheima;  
      proxy_cache_min_uses 5;
      proxy_cache_valid 200 5d;
      proxy_cache_valid 404 30s;
      proxy_cache_valid any 1m;
      proxy_no_cache $cookie_nocache $arg_nocache $arg_comment $mychoise;
      proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment $mychoise;
      add_header ngin-cache "$upstream_cache_status";
      proxy_pass http://backend/js/;
    }
    location ~ /purge(/.*) {
      proxy_cache_purge itcast itherma;  # 删除缓存
    }
  }
}

# $cookie_nocache:代表当前请求cookie中键的名称为nocache对应的值
# $arg_nocache:指的是当前请求参数中美味nocache的值
# $arg_comment:指的是当前请求参数中美味comment的值
# 你可以这样去获取他们的值

log_format params $cookie_nocache | $arg_nocache | $arg_comment
server {
  listen 8081;
  server_name localhost;
  location / {
    access_log logs/access_params.log params;
    root html;
    index index.html;
  }
}

Nginx 四层负载均衡

# Nginx 四层负载均衡
# ./configure 的时候需要添加--with-stream模块。

# stream指令:该指令提供在其中指定流服务器指令的配置文件上下文,和http指令同级。
# 语法:stream {...}
# 默认:无
# 位置:main    也就是全局

# upstream指令:该指令和http的upstream指令是类似的。
# 如何配置:
stream {
  upstream redisbackend {
    server 192.168.200.146:6379;
    server 192.168.200.146:6378;
  }
  upstream tomcatbackend {
    server 192.168.200.146:6379;
    server 192.168.200.146:6378;
  }
  server {
    listen 81;
    proxy_pass redisbackend;
  }
  server {
    listen 82;
    proxy_pass tomcatbackend;
  }
}

# 安装redis
# 1.下载redis的安装包  redis-4.0.14.tar.gz
# 2.将安装包解压 
tar -zxf  redis-4.0.14.tar.gz
# 3.进入redis安装包  
cd redis-4.0.14
# 4.使用make和install进行编译和安装
make PREFIX=/usr/local/redis01 install
# 5.拷贝redis配置文件redis.conf到/usr/local/redis01/bin
cp redis.conf /usr/local/redis01/bin
# 6.修改redis.conf配置文件:
port 6379   # redis的端口
daemonize yes  # 后端启动redis
# 7.将redis01复制一份redis02
cp -r redis01/ redis02
# 8.然后将redis02里的redis.conf中的端口改成6378
# 9.运行redis01、02,./redis-server  ../redis.conf
# 这个时候你在其他机子上并不能访问自己的redis,你需要再修改一个配置
# 10.修改bind的值
bind 0.0.0.0  # 修改成其他机子可以访问自己

Nginx 七层负载均衡

# 负载均衡
# 方式一:
# 同样资源放置多个链接让用户自己点其中一个链接去访问。如:我们下载资源的时候,经常会出现“广东电信”、“湖北电信”……
# 方式二:
# 通过域名去做负载均衡,因为一个域名我们可以配置多个ip地址,
# 当一个域名配置了多个IP地址后,浏览器通过域名访问的时候,域名解析会轮询返回域名所绑定的IP地址
# 但问题来了,浏览器通过域名解析得到与域名匹配的IP地址后,就会将域名与域名的IP存放在本地的缓存中了,
# 所以下次再访问的时候优先从本地缓存中获取IP,而不是从DNS域名解析那里获取。所以这种程度的负载均衡并没有达到最大化
# 方式三:四/七层负载均衡。
# 网络通信的七层模型分别是:1.物理层、2.数据链路层、3.网络层、4.传输层、5.会话层、6.表示层、7.应用层
# 这里的四/七层负载均衡。对应的就是4.传输层、7.应用层
# 越靠近物理层进行负载均衡的效率越高
# Nginx可是实现四/七层的负载均衡。

# 所谓的四层负载均衡指的是OSI七层模型中的传输层,主要是基于IP+PORT的负载均衡
# 实现四层负载均衡的方式:
# 硬件: F5 BIG-IP\Radware等  //硬件有一个不好的地方时,硬件在出场后就已经固定了,我们不好去拓展
# 软件:LVS、Nginx、Hayproxe等
# 所谓七层负载均衡职到是在应用层,主要是基于虚拟的URL或主机IP的负载均衡
# 实现七层负载均衡的方式:
# 软件:Nginx、Hayproxy等
# 四层和七层负载均衡的区别
# 1.四层负载均衡数据包时在底层就进行了分发,而七层负载均衡数据包则时在顶端进行分发,所以四层负载均衡的效率比七层负载均衡的效率要高。
# 2.四层负载均衡不识别域名,而七层负载均衡识别域名。


# Nginx七层负载均衡的指令
# upstream指令:该指令是用来定义一组服务器,他们可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。服务器可以指定不同的权重,默认为1.
# 语法:upstream name {...}
# 默认值:无
# 位置:http

# server指令:该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、断后或者unix socket
# 语法:server name [paramerters]
# 默认值:无
# 位置:upstream
# 例子:
upstream backend {
  server 192.169.1.101; 
  server 192.169.1.102;
  server 192.169.1.103;
}
server {
  listen 8082;
  server_name localhost;
  location / {
    proxy_pass http://backend;  //这里backend就是用upstream申明的服务器组
  }
}
# 配置完成后,192.169.1.101、192.169.1.102、192.169.1.103三台服务器循环处理用户的访问请求。

# 负载均很的状态:代理服务器在负责均衡调度中的状态有以下几个:
# down:当前的server暂时不参与负载均衡
upstream backend {
  server 192.169.1.101 down; 
  server 192.169.1.102;
  server 192.169.1.103;
}
# backup:预留的备份服务器,当103当机了才会启用102参与负载均衡
upstream backend {
  server 192.169.1.101 down; 
  server 192.169.1.102 backup;
  server 192.169.1.103;
}
# max_fails:允许请求失败的次数
# fail_timeout:经过max_fails失败后,服务暂停时间,默认是10s;
upstream backend {
  server 192.169.1.101 down; 
  server 192.169.1.102 backup;
  server 192.169.1.103 max_fails=3 fail_timeout=15;# 当服务器请求失败次数连续达到3次的时候,这时候103服务器就会暂停15秒不接收任何请求,这15秒会启用102备用服务器接收处理客户端访问请求,15秒后103会再次处理请求,如果没有失败103就算恢复正常,如果再次失败3次就继续暂停15秒。
}
# max_conns:限制最大的接受链接数,默认0,不做限制。防止服务器接收访问的请求过多而导致服务器当机。

# 方便测试当即状态,你可以在防火墙中设定端口是否放行
# 查询防火墙中指定的端口是否开放
firewall-cmd --qurey-port=9001/tcp
# 如何开放一个指定的端口
firewall-cmd --permanent --add-port=9002/tcp
# 批量添加开放端口
firewall-cmd --permanent --add-port=9001-9003/tcp
# 如何移除一个指定的端口
firewall-cmd --permanent --remove-port=9002/tcp
# 重新加载
firewall -cmd --reload

# 负载均衡策略
# Nginx默认策略是,接收客户端访问的请求后轮询分发到服务器。
# 除了轮询,Nginx还提供了其他几种分配算法
# 轮询:默认方式。weight=1.
# weight:权重方式。也就是按比例分配。轮询和weight一起的。
upstream backend {
  server 192.169.1.101 weight=10; 
  server 192.169.1.102 weight=5;
  server 192.169.1.103 weight=5;
}
# ip_hash:依据ip分配方式,也就是访问服务器的浏览器客户端所在电脑的ip。当客户访问你的网站的时候需要登录,问题来了,当你第一次访问的时候是101服务器处理登录的并且在101服务器上保存的session,而第二次访问的时候是102,这个时候102是没有session的,所以又得登录生成session依次类推,下次访问服务器地址又变成103的话是不是又得登录。而这个ip_hash就是根据这个ip来分配的,当你第一次连接的是101那么往后的请求也都是在101完成的。这种方案不好的地方在于,你设置的权重或者其它算法将不起作用。要解决这个问题,你可以在三台服务器上搭建一个共同保存session的地方,比如:redis。
upstream backend {
  ip_hash;
  server 192.169.1.101; 
  server 192.169.1.102;
  server 192.169.1.103;
}
# least_conn:依据最少连接方式。当前服务器正在连接的数量最少的优先分配。这种负载均衡策略主要是解决处理请求耗时较长的访问。
upstream backend {
  least_conn;
  server 192.169.1.101; 
  server 192.169.1.102;
  server 192.169.1.103;
}
# url_hash:依据URL分配方式。应用场景:客户端访问服务器的某个资源文件的时候,服务器不是从本地拿取文件,而是从文件系统服务器拿文件,拿到的文件如果是客户端访问频繁的资源的话,服务器会将资源文件缓存到本地,下次客户端再次访问的时候就不需要重新去文件系统中拿取了。这样就出现了ip_hash一样的问题。url_hash就是解决该问题的。
upstream backend {
  hash $request_uri;
  server 192.169.1.101; 
  server 192.169.1.102;
  server 192.169.1.103;
}
# fair:依据相应时间的方式。服务器响应越快的优先分配。
# fair算法是属于第三方的负载均衡算法,所以你需要添加nginx-upstream-fair。
# 1.下载nginx-upstream-fair模块
# 下载地址:https://github.com/gnosek/nginx-upstream-fair
# 2.解压缩:unzip nginx-upstream-fair.zip
# 3.重命名:mv nginx-upstream-fair fair
# 4.使用./configure命令将资源添加到Nginx模块中
# ./configure -add-module=/root/fair
# 5.编译:make,这时候会报一个default_port错误。
# 如何解决:在Nginx的源码中src/http/ngx_http_upstream.h中找到"ngx_http_upstream_srv_conf_s",在结构体中添加"in_port_t   default_port",注意是添加不是替换。
# 6.平滑升级。
# 7.配置fair指令
upstream backend {
  fair;
  server 192.169.1.101; 
  server 192.169.1.102;
  server 192.169.1.103;
}

# 案例一:对所有请求实现一般轮询规则的负载均衡
upstream backend {
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}
server {
  listen 8083;
  server_name localhost;
  location / {
    proxy_pass http://backend;
  }
}

# 案例二:对所有请求实现权重轮询规则负载均衡
upstream backend {
  server 192.168.200.146:9001 wight=7;
  server 192.168.200.146:9002 wight=7;
  server 192.168.200.146:9003 wight=7;
}
server {
  listen 8083;
  server_name localhost;
  location / {
    proxy_pass http://backend;
  }
}

# 方案三:对特定资源实现负载均衡
upstream videobackend {
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

upstream filebackend {
  server 192.168.200.146:9011;
  server 192.168.200.146:9012;
  server 192.168.200.146:9013;
}
server {
  listen 8083;
  server_name localhost;
  location /video/ {
    proxy_pass http://videobackend;
  }
  location /file/ {
    proxy_pass http://filebackend;
  }
}

# 方案四:对不同域名实现负载均衡
upstream itcastbackend {
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}

upstream itheimabackend {
  server 192.168.200.146:9011;
  server 192.168.200.146:9012;
  server 192.168.200.146:9013;
}
server {
  listen 8085;
  server_name www.itcast.cn;
  location / {
    proxy_pass http://itcastbackend;
  }
}
server {
  listen 8086;
  server_name www.itheima.cn;
  location / {
    proxy_pass http://itheimabackend;
  }
}

# 案例五:实现带有URL重写的负载均衡
upstream backend {
  server 192.168.200.146:9001;
  server 192.168.200.146:9002;
  server 192.168.200.146:9003;
}
server {
  listen 8087;
  server_name localhost;
  location /file/ {
    rewrite ^(/file/.*) server/$1 last;
  }
  location /server {
    proxy_pass http://backend;
  }
}

Nginx 配置SSL证书

# Nginx 如何添加对SSL的支持
# 需要安装 --with-http_ssl_module模块
# ssl指令:该指令用来在指定的服务器开启HTTPS,可以使用listen 443 ssl来开启
# 语法:ssl on | off;
# 默认:off
# 位置 http、server
server {
  lsten 443 ssl;
}

# ssl_certificate指令:为当前这个虚拟主机指定一个带有PEM格式证书的证书。
# 语法:ssl_ceritificate file;
# 默认:无
# 位置 http、server
ssl_ceritificate www.sohu.com.pem;

# ssl_certificate_key指令:为pem指定secret_key文件路劲。
# 语法:ssl_certificate_key file;
# 默认:无
# 位置 http、server
ssl_ceritificate www.sohu.com.key;

# ssl_session_cache指令:该指令用来配置用于SSL回话的缓存
# 语法: ssl_session_cache off | none | [builtin[:size]] [shared:name:size]
# 默认:none
# 位置 http、server
# off:禁用回话魂村,客户端不得重复使用会话
# none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数。
# builtin:内置OpenSSL缓存,仅在一个工作进程中使用
# shared:所有工作进程之间共享缓存,缓存的相关信息用name和size来指定
ssl_session_cache none;

# ssl_session_timeout:开启SSL会话功能后,设置客户端能够反复使用存储在缓存中的会话参数时间。
# 语法:ssl_session_timeout time;
# 默认:5m    //也就是5分钟
# 位置 http、server
ssl_session_timeout 5m;

# ssl_ciphers:支出允许的密码,密码指定为OpenSSL指定的密码格式。
# 语法:ssl_ciphers ciphers;
# 默认值:ssl_ciphers HIGH:!aNULL:!MD5;
# 位置 http、server
ssl_ciphers HIGH:!aNULL:!MD5;

# ssl_prefer_server_ciphers:该指令指定是否服务器密码优先客户端密码
# 语法:ssl_prefer_server_ciphers on | off
# 默认:off
# 位置 http、server
ssl_prefer_server_ciphers off

# SSL证书来源
# 1.去阿里云或者腾讯云或者其他证书机构购买或者申请SSL证书。
# 2.用OpenSSL去自己制作SSL证书
# OpenSSL生成证书的命令
mkdir /root/cert
cd /root/cert
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -singnkey server.key -out server.crt

# 如何配置刚生成的SSL证书
server {  
  listen 443 ssl;
  server_name localhost;
  
  ssl_certificate cert.pem;
  ssl_certificate_key cert.key;
  
  ssl_session_cache shared:SSL:1m;
  ssl_session_timeout 5m;
  
  ssl_ciphers HIGH:!aNULL:MD5;
  ssl_prefer_server_ciphers on;
  
  location / {
    root html;
    index index.html;
  }
}
# 再次重启的时候浏览器还是会报错,是因为我们自己生成的证书是没有认证机构的。要不报错就必须从认证机构哪里获得证书。

Nginx 反向代理

# Nginx 反向代理
# 反向代理模块是由ngx_http_proxy_module进行解析的
# proxy_pass指令:用来设置被代理服务器地址,可以是主机名称、IP地址加端口号形式。
# 位置:location
# 语法:proxy_pass URL;
server {
  listen 8080;
  server_name localhost;
  location /server {
    # proxy_pass http://192.168.1.100;
    proxy_pass http://192.168.1.100/;
    # 地址后面的斜杠加和不加的区别
    # 当客户端访问 http://192.168.1.100/server/index.html
    # 不加斜杠,就变成了 http://192.168.1.100/server/index.html
    # 加斜杠,就变成http://192.168.1.100/index.html
    # 也就是加了斜杠就是替换location中的/server为访问的uri。
  }
}

# proxy_set_header指令:该指令可以更改Nginx服务器接收到客户端请求头信息,然后将新的请求头发送给代理的服务器。
# 语法:proxy_set_header field value;
# 默认值:proxy_set_header Host $proxy_host;
# proxy_set_header Connection close;
# 位置:http、server、location
proxy_set_header username TOM;

# proxy_redirect指令:该指令是用来重置头信息中的"location"和"Refresh"的值的。
# 具体说明:假设192.168.1.100是代理服务器,192.168.1.200是服务器地址
# 当浏览器输入http://192.168.1.100/index.html访问服务器的时候,访问的是代理服务器,而实际上页面的内容是在服务器上
# 所以代理服务器需要代理访问http://192.168.1.200/index.html,
# 而http://192.168.1.200/index.html这时候处理结果是重定向到http://192.168.1.200/other.html
# 如果代理服务将192.168.1.200服务器返回的内容原封不动的返回到浏览器的话,那么浏览器的URL就会重定向到http://192.168.1.200/other.html了
# 这样就暴露了我们服务器的真实地址了
# proxy_redirect就是通过重置头信息中的"location"和"Refresh"的值来处理这个问题的。
# 语法:proxy_redirect redirect replacement;
#       proxy_redirect default;
#       proxy_redirect off;
# 位置:http、server、location
# 参数说明:redirect为目标location的值,replacement是要替换的值
# default:就是location块的uri变量的值。
# off:关闭proxy_redirect功能。
# 例子:
server {
  listen 8081;
  server_name 192.168.1.100;
  location / {
      proxy_pass http://192.168.1.200/
      proxy_redirect http://192.168.1.200/ http://192.168.1.100/;
  }
}
server {
  listen 80;
  server_name 192.168.1.100;
  location / {
    proxy_pass http://192.168.1.200:8080/
  }
}

Nginx 正向代理

# Nginx正向代理
# 正向代理这块没有详细其他配置了
# 以后需要的话再去官方文档中研究
server {
  listen 82;
  resolver 8.8.8.8;  # 设置DNS的IP  用来解析proxy_pass中的域名
  location / {
    proxy_pass http://$host$request_uri;
  }
}

Nginx Rewrite资源重定向

# Rewrite功能配置
# Rewrite功能主要是实现了url重写
# 如:你输入www.jd123.com,你可以通过Rewrite让它重定向到www.jd.com
# Rewrite的实现依赖与PCRE的支持,因此要使用先你需要先安装OCRE库。
# Nginx使用的是ngx_http_rewrite_module模块来解析和处理rewrite功能的相关配置的。
# Rewrite相关指令
# set指令:该指令用来设置一个新的变量。
# 语法: set $variable vale;
# 默认:空
# 位置:server、location、if
server {
  listen 8081;
  server_name localhost;
  location /server {
      set $name TOM;
      set $age 18;
      default_type text/plain;
      return 200 $name=$age;
  }
}

# Rewrite常用全局变量
# $args:变量中存放了请求URL中的请求参数。比如:http://192.168.200.133/server?arg1=value1&args2=value2中的"arg1=value1&args2=value2"。功能和$query_string一样。
# $http_user_agent:变量存储的是用户访问服务器的代理信息(如果是浏览器访问,记录的是浏览器的相关版本信息)
# $host:访问服务器的server_name。
# $document_uri:存储的是当前访问地址的URI。比如:http://192.168.200.133/server?arg1=value1&args2=value2中的"/server"和$uri
# $document_root:变量存储的是当前请求对应的location的root值。
# $document_length:存储的是请求头中的Content-Length的值。
# $content_length:存储的是请求头中的Content-Type。
# $http_cookie:存储的是客户端的cookie信息,可以通过add_header Set-Cookie 'cookieName=value'来添加cookie数据。
# $limit_rate:存储的是Nginx服务器对网络链接速率的限制,也就是Nginx配置中的limit_rate指令设置的值,默认是0,不限制。
# $remote_addr:存储1是客户端的ip地址。
# $remote_port:客户端与服务端建立链接的端口。
# $remote_user:存储的了客户端的用户名,需要有认证模块才能获取。
# $scheme:存储了访问的协议。http、https……
# $server_addr:存储了服务器的地址。
# $server_name:服务器的名称。
# $server_port:服务器的端口。
# $server_protocol:客户端请求协议的版本。如:HTTP/1.1
# $request_body_file:存储了发给后端服务器的本地文件资源的名称。
# $request_method:客户端请求服务器的方式。get、post等
# $request_filename:当前请求的资源文件的路劲名。
# $request_uri:存储了当前请求的URI,并且附带请求参数,比如:http://192.168.200.133/server?arg1=value1&args2=value2中的"/server?arg1=value1&args2=value2"

# 这些变量也都可以在log中使用
server {
  listen 8081;
  server_name localhost;
  log_format main '$remote_addr - $request - $status';
  location /server {
      set $name TOM;
      set $age 18;
      access_log logs/access.log main;
      default_type text/plain;
      return 200 $name=$age;
  }
}

# if指令:条件判断
# 语法:if (condition){...}
# 位置:server、location
location /testif {
  set &username 'ROSE';
  default_type text/plain;
  if ($args){      # 当$args等于0或者没有值的时候返回False
    return 200 success;
  }
  if ($requests_method = POST){   #是post请求过来的为真,否则为假。!=:和=相反
    RETURN 405;
  }
  if ($http_user_ahent ~* safari){ # 当$http_user_ahent包含safari的时候为真。safari你可以写成你的正则表达式。~和~*的区别是~*不区分大小写。
    return 200 Chrome;
  }
  return 200 error;
}

# "-f"和"!-f"判断请求文件是否存在。
# "-d"和"!-d"判断请求目录是否存在。
# "-e"和"!-e"判断请求文件或者目录是否存在。
# "-x"和"!-x"判断请求的文件是否是可执行文件。
location / {
  root html;
  if (!-f $request_filename){  # 如果文件不存在就返回file not found!
    return 200 '<h1> file not found!</h1>';
  }
}


# break指令
# 该指令用于终端当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。
# 并且break还有另外一个功能就是终止当前匹配并把当前的URI在本location进行重定向访问处理。
# 位置 server、location、if
# 例子:
location /testbreak {
  default_type text/plain;
  set $username JERRY;
  if ($args){
    set $username TOM;   # 执行
    break;
    set $username ROSE;  # 不执行
  }
  add_header username $username;   # 执行
  return 200 'username $username'; # 重定向到  index index.html  这里我们没有配置index所以它走的默认dindex值。这就是上面说的终止当前并把当前的URI在本location重定向访问处理。
}

# return 指令
# 语法一:return code [text];
# 语法二:return code URL;
# 语法三:return URL;   相当于:return 302 URL;   302就是重定向的相应码。
# 位置:server、location、if


# rewrite指令:该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序一次对URL进行匹配和处理。
# 语法:rewrite regex replacement [flag];    //flag默认值:last
# 位置:server、location、if
# flag: last | break | redirect | permanent
# regex:用来陪陪URI的正则表达式
# replacement:匹配成功后,用于替换URI中被截取内容的字符串、如果该字符串式以"http://"或者"https://"开头的,则不会继续向下对uri进行其他处理,而是直接返回重写后的URI给客户端。
# 例子:
location /rewrite {
  rewrite ^/rewrite/url\w*$ https://www.baidu.com;      # 这里重定向跳转到www.baidu.com
  rewrite ^/rewrite/(test)\w*$ /$1;            # 这里重定向到location /test
  rewrite ^/rewrite/(demo)\w*$ /$1;            # 这里重定向到location /demo
}
location /test {
  default_type text/plain;
  return 200 test_success;
}
location /demo {
  default_type text/plain;
  return 200 demo_success;
}

# flag的用法
location /testflag {
  default_type text/plain;
  return 200 testflag_success;
}
location /rewriteflag {
  rewrite ^/rewrite/(testflag)\w*$ /$1;
  # rewrite ^/rewrite/(testflag)\w*$ /$1 last;   //当匹配成功后会在location所在的整个server中找到/testflag location然后返回,并且浏览器中的地址不会发生任何重定向的变化
  # rewrite ^/rewrite/(testflag)\w*$ /$1 break;  //当匹配成功后会在当前location中查找访问的资源,然后返回给浏览器。这里访问的路劲是:rewriteflag/html/index.html
  # rewrite ^/rewrite/(testflag)\w*$ /$1 redirect;//临时重定向到 "location /testflag",浏览器地址会变动
  # rewrite ^/rewrite/(testflag)\w*$ /$1 permanent;//永久重定向到 "location /testflag",浏览器地址会变动
}


# rewrite_log指令
# 该指令配置是否开启URL重写日志的输出功能
# 语法:rewrite_log on | off
# 默认:off
# 位置:http、server、location、if
# 开启后,URL重写的相关日志将以notice级别输出到error指令配置的日志文件中去。
rewrite_log on;
error_log logs/error.log notice;  # 这里错误日志级别设置为notice。

# 案例:域名跳转
server {
  listen 80;
  server_name www.it.com;
  
  location /test {
    default_type text/plain;
    return 200 test_success;
  }
}
server {
  listen 80;
  server_name www.abc.com www.abc.ccn;
  rewrite ^(.*) www.it.com$1;   # $1当访问的是www.abc.com/test的时候  $1指的就是/test
}

# 案例:域名镜像
# 主要实现将资源分散到不同的主机上
server {
  listen 80;
  server_name www.abc.cn;
  
  location /user {
    rewrite ^/user(.*)$ http://www.otherhost.cn$1;   # 这里上面也讲到过,并不会影响浏览器url地址,所以部分资源我们可以用专门的电脑去处理。
  }
  location .emp{
    default_type text/plain;
    return 200 '<h1>emp_access</h1>';
  }
}

# 防盗链,我们也可以通过rewrite返回一个默认图片

Nginx 配置静态资源防盗链

# 什么是静态资源盗链:
# 你服务器上的一张图片,127.0.0.1/images/a.png
# 别人的html页面可以直接通过<img src="127.0.0.1/images/a.png" />来进行显示。

# 如何通过Nginx防止资源盗链
# valid_referers指令:会通过查看请求头的referer内容自动和valid_referers指令设置的内容进行匹配,
# 如果匹配到了就将$invalid_referer变量值设置为0,否者就设置为1,匹配的过程是不区分大小写的
# 语法:valid_referers nont | blocked | server_names | string
# 默认值: 无
# 位置:server、location
# none:如果请求头中的Referer为空,则允许访问
# blocked:Referer不为空,但是改制呗防火墙或者代理进行伪装过,如果不带"httpL//"、"https://"等协议的资源允许访问
# server_names:指定具体的域名或者ip
# string:可以支持正则表达式和*的字符串。如果是正则表达式,需要以~开头标识。
valid_referers none bocked www.baidu.com 192.168.200.222 *.example.com  example.* ~\.google\.
if ($invalid_referer){   # 如果匹配到了就将$invalid_referer变量值设置为0,否者就设置为1,匹配的过程是不区分大小写的
  return 403; # 403未找到资源   或者通过rewrite去返回一个默认图片
}

Nginx 浏览器缓存配置指令

# 浏览器缓存
# 当浏览器第一次访问服务器资源的时候,服务器返回到浏览器后,浏览器进行缓存
# 缓存的大概内容有:
# 1.缓存过期的日期和时间
# 2.设置和缓存相关的配置信息
# 3.请求资源最后修改时间
# 4.请求资源的MD5值
# 强缓存:当浏览器再次请求同样资源的时候,会去缓存中查看是否有它的缓存,有的话就查看是否过期,如果没过期就直接从浏览器缓存中拿取数据。这就是浏览器强缓存。
# 弱缓存:当浏览器再次请求同样资源的时候,会去缓存中查看是否有它的缓存,有的话就查看是否过期,如果过期了,浏览器就会拿着“请求资源最后修改时间”和“请求资源的MD5值”去服务器请求资源。这个时候服务器收到请求就会通过“请求资源的MD5值”去判断文件是否有改动,没有改动的话,服务器就会返回304状态码。这就是浏览器弱缓存。资源有改动的话,服务器就像浏览器第一次访问那样返回资源到浏览器。

# expires指令:该指令用来控制页面缓存的过期时间的。也就是可以通过该指令控制HTTP应答中的"Expires"和"Cache-Control"
# 语法一:expires [modified] time;
# 语法二:expires epoch | max | off;
# 默认值:off;
# 位置:http、server、location
# time:可以是负数、指定过期时间,如果是负数,Cache-Control则为no-cache(也就是弱缓存处理发方式),
# 如果为整数或0,Cache-Control的值为max-age=time。也就是多少秒后过期。
# epoch:指定Expires的值为"1 January,1970,00:00:01 GMT"(1970-01-01 00:00:00),Cache-Control的值为no-cache
# max:指定Expires的值为'31 December 2037 23:59:59 GMT'(2037-12-31 23:59:59),Cache-Control的值为10年的秒数。
# off:默认不缓存。
expires 1000;    # 缓存1000秒后需要重新获取

# add_header指令是用来添加指定的响应头和响应值。
# 语法:add_header name value [always]
# 位置:http、server、location
add_header Cache-Control no-cache;
# 缓存响应指令:
# Cache-Control: must-revalidate    //可缓存但必须再向服务器进行确认
# Cache-Control: no-cache        //缓存前必须确认其有效性
# Cache-Control: no-store        //不缓存请求或响应的任何内容
# Cache-Control: no-transform        //代理不可更改媒体类型
# Cache-Control: public        //可向任意方提供响应的缓存
# Cache-Control: private        //仅向特定用户返回响应
# Cache-Control: proxy-revalidate    //要求中间缓存服务器对缓存的响应有效性再进行确认
# Cache-Control: max-age=<seconds>    //响应最大Age值
# Cache-Control: s-maxage=<seconds>    //公共缓存服务器响应的罪罚Age值

# Nginx的跨域问题解决
# 浏览器调用服务器的GET,POST……方法的时候会实行了同源策略检查,检查不通过的话浏览器就会报错。不是同源就是跨域。
# 什么是同源策略:你当前页面通过GET,POST方法向服务器发请求的时候,
# 如果你当前页面的协议、域名(IP)、端口和请求接口的服务器有任何的不一样那么就不符合同源策略,
# 就会报缺少Access-Control-Allow-Origin、Access-Control-Allow-Methods的错
# Nginx可以直接通过add_header来配置请求响应头来解决跨域问题
add_header Access-Control-Allow-Origin http://127.0.0.1;
add_header Access-Control-Allow-Origin *; # 允许任何人调用
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;

Nginx 文件传输效率、实时、压缩配置指令

# sendfile  开启文件高效传输模式
# 默认值:off
# 位置:http、servcer、location……
# 开启和不开启worker访问的文件发送到浏览器的过程不同。
# 不开启的时候worker进程先调用read()函数将数据读取致缓存,然后返回给浏览器
# 开启之后worker进程直接调用sendfile()将文件在缓存中通过句柄发送给浏览器了
sendfile on|off;

# tcp_nopush 该指令必须在sendfile打开的时候才会生效,主要是用来提高网络包的传输'效率'
# 语法:tcp_nopush on|off
# 默认值: off
# 位置:http、server、location
tcp_nopush on|off;

# tcp_nodelay 该指令必须在keep-alive开启的情况下才生效,来提高网络包传输的‘实时性’
# 语法:tcp_nodelay on|off
# 默认值:on
# 位置:http、server、location
# tcp_nopush 、tcp_nodelay 之间的关系是互斥的
# 大家都知道tcp每个包传输的时候其中可能99%都是协议的内容,%1是我们真实要发送到客户端的内容,
# tcp_nopush就是要等数据达到规定大小的时候才发送出去,这样就提高了发送数据的效率,但于此同时却缺乏了发送数据的实时性,tcp_nodelay 就和tcp_nopush相反,只要有数据就发送。
# 后面随着linux系统和Nginx的更新,这两个指令可以同时设置为on,linux系统会判定发送文件的时候启用tcp_nopush 模式,其他时候看情况适用tcp_nodelay 模式。具体是怎么应用还需要进一步查证。
tcp_nodelay on;

# ngx_http_gzip_module 模块
# nginx内置了很多模块,这些模块的使用在nginx官方都是有说明文档的
# gzip、gzip_types配置指令就是来配置ngx_http_gzip_module
# gzip、gzip_types是来配置浏览器访问文件的时候是否先将文件压缩后传输
# gzip是用来是指是否启用或关闭压缩功能
# gzip_types是用来控制只对哪些文件类型进行压缩,它对应的值是mime.type文件中的值
# 位置 http、server、location
# 语法:
gzip on|off;  # 默认off
gzip_type mome-type1 mome-type2 ...;  # 默认 text/html
# 之所以要用gzip_type指定类型,是因为有些图片或者文件,它本身就已经压缩了,你通过nginx再次对它压缩的效果其实不大,反而大大增加了服务器运算。
# 所以不建议直接设置成gzip_type *;

# gzip_comp_level指令,该指令可以设置压缩级别1-9,数值越低压缩耗时越低,同时压缩程度越低,
# 数值越高,压缩耗时越高(也就是运算复杂度越高),但压缩成都越好。
# 一般不建议直接设置成1或者9,建议使用6(中间值)就可以了,因为设置6级和9级压缩后文件的大小变化其实并没有预想的那么好。
# 语法 gzip_comp_level level;
# 默认值:1
# 位置: http、server、location
 gzip_comp_level 6;

# gzip_vary指令:设置http的请求头中是否包含Vary: Accept-Encoding;值来告诉浏览器我们传输的文件是进行过gzip压缩的。
# 语法: gzip_vary on|off
# 默认:off
# 位置 http、server、location
gzip_vary on;

# gzip_buffers指令:该指令用于处理请求压缩的缓冲去数量和大小。对文件进行压缩的时候需要用到缓存,这里就是设置压缩时申请缓存大小。一般该指令不建议去修改它的默认值。32bit和64bit它的默认值是不同的,
# 语法:gzip_buffers number size;
# number 数量,size是大小,number*size等于缓冲区内存大小
# 默认值:gzip_buffers 32 4k | 16 8k;
# 位置 http、server、location

# 选择性开启或者关闭gzip压缩功能
# 如果浏览器发送的http请求头User-Agent的值符合regex 就启用gzip,否则就不启用。
# User-Agent是浏览器和操作系统的相关信息,防止某些浏览器版本不支持gzip。
# 语法: gzip_disable regex ...;
# gzip_disable "Mozilla/5.0.*";
# 语法:gzip_http_version 1.0|1.1;
# 默认:1.1  一般不用改动它
# gzip_http_version 通过http请求版本来控制是否启用gzip
# gzip_min_length length;  如果请求的内容小于length的时候就不启用gzip功能。
# 页面大小可以通过Content-Length来获取。
# 默认:20kb,当数值后面没有跟单位的时候,默认b单位
gzip_min_length 20;
# 单位有 bytes[字节]/kb[千字节]/m[兆]
# gzip_proxied指令是在反向代理的时候使用
# 当满足某些条件的时候启用gzip
# 语法 gzip_proxied off|expired|no_cache|no-store|private|no_last_modifield|no_etag|auth|any;
# 默认值:off
# off   关闭Nginx服务器对后台服务器返回结果的gzip压缩
# expired    启用压缩,如果header头中包含“Expires”头信息
# no-cache  启用压缩,如果header头中包含“Cache-Control:no_cache”头信息
# no-store  启用压缩,如果header头中包含“Cache-Control:no_store”头信息
# no-private    启用压缩,如果header头中包含“Cache-Control:private”头信息
# no_last_modifield  启用压缩,如果header头中不包含"Last-Modifield"头信息
# no_etag  启用压缩,如果header头中不包含"ETag"头信息
# auth  启用压缩,如果header头中包含"Authoriztion"头信息
# any  无条件启用压缩

# gzip和sendfile共存问题
# 在浏览器访问服务器文件的时候,文件从服务器返回致浏览器经过了三个缓存区
# 分别是:1.服务端收到请求时应用程序向内核发送read读取文件指令,然后内核去读取文件到内核缓冲区,
# 2.再冲内核缓冲区返回到应用程序缓冲区,
# 3.再由应用程序把文件内容冲应用程序缓冲区发送到Socket缓冲区返回到浏览器。
# 而sendfile省去了第2步骤,当服务器接收到请求时,直接将要传递的文件名通过sendfile函数告诉内核要发送到哪个Socket缓存。那么内核读取到文件后并不返回到应用程序缓冲区,而是直接将文件读取到和内核缓冲后直接copy到Socket缓冲区完成返回。
# 那么问题来了,gzip压缩是需要在应用程序中执行压缩的,然而你启用了sendfile模式那么就无法使用gzip的功能。
# 后面Nginx新增了ngx_http_gzip_static_module模块去处理它
# 指令:gzip_static on | off | always;
# 注意,ngx_http_gzip_static_module在Nginx安装的时候,默认是不安装的,所以你要用的话需要手动通过./configure去配置升级。
# 它的处理流程是:在文件发送前先一步将文件内容压缩打包成.gz后缀的压缩包,等用的时候直接使用把压缩包返回到浏览器。这样做好处也是挺大的。
# 那么.gz文件是什么时候生成的呢
# 是通过命令来的,下面就是 jquery.js打包成 jquery.js.gz
gzip jquery.js
# on:当客户端浏览器支持就发送压缩后的文件,而不是原文件
# off:关闭
# always:不管客户端浏览器支持不支持都发送压缩后的文件

Nginx listen、server_name、location的配置

# Nginx静态资源的配置指令
# listen指令
# 语法 listen address[:port][default_server]
# 如:
listen 127.0.0.1:8000; # 监听指定ip和端口
listen 127.0.0.1:8000 default_server; # 监听指定ip和端口,并设置为默认连接。默认连接就是在服务列表中没有找到服务的时候默认访问该服务
listen 127.0.0.1;    # 监听指定ip下的所有端口
listen 8000;        # 监听指定端口下的连接
listen *:8000;        # 也是监听指定端口下的连接

# 补充知识点:/etc/hosts域名解析文件配置
# ,当本地浏览器访问某个域名的时候,首先会从/etc/hosts文件中查找,找不到再去dns中去找
# 所以你可以直接配置本地的域名
vim /etc/hosts
127.0.0.1 www.baidu.com

# server_name指令
# 语法 server_name name1  name2 name3 ……
# name的值可以是一个ip地址,也可以是域名,多个name之间需要用空格隔开
# 位置:只能在server中配置server_name
# 如:
server_name www.abc.cn www.a.cn

# server_name的配置方式有三种
# 1.精准配置
server_name www.abc.cn www.a.cn
# 2.通配符配置,通配符不能放在中部位置的,只能放在首尾位置
server_name *.abc.cn www.a.*
# 3.正则表达式配置
# 以正则配置server_name的时候必须以~开头
# 不明白正则怎么用的可以在该网站学习:https://www.runoob.com/regexp/regexp-syntax.html
# 这里的(\w+)小括号的内容你可以在下文通过$1的方式获取它的值
# 比如:输入的是www.abc123.com,那么$1的值就是abc123,你可以在日志中引用
# 如果有多个()按顺序$1 $2 $3 ……
server_name ~^www.\.(\w+)\.com;

# server_name 的匹配执行顺序
# 也就是当一个一个请求能匹配多个server_name的时候,到底执行哪个server_name
# 优先是精准匹配
# 然后是通配符在开头的server_name
# 再然后是通配符再结尾的server_name
# 最后是正则表达式的server_name
# 都没找到的话就返回defualt_server  也就是not found server。

# location指令
# 语法:localtion [= 、 ~ 、 ~* 、 ^~ 、 @] uri{...}
location /abc{
  default_type text/plain;
  return 200 'access success';
}
# =等号是精准匹配,
# www.abc.com/abc 和 www.abc.com/abc?a=123 都可以访问
# www.abc.com/abc/ 和 www.abc.com/abcd  都不能访问
location =/abc{
  default_type text/plain;
  return 200 'access success';
}
# ~和~*表示当前uri包含了正则表达式,它们之间的区别是~区分大小写,~*不区分大小写
# 能匹配 www.abc.com/abc1  www.abc.com/abcdef
# 不能匹配www.abc.com/abc
location ~*^/abc\w${
  default_type text/plain;
  return 200 'access success';
}

# ^~,注意它是不包含正则表达式的前面,功能和不加符号的一直,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了。
# location的搜索模式是一直往后搜索,然后取最后一个匹配的location
# ^~的存在就是,搜索到该location并且匹配成功,就直接停止向后搜索
location ^~/abc{
  default_type text/plain;
  return 200 'access success';
}

# root、alias都是设置请求资源的目录
# root语法:root path;
# 默认值:html
# alias语法:alias path;
# 默认值:无
# 当访问 localhost/images/mv.png时
# root情况下访问的文件路劲是 html/images/mv.png
# alias情况下范文的文件路径是 html/mv.png
# 得出结论是:
# root处理结果是:root路径+location路径
# alias处理结果是: alias路径替换location路径

location /images {
  root html;
}
location /images {
  alias html;
}

# index指令  配置访问目录下默认访问的文件。可以配置多个文件,空格隔开
# 它会从左往右依次去找,直到找到文件为止
# 语法:index file ...;
index index.html index.hml

# error_page 指令,用来设置网站的错误页面
# 语法:error_page code ... [=[response]] uri
# code是返回状态码
# 位置 http、server、location
# 可以直接指定具体跳转的地址
server {
  error_page 404 http://www.itcast.cn
}
# 可以指定重定向地址
server {
  error_page 404 50.html;
  error_page 500 502 503 504 /50x.html;
  location =/50x.html{
  root html;
  }
}
# @语法
server {
  error_page 404 @jump_to_error;
  error_page 500 502 503 504 /50x.html;
  location @jump_to_error{
    root html;
  }
}
# 可选项 =[response]的作用的是,将响应码重新修改
# 也就是location中return的响应码
# 这里本应该返回404响应码,当加上=200的时候它就返回200了,而不反悔404
server {
  error_page 404 =200 @jump_to_error;
  error_page 500 502 503 504 /50x.html;
  location @jump_to_error{
    root html;
  }
}

将Nginx配置成系统开机启动服务

# 如何将nginx配置成我们的系统服务
# 1.在/usr/lib/systemd/system目录下面配置nginx.service内容
# 如果想要详细了解制作的过程:https://blog.csdn.net/weixin_40596016/article/details/90485038
vim /usr/lib/systemd/system nginx.service
[Unit]
Description=nginx web service
Documentation=http://nginx.org/en/docs/
After=network.targe

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=True

[Install]
wanteBy=default.target

# 2.分配权限
chmod 755 /usr/lib/systemd/system/nginx.service

# 3.systemctl命令
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl status nginx
systemctl enable nginx  # 开机启动

# 4.将nginx配置到系统环境变量中
# 只需要在/etc/profile文件最后加上vim /etc/profile
export PATH=$PATH:/usr/local/nginx/sbin

Nginx 平滑升级、Nginx的一些基础配置

# Nginx 平滑升级
# 方案一:使用Nginx服务信号进行升级
# 1.将就版本的sbin目录下可执行nginx进行备份(mv nginx nginxold)
# 2.将新版本 configure、make 后会生成一个objs目录,你只要将objs/sbin目录下的nginx可执行文件拷贝到nginxold相同目录
# 3.发送kill  -USR2 `more /usr/local/logs/nginx.pid` 信号,这里不明白可以往上节翻
# 4.发送kill -QUIT `more /usr/local/logs/nginx.pid.oldbin`

# 方案二:Nginx实名make平滑升级
# 1.将就版本的sbin目录下可执行nginx进行备份(mv nginx nginxold)
# 2.将新版本 configure、make 后会生成一个objs目录,你只要将objs/sbin目录下的nginx可执行文件拷贝到nginxold相同目录
# 3.进入源码安装的目录执行 make upgrade
复制代码
复制代码
# Nginx 配置文件
worker_processes  1;   # worker 进程数量

events {    # 配置与用户网络连接
    worker_connections  1024;
}


http {        # 代理配置,一个http可以代理多个地址,所以这里可以设置有多个server
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;# 端口
        server_name  localhost;# 服务器名
        location / {    # 访问路径,localhost:80/
            root   html;    #配置访问目录,如果配置了user pc1;那么这里的目录指的是/home/pc1/html
            index  index.html index.htm;  # 当访问localhost:80/ 会在html目录下依次查找index.html index.htm文件,找到了就返回
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

# 配置worker进程所属用户,所以你可以对用户分配权限,让worker进程只能访问到该访问的内容
# user是配置指令,user_1用户名,group用户所属组,group默认值是和用户名一样
user user_1 [group]

# 配置master启动多少个worker进程
# 是否可以开启worker进程
master_process off/on;
# 配置master最多启动1个worker进程,master_process必须先注释不然就没用
worker_processes  1;

# 是否守护进程启动nginx,默认是on
# daemon on/off;

# 配置master 进程pid存放文件
pid        logs/nginx.pid;

# 配置错误日志路劲,info日志级别
# 日志级别有:debug 调试|info 信息|notice 通知|warn 警告|error 错误|crit 临界|alter 报警|emerg 紧急,
# info以下的等级都会带来大量的磁盘io消耗,影响Nginx的性能
# error_log不仅可以在全局配置,还可以在http/sever/location中配置
error_log  logs/error.log  [info];

# 多个文件分开配置。
# 这里是加载main.conf的配置信息,也可以这么加载 include /home/pc1/html/conf.d/*.conf,加载目录下.conf后缀的文件
include main.conf;

# events块配置:配置用户与Nginx服务的网络链接,这里的配置对服务器的影响比较大
# 配置Nginx网络链接序列化
# 所谓连接序列化只的是,
# 当有访问请求的时候该配置打开的时候所有worker进程都会过来拉取任务处理,而off的时候master会主动推给一个worker进程处理
# 默认off
accept_mutex on|off;

# 设置是否用户worker进程可以同时接受多个网络连接,默认值off
multi_accept on|off;

# 和multi_accept on一起使用,设置worker进程最大连接数
# 默认512
worker_connections number;

# 设置Nginx使用那种事件驱动来处理网络消息
# 类型有:select|poll|epoll|kqueue等
# 默认值是根据不同的操作系统决定
use method;
# 你也可以在源码安装的时候来配置
# --with-select_module        加入select
# --without-select_module    移除select
# --with-poll_module
# --without-poll_module

# http块
# NINE-Type   设置你对应的文件类型
include mime.types;   # 这里直接在http块配置引用的mime.types文件
default_type application/octet-stream;  
# 你可以查看mime.types文件,可以看到文件类型对应的后缀
# 你可以在http、server、location中配置它,那样的话location返回值的类型就是以配置的文件类型进行返回
# 因为web端不同的文件类型显示的方式是不一样的所以才需要该配置去进行协调

# 配置自定义服务器日志
# access_log 配置日志路径,log_format是日志的内容,$http_user_agent这是forma中的内置变量。后面再详细讲解
# 他们可以配置在http\server\location块中的
log_format mylog_format '============>This my format:$http_user_agent';
access_log logs/my.log log_format 1024;

# 该参数开启能大大提高磁盘读写的性能
# 默认是关闭的
sendfile on|off;

# 长连接超时时间
keepalive_timeout 75s;

# 长连接处理次数,当长连接处理100次后断开连接。
keepalive_requests 100;
# Nginx目录结构
# 首先推荐一个查看目录结构的工具 tree
# yum install -y tree  
# sudo apt-get install -y tree   ubuntu

# 查看nginx目录结构,我这里是默认安装目录,所以是/usr/local/nginx/
tree /usr/local/nginx/
/usr/local/nginx/
|-- client_body_temp
|-- conf    # 配置文件目录
|   |-- fastcgi.conf
|   |-- fastcgi.conf.default    # .default结尾是备份配置文件,也就是当你将配置文件搞坏了,你可以从默认配置开始重新配置
|   |-- fastcgi_params
|   |-- fastcgi_params.default
|   |-- koi-utf
|   |-- koi-win
|   |-- mime.types        # 文件名与文件后缀
|   |-- mime.types.default
|   |-- nginx.conf        # Nginx的配置文件
|   |-- nginx.conf.default
|   |-- scgi_params
|   |-- scgi_params.default
|   |-- uwsgi_params
|   |-- uwsgi_params.default
|   `-- win-utf
|-- fastcgi_temp
|-- html
|   |-- 50x.html    # nginx访问错误的时候返回页面
|   `-- index.html    # nginx首页
|-- logs
|   |-- access.log    # 访问日志
|   |-- error.log    # 错误日志
|   `-- nginx.pid    # nginx进程的PID
|-- proxy_temp
|-- sbin
|   `-- nginx        # 可执行二进制文件
|-- scgi_temp
`-- uwsgi_temp

# Nginx服务控制命令
# 1.Nginx服务的信号控制
# 查询nginx进程
ps -ef | grep nginx
# nginx有两个进程,分别是:master 和 worker进程
# 正确应该说Nginx有两种类型的进程
# worker接待用户的进程,也就是说并发量大的时候接待用的进程数量可以通过配置文件来配置
# master进程是管理worker进程的进程,也就是当有worker进程以外停止的时候master会启动新的worker进程,master进程会控制worker进程始终保持配置的进程数量
# Nginx信号:使用方法:kill -TERM 13673   13673就是master进程的pid
     1.TERM/INT    立即关闭整个服务
     2.QUIT        优雅关闭整个服务
     3.HUP        重新生效配置文件,master不会重启,但所有worker进程会重新启动
     4.USR1        重新打开日志文件,可以用来进行日志切割
     5.USR2        平滑升级到最新版本的nginx。在不关闭服务的情况下升级nginx。
     6.WINCH    所有子进程不再接受吃力链接,相当于给worker进程发送QUIT指令
     
# 这里学一个kill的新用法
# ``的用法,读取文件内容作为参数传递给kill命令
kill -QUIT `more /usr/local/nginx/logs/nginx.pid`

# 2.Nginx的命令控制
# 如何查看
复制代码
[root@VM-8-14-centos sbin]# ./nginx -h
nginx version: nginx/1.20.1
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
             [-e filename] [-c filename] [-g directives]

Options:
  -?,-h         : 帮助信息
  -v            : 简单的版本信息
  -V            : 详细版本信息
  -t            : 测试nginx.conf配置文件是否有问题
  -T            : 与-t区别是,成功的时候输出详细的配置信息
  -q            : 与t一起用,也就是测试期间只输出错误信息
  -s signal     : 给Nginx服务的master进程发送信号: stop, quit, reopen, reload
  -p prefix     : 设置源码路劲,一般不会去该它 (默认: /usr/local/nginx/)
  -e filename   : 设置错误日志路径 (默认: logs/error.log)
  -c filename   : 设置要加载的config文件路劲 (默认: conf/nginx.conf)
  -g directives : ./nginx -g "pid logs/abc.pid"   直接在运行的时候配置部分config,一般不建议这么用
# Nginx用户认证模块
# 主要应用业务:文件下载。当用户需要下载某些文件的时候,我们增加用户名和密码机制来进行用户验证。
# 该功能的实现是通过ngx_http_auth_basic_module模块来实现的
# 默认情况是已经安装了的,如果不需要使用就在configure的时候加上--without-http_auth_basic_module

# auth_basic指令:使用“http基本认知”协议启用用户名和密码的验证
# 开启后,服务端会返回401,指定的字符串会返回到客户端给用户提示信息,但是不同的浏览器显示内容不一致。
# 语法:auth_basic string:off;
# 默认值: off;
# 位置:http、server、location、limit_except

# auth_basic_user_file:指定用户名和密码所在文件
# 语法:auth_basic_user_file file;
# 默认值:无
# 位置:http、server、location、limit_except
# 例子:
location /download {
  root /usr/local;
  autoindex on;
  autoindex_exact_size on;
  autoindex_format html;
  autoindex_localtime on;
  auth_basic 'Please input your auth';
  auth_basic_user_file htpasswd;
}

# 用户名和密码的文件怎么生成:
# 1.安装生成工具httpd-tools
yum install -y httpd-tools
# 2.创建一个新文件,记录用户名和密码
htpasswd -c /usr/local/nginx/conf/htpasswd username
# 3.在指定文件新增一个用户名和密码
htpasswd -b /usr/local/nginx/conf/htpasswd username password
# 4.删除指定文件中的某个用户
htpasswd -D /usr/local/nginx/conf/htpasswd username
# 5.验证用户名和密码是否正确
htpasswd -v /usr/local/nginx/conf/htpasswd username
# 限制请求体的大小,若超过所设定的大小,返回413错误。
client_max_body_size  50m;
# 读取请求头的超时时间,若超过所设定的大小,返回408错误。
client_header_timeout 1m;
# 读取请求实体的超时时间,若超过所设定的大小,返回413错误。
client_body_timeout 1m
# http请求无法立即被容器(tomcat, netty等)处理,被放在nginx的待处理池中等待被处理。此参数为等待的最长时间,默认为60秒,官方推荐最长不要超过75秒。
proxy_connect_timeout 60s;
# http请求被容器(tomcat, netty等)处理后,nginx会等待处理结果,也就是容器返回的response。此参数即为服务器响应时间,默认60秒。
proxy_read_timeout 1m;
# http请求被服务器处理完后,把数据传返回给Nginx的用时,默认60秒。
proxy_send_timeout 1m;
1 # Nginx api接口调用配置
 2 
 3 # 什么是跨域同源?
 4 # 同源策略:协议(http、https、wss……)+域名+端口=一个完整的网站
 5 # 跨域:当前所在的网站post(get、option)请求到非同源的网站去
 6 
 7 # 一、直接配置请求头允许所有网站跨域请求
 8 add_header 'Access-Control-Allow-Origin' '*';
 9 # *号也可以改成你域名,就代表允许该域名对自己进行跨域请求
10 # 这样设置的话不好的是每次提交post或者get请求必须将请求的url写清楚
11 # 好处是,该接口是公开性,共任何公司任何网站进行接口数据传输调用
12 
13 # 二、直接给网站做代理连接
14 location /api {
15     proxy_pass http://odoo;
16 }
17 # 这样做好处是不用做跨域处理,
18 # 如果你的接口要公开给其他公司调用做数据传输的话,你还是使用上面那种方法
19 # 公司产品多的话那么每个产品都得需要维护一次
20 
21 # 建议:根据实际情况两种配合使用
# Nginx的拓展模块

# ngx_lua模块
# 淘宝开发的ngx_lua模块通过lua解释器集成近Nginx,可以采用lua脚本实现业务逻辑,由于lua的紧凑、快速以及内建协程,所以在保证宝兵法服务能力的同时极大地降低了业务逻辑实现成本
# ngx_lua模块环境准备
# 方式一:OpenRestry
# OpenRestry是由淘宝工程师开发的,其官网是(http://openresty.org/),其上提供了大量的Lua库、第三方模块以及大多数的依赖项。
# 用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网站。
# 所以OpenResty内部就已经集成了Nginx和Lua,所以我们使用起来会更加方便。

# 安装
# 1.下载:https://openresty.org/download/openresty-1.19.9.1.tar.gz
# 2.解压缩:tar -zxf openresty-1.19.9.1.tar.gz
# 3.进入解压缩后的目录:cd openresty-1.19.9.1
# 4.执行配置命令:./configure
# 5.执行编译和安装: make && make install
# 6.进入openresty目录,找到Nginx:cd /usr/local/openresty/nginx/
# 7.在conf目录下的Nginx.conf添加如下内容
location /lua {
  default_type 'text/html';
  content_by_lua 'ngx.say("<h1>Hello world,openresty</h1>")';
}
# 8.在sbin目录下启动nginx
# 9.通过浏览器访问测试

# 直接进入使用例子:
location /getByGender {
  default_type 'text/html';
  # set_by_lua
  set_by_lua $param "
    --获取请求URL上的参数对应值  name  gender
    local uri_args = ngx.req.get_uri_args()
    local name = uri_args['name']
    local gender = uri_args['gender']
    --  条件判断
    if gender=='1' then
      return name..'先生'
    elseif gender=='0' then
      return name..'女士'
    else
      return name
    end
  "
  charset utf-8;
  return 200 $param
}


# lua操作redis
# Redis在系统中经常作为数据缓存、内存数据库使用,在大型系统中扮演者非常重要的作用。在Nginx核心系统中,Redis是常备主键。
# Nginx支持3种方法访问Redis,分别是:HttpRedis模块、HttpRedis2Module、lua-resty-redis库。
# 这三种方式中HttpRedis模块提供的指令少,功能单一,合适做简单的缓存,HttpRedis2Module模块比HttpRedis模块操作更灵活,功能更强大。
#lua-resty-redis库是OpenResty提供的一个Redis的接口库,可根据自己的业务情况来做一些逻辑处理,社和做复杂的业务逻辑。
# 步骤一:lua-resty-redis环境准备:准备一台redis的服务器
# 步骤二:准备对应的API
# lua-resty-redis提供了访问Redis的详细API,包括创建对接、链接、操作、数据处理等。这些api基本上与Redis的操作一一对应
# 1.lua导入lua-resty-redis
redis = require "resty.redis"
# 2.new 语法。创建一个Redis对象
redis,err = redis:new()
# 3.connect  设置链接Redis的链接信息
ok,err=redis:connect(host,port[,options_table])
# ok:连接成功返回1,连接失败返回nil
# err:返回报错信息
# 4.set_timeout,设置请求操作Redis的超时时间
redis:set_timeout(time)
# 5.close  关闭当前链接。成功返回1,失败返回nil和错误信息
ok,err = redis:close()
# 6.redis命令对应的方法
# 在lua-resty-redis中,所有的Redis命令独有自己的方法,方法名字和命令明智相同,只是全是小写。


# 实例:
location /testRedis{
  default_type "text/html";
  content_by_lua_block{
    local redis = require "resty.redis"
    local redisObj = redis:new()
    redisObj:set_timeout(1000)
    local ok,err = redisObj:connect("192.168.200.111", 6379)
    if not ok then
      ngx.say("failed to connection redis", err)
      return
    end
    ok,err = redisObj:set("username", "ROSE")
    if not ok then
      ngx.say("faild to set username", err)
      return
    end
    local username, err = redisObj.get("username")
    if not username then
      ngx.say("faild to get username",err)
      return
    else
      ngx.say(username)
      
    redisObj:close()
  }
}

# ngx_lua操作Mysql
# 用ngx_lua模块和lua-resty-mysql模块:这两个模块是OpenResty默认安装的
# 你也可以用drizzle_nginx_module(HttpDrizzleModule)模块:这个库不在OpenResty中,所以需要独立安装
# lua-resty-mysql的使用
# API:
# 引入"resty.mysql"模块
local mysql = require "resty.mysql"
# new 创建一个Mysql连接对象,错误时返回Nil和错误信息
db,err = mysql:new()
# connect 连接Mysql服务器,options是一个Lua表结构,里边包含数据库连接的相关信息
# host(服务器ip或者名字)、port(Mysql服务的端口)、user(Mysql的登录用户)、password(登录密码)、database(要连接的数据库名)
ok,err = db:connect(options)
# set_timeout  设置请求超时时间(ms),包括connect,可以在connect之前设置
db:set_timeout(time)
# close 关闭当前连接
db:close()
# send_query  异步想远程Mysql发送一个查询语句
bytes,err=db:send_query(sql)
# read_result  从Mysql服务器返回的结果中读取一行数据。
res,err,errcode,sqlstate = db:read_result()
res,err,errcode,sqlstate = db:read_result(rows)
# 返回参数
# res:返回一个描述ok包,或结果集包的Lua表
# err:错误信息
# errcode:mysql的错误码
# sqlstate:sql语句的错误码
# 参数:rows:指定返回结果集的最大行数,默认4
# 如果成功
{
  {id=1,username="Tom"},
  {id=2,username="Jerry"},
}
# 如果是增删改:
{
  omsert_id = 0,
  server_status=2,
  warning_count=1,
  affected_rows=2,
  message=Nil
}

# 例一:
location /testMysql {
  default_type "text/html";
  content_by_lua_block{
    local mysql = require "resty.mysql"
    local db = mysql:new()
    local ok,err = db:connect{
      host="127.0.0.1",
      port=3306,
      user="root",
      password="123456",
      database="nginx_db"
    }
    db:set_timeout(1000)
    db:send_query("select * from from users")
    local res,err,errcode,sqlstate = db:read_result(4)
    ngx.say(res[1].id..","..res[1].username)
    db:close()
  }
}

# 例一的基础上,我们返回json字符串
location /testMysql {
  default_type "text/html";
  content_by_lua_block{
    local mysql = require "resty.mysql"
    local cjson = require "cjson"
    
    local db = mysql:new()
    local ok,err = db:connect{
      host="127.0.0.1",
      port=3306,
      user="root",
      password="123456",
      database="nginx_db"
    }
    db:set_timeout(1000)
    db:send_query("select * from from users")
    local res,err,errcode,sqlstate = db:read_result(4)
    --ngx.say(res[1].id..","..res[1].username)
    ngx.say(cjson.encode(res))
    
    db:close()
  }
}

# 在Nginx中配置全局变量init_ty_lua_block导入其他地方也要用到的cjson,防止重复require导入报错
init_ty_lua_block {
  cjson = require "cjson"
}


# query快捷方法。query集成了send_query和read_result方法。
# 语法:
res,err,errcode,sqlstate = db:query(sql[, rows])
 
应用架构之「Nginx+Keepalived」Web 集群方案

Nginx 是一个开源(遵循 BSD 协议)、高性能、高可靠的 Web 和反向代理服务器。主要用于 Web 应用的缓存和负载均衡,支持热部署、占用内存少、并发能力强,能支持高达 5w 个并发连接数。

Nginx 主要应用场景包括: 1、静态资源(静态 HTML 网站、文件、图片、音视频)的 Web 服务器; 2、Web 应用和服务的反向代理(负载均衡、缓存)服务器。

Keepalived是一个开源(遵循 GPLv2 协议)的、基于 VRRP 协议的轻量级服务高可用和负载均衡方案,提供避免服务器单点故障和请求分流的能力。它为 Nginx 扩展了高可用能力,共同组成完整的 Web 服务集群模式(高可用+负载均衡)。

目录

1.集群部署拓扑图

2.Web 应用服务器部署

3.Nginx 代理服务器的安装和配置

4.Keepalived 高可用中间件的安装和配置

附录一 Nginx 配置文件详解

附录二 Nginx 配置虚拟主机头

附录三 扩展 Nginx 客户端身份认证

附录四 扩展 Nginx 跨域访问

附录五 扩展 Nginx 网页压缩

附录六 Nginx 四层网络协议负载均衡

1.集群部署拓扑

 

 

 

Web应用集群部署拓扑图

网络资源规划:

1、Web 应用服务器节点

2、Nginx 高可用服务器节点

Keepalived Virtual IP:192.168.216.130。

Web 应用服务器可以使用任何中间件部署 WebSite 、WebApp 或者是通过 Http 协议提供服务的资源。需要注意的是:作为 Web 负载均衡的节点,发布的服务通常需要具备完全一致性,包括但不限于:数据源一致性、程序一致性、配置一致性。

常见的 Web 开源中间件:

本例采用 Python HttpServer 搭建静态站点的演示环境。

在各个 "Web 应用服务器节点" (Web-1、Web-2、Web-3)上制作、发布静态站点。以节点 "Web-1" 为例:

1、在用户主目录下创建静态站点。

使用文本编辑器创建 HTML 文件:

[centos@Web-1 ~ ]mkdir website
[centos@Web-1 ~ ]gedit ~/website/index.html

在文件中编写以下内容并保存:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>website-1</title>
</head>
<body>
【Nginx+Keepalived】Web 集群演示
</body>
</html>

注意: 为了演示 Nginx 负载均衡特性,"<title />"中定义各个站点的标识,三个 Web 站点依次为:"website-1"、"website-2"、"website-3";"<body />"中定义的内容必须一致,体现发布服务的一致性。

 

2、进入静态站点目录并发布站点。

[centos@Web-1 ~ ]cd website
[centos@Web-1 website ]sudo python3 -m http.server 80

3、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"80"端口访问服务器。

[centos@Web-1 ~ ]$ sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
[centos@Web-1 ~ ]$ sudo firewall-cmd --reload

4、使用浏览器访问 Web 服务。

Web 服务测试页面 

注意:其他 "Web 应用服务器节点" 全部需要按照以上步骤配置。

 

 

 

 

在各个 "Proxy 集群节点" (Proxy-1、Proxy-2)安装、配置 Nginx,以 "Proxy-1" 为例:

1、打开 Nginx 下载,下载 Nginx 的源代码 tar.gz 包到用户主目录中。

Nginx 下载页面

2、验证并安装依赖软件。通过源代码编译的方式安装 Nginx,需要依赖软件"make"、"gcc"、"pcre"、"pcre-devel"、"zlib"、"zlib-devel"、"openssl"、"openssl-devel",验证或安装依赖软件。

[centos@Proxy-1 ~]$ sudo dnf install make gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel

补充知识:

① "gcc"是一个C/C++、FORTRAN、JAVA、OBJC、ADA等多种语言的编译器,用来将源代码编译成可发布的软件程序。

② "make"是一个工程管理工具,能够根据 Makefile 中的脚本执行编译、安装流程。

③ "pcre"是一个正则表达式函数库;"pcre-devel"是它的开发库。

④ "zlib"是一个数据压缩函数库;"zib-devel"是它的开发库。 

⑤ "openssl"是一个实现安全通信,避免窃听,同时确认另一端连接者身份的软件程序;"openssl-devel"是它的开发库。

3、解压缩 Nginx 的源代码 tar 包到用户主目录下。

[centos@Proxy-1 ~]tar -zxvf nginx-1.18.0.tar.gz
[centos@Proxy-1 ~]ll
drwxr-xr-x. 8 centos centos 4096 4 21 22:09 nginx-1.18.0

4、安装 Nginx,进入源代码目录,配置、编译、安装程序。

[centos@Proxy-1 ~]$ cd nginx-1.18.0
[centos@Proxy-1 nginx-1.18.0]$ ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-stream
Configuration summary
+ using system PCRE library
+ OpenSSL library is not used
+ using system zlib library

nginx path prefix"/usr/local/nginx"
nginx binary file"/usr/local/nginx/sbin/nginx"
nginx modules path"/usr/local/nginx/modules"
nginx configuration prefix"/usr/local/nginx/conf"
nginx configuration file"/usr/local/nginx/conf/nginx.conf"
nginx pid file"/usr/local/nginx/logs/nginx.pid"
nginx error log file"/usr/local/nginx/logs/error.log"
nginx http access log file"/usr/local/nginx/logs/access.log"
nginx http client request body temporary files"client_body_temp"
nginx http proxy temporary files"proxy_temp"
nginx http fastcgi temporary files"fastcgi_temp"
nginx http uwsgi temporary files"uwsgi_temp"
nginx http scgi temporary files"scgi_temp"

[centos@Proxy-1 nginx-1.18.0]$ make
[centos@Proxy-1 nginx-1.18.0]$ sudo make install

[centos@Proxy-1 ~]$ ll /usr/local/nginx
drwxr-xr-x2 root root 4096 5 18 09:39 conf
drwxr-xr-x2 root root 40 5 18 09:39 html
drwxr-xr-x2 root root 6 5 18 09:39 logs
drwxr-xr-x2 root root 19 5 18 09:39 sbin

程序安装目录是"/usr/local/nginx"。

5、设置 Nginx 配置文件参数。

使用文本编辑器打开配置文件:

[centos@Proxy-1 ~ ]$ sudo gedit /usr/local/nginx/conf/nginx.conf

修改或验证文件中的以下参数并保存(七层代理):

http {

# 负载均衡
upstream website {
server 192.168.216.1:80 weight=1;
server 192.168.216.2:80 weight=1;
server 192.168.216.3:80 weight=1;
}

server {
# 监听端口
listen 80;

# 服务器域名(主机头)
server_name localhost;

# 代理 Web 服务的 Url 前缀,一般是 Web 服务的虚拟目录(可以是正则表达式)。
location / {
proxy_pass website;
}
}
}

在文件中追加以下参数并保存(四层代理):

stream {        # 负载均衡    upstream website {        server 192.168.216.1:80 weight=1;        server 192.168.216.2:80 weight=1;        server 192.168.216.3:80 weight=1;    }        server {        # 监听端口        listen       80;                # 代理服务位置        proxy_pass website;    }}

注意:两种方案二选一即可。

Web 代理一般使用七层协议代理,以便于实现主机头等站点路由功能; 四层协议可用于 Web 代理以外的负载均衡场景,如:MySQL 数据库只读连接等。

6、配置 Nginx 开机自启动。

使用文本编辑器创建配置文件:

[centos@Proxy-1 ~ ]$ sudo gedit /usr/lib/systemd/system/nginx.service

编写文件内容并保存如下:

[Unit]Description=NginxAfter=syslog.target network.target[Service]Type=forkingUser=rootGroup=rootExecStart=/usr/local/nginx/sbin/nginxExecReload=/usr/local/nginx/sbin/nginx -s reloadExecStop=/usr/local/nginx/sbin/nginx -s quitPrivateTmp=true[Install]WantedBy=multi-user.target 

设置开机启动: 

[centos@Proxy-1 ~ ]$ sudo systemctl daemon-reload[centos@Proxy-1 ~ ]$ sudo systemctl enable nginx.service

7、启动 Nginx 服务。

[centos@Proxy-1 ~ ]$ sudo systemctl start nginx.service

8、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"80"端口(Nginx 默认端口)访问服务器。

[centos@Proxy-1 ~ ]$ sudo firewall-cmd --zone=public --add-port=80/tcp --permanent[centos@Proxy-1 ~ ]$ sudo firewall-cmd --reload

注意:其他 "Proxy 集群节点" 全部需要按照以上步骤配置。 

9、Nginx 运维管理。

1)启动 Nginx 服务(任选一种方式)

[centos@Proxy-1 ~ ]$ sudo systemctl start nginx.service 

或者

[centos@Proxy-1 ~ ]$ sudo -u /usr/local/nginx/sbin/nginx 

2)停止 Nginx 服务(任选一种方式)

[centos@Proxy-1 ~ ]$ sudo systemctl stop nginx.service

或者

[centos@Proxy-1 ~ ]$ /usr/local/nginx/sbin/nginx -s quit

3)重启 Nginx 服务

[centos@Proxy-1 ~ ]$ sudo systemctl restart nginx.service

或者

[centos@Proxy-1 ~ ]$ /usr/local/nginx/sbin/nginx -s reload

4)查看 Nginx 服务状态

[centos@Proxy-1 ~ ]$ sudo systemctl status nginx.service

或者

[centos@Proxy-1 ~ ]sudo ps -ef | grep nginx
root 119777 1 0 10:16 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx

[centos@Proxy-1 ~ ]sudo netstat -ntap | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 119777/nginx: maste

[centos@Proxy-1 ~ ]sudo tail /usr/local/nginx/logs/error.log
[centos@Proxy-1 ~ ]sudo tail /usr/local/nginx/logs/access.log

5)启用 Nginx 服务开机自启动

[centos@Proxy-1 ~ ]$ sudo systemctl enable nginx.service

6)禁用 Nginx 服务开机自启动

 [centos@Proxy-1 ~ ]$ sudo systemctl disable nginx.service

4.Keepalived 高可用中间件的安装和配置

在各个 "Proxy 集群节点" (Proxy-1、Proxy-2)安装、配置 Keepalived,以 "Proxy-1" 为例:

1、安装 EPEL 的 Yum源。

使用文本编辑器创建仓库配置文件:

[centos@Proxy-1 ~ ]$ sudo gedit /etc/yum.repos.d/epel.repo

在文件中编写以下内容并保存:

[epel-modular]name=Extra Packages for Enterprise Linux Modular $releasever - $basearchbaseurl=mirrors.aliyun.com/epel/$releasever/Modular/$basearchenabled=1gpgcheck=1gpgkey=mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8[epel]name=Extra Packages for Enterprise Linux $releasever - $basearchbaseurl=mirrors.aliyun.com/epel/$releasever/Everything/$basearchenabled=1gpgcheck=1gpgkey=mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

更新 Yum 源:

[centos@Proxy-1 ~]$ sudo dnf clean all[centos@Proxy-1 ~]$ sudo dnf makecacheExtra Packages for Enterprise Linux Modular 8 - 429 kB/s | 118 kB     00:00    Extra Packages for Enterprise Linux 8 - x86_64  3.7 MB/s | 6.9 MB     00:01    元数据缓存已建立。

EPEL(Extra Packages for Enterprise Linux)是企业级 Linux 操作系统的扩展包仓库,为 Redhat/CentOS系统提供大量的额外软件包。

2、安装 Keepalived。

[centos@Proxy-1 ~]$ sudo dnf install keepalived

程序安装目录是"/usr/sbin",配置文件目录是"/etc/keepalived"。

3、设置 Keepalived 配置文件参数。 

使用文本编辑器打开配置文件:

[centos@Proxy-1 ~ ]$ sudo gedit /etc/keepalived/keepalived.conf

在文件中编写以下内容并保存:

# 定义全局配置
global_defs {
# 本地节点 ID 标识,一般设置为主机名。
router_id proxy-1
}

# 定义周期性执行的脚本,脚本的退出状态码会被调用它的所有的 vrrp_instance 记录。
vrrp_script chk_nginx {
# 执行脚本的路径。
script "/etc/keepalived/nginx_check.sh"
# 脚本执行的间隔(单位是秒)。默认为1s。
interval 2
# 当脚本调整优先级,从 -254 到 254。默认为2。
# 1. 如果脚本执行成功(退出状态码为0),weight大于0,则priority增加。
# 2. 如果脚本执行失败(退出状态码为非0),weight小于0,则priority减少。
# 3. 其他情况下,priority不变。
weight -20
# 当脚本执行超过时长(单位是秒)则被认为执行失败。
# 运行脚本的用户和组。
user root root
# timeout 30
# 当脚本执行成功到设定次数时,才认为是成功。
# rise 1
# 当脚本执行失败到设定次数时,才认为是失败。
# fall 3
}

# 定义虚拟路由,可以定义多个。
vrrp_instance VI_1 {
# 本地节点初始状态,包括 MASTER(主节点) 和 BACKUP (备节点)。
state MASTER
# 本地节点绑定虚拟 IP 的网络接口。
interface ens33
# 本地节点优先级,优先级高的节点将动态变成 MASTER 节点,接管 VIP 。初始状态下,MASTER 节点的优先级必须高于 BACKUP 节点。
priority 100
# VRRP 实例 ID,范围是0-255。同一集群的所有节点应设置一致的值。
virtual_router_id 216
# 组播信息发送时间间隔。同一集群的所有节点必须设置一样,默认为1秒。
advert_int 1
# 设置验证信息。同一集群的所有节点必须一致
authentication {
# 指定认证方式。PASS 表示简单密码认证(推荐);AH:IPSEC认证(不推荐)。
auth_type PASS
# 指定认证所使用的密码,最多8位。
auth_pass 1111
}

# 声明调用已定义的 vrrp_script 脚本。
track_script {
chk_nginx
}

# 定义虚拟 IP 地址。
virtual_ipaddress {
192.168.216.130
}
}
# 定义对外提供服务 LVS (负载均衡)的 VIP 和 端口(当端口号设置为【0】时,表示所有端口),只实现高可用时可不配置。
# 注意:本方案中,通过 Nginx 实现 Web 负载均衡,Keepalived 只实现高可用,因此负载均衡既可以不配置,也可以配置成 Nginx 的负载均衡;当没有 Ngxin 时,可以直接配置成 Web 的负载均衡。
virtual_server 192.168.216.130 80 {
# 设置健康检查时间,单位是秒
delay_loop 6
#负载均衡调度算法
lb_algo rr
# 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
lb_kind DR
# VIP 子网掩码
nat_mask 255.255.255.0
# 会话保持时间,一定时间之内用户无响应则下一次用户请求时需重新路由,一般设为0,表示不需要
persistence_timeout 0
# 网络协议
protocol TCP
# 定义后端 RealServer 的真实服务器属性,IP 地址和端口(当端口号设置为【0】时,表示所有端口)
real_server 192.168.216.128 80 {
# 配置节点权值,数字越大权重越高
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.216.129 80 {
weight 1
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}

初始化的主节点和备节点的区别体现在以下参数中:

  • 初始主节点

vrrp_instance VI_1 {
# 必须设置为 MASTER 。
state MASTER
# 必须设置为最大值。
priority 100
}
  • 初始备节点

vrrp_instance VI_1 {
# 必须设置为 BACKUP 。
state BACKUP
# 必须设置为小于主节点的值。
priority 90
}

4、创建或编辑 Nginx 检测脚本文件。文件路径对应配置文件中 vrrp_script 的 script 设置值。 

使用文本编辑器创建脚本文件:

[centos@Proxy-1 ~ ]$ sudo gedit /etc/keepalived/nginx_check.sh

在脚本文件中编写以下内容并保存:

#!/bin/bash
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" = "0" ]; then
/usr/local/nginx/sbin/nginx
sleep 2
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" = "0" ]; then
killall -9 keepalived
fi
fi

给脚本文件增加可执行权限:

[centos@Proxy-1 ~ ]$ sudo chmod 755 /etc/keepalived/nginx_check.sh 

5、配置 Keepalived 系统服务。

使用文本编辑器创建配置文件:

[centos@Proxy-1 ~ ]$ sudo gedit /usr/lib/systemd/system/keepalived.service

验证或修改文件内容并保存如下:

[Unit]Description=LVS and VRRP High Availability MonitorAfter=network-online.target syslog.target nginx.serviceWants=network-online.targetRequires=nginx.service[Service]Type=forkingUser=rootGroup=rootPIDFile=/var/run/keepalived.pidKillMode=processEnvironmentFile=-/etc/sysconfig/keepalivedExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONSExecReload=/bin/kill -HUP $MAINPIDExecStop=/bin/kill -HUP $MAINPID[Install]WantedBy=multi-user.target

重新加载系统服务管理器:

[centos@Proxy-1 ~ ]$ sudo systemctl daemon-reload

6、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"112"端口(Keepalived 默认端口)访问服务器。

[centos@Proxy-1 ~ ]$ sudo firewall-cmd --zone=public --add-port=112/tcp --permanent[centos@Proxy-1 ~ ]$ sudo firewall-cmd --reload

7、启动/重启 Keepalived 服务(不建议设置为开机自启动)。

启动 Keepalived 服务之前,应确保已正确启动了各节点的 Nginx 服务。各节点的启动或重启的顺序为:① 启动 Keepalived 主节点;② 依次启动 Keepalived 备节点。

[centos@Proxy-1 ~ ]$ sudo systemctl restart keepalived.service

8、启动 Keepalived 可能因为各种未知的原因失败,主要是由于引发了 SELinux 异常。

注意:其他 "Proxy 集群节点" 全部需要按照以上步骤配置。 

8、使用浏览器通过虚拟 IP 访问 Web 代理服务。

 

通过虚拟 IP 访问 Web 代理服务

附录一 Nginx 配置文件详解

位于程序配置目录 "/usr/local/nginx/conf" 下的 "nginx.conf" 是 Nginx 的主配置文件。主配置文件的参数包括:

#定义Nginx运行的用户和用户组
user root root;

#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;

#进程文件
pid /var/run/nginx.pid;

#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;

#工作模式与连接数上限
events{
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
use epoll;
#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 65535;
}

#四层负载均衡(以 MySQL 为例)
stream{
upstream mysql {
server 192.168.80.121:3306 weight=1;
server 192.168.80.122:3306 weight=2;
server 192.168.80.123:3306 weight=3;
}

server {
#监听端口
listen 3306;
proxy_pass mysql;
}
}

#设定http服务器
http{
include mime.types#文件扩展名与文件类型映射表
default_type application/octet-stream#默认文件类型
charset utf-8#默认编码
server_names_hash_bucket_size 128#服务器名字的hash表大小
client_header_buffer_size 32k#上传文件大小限制
large_client_header_buffers 4 64k#设定请求缓
client_max_body_size 8m#设定请求缓
#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
sendfile on;
autoindex on#开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on#防止网络阻塞
tcp_nodelay on#防止网络阻塞
keepalive_timeout 120#长连接超时时间,单位是秒

#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

#gzip模块设置
gzip on#开启gzip压缩输出
gzip_min_length 1k#最小压缩文件大小
gzip_buffers 4 16k#压缩缓冲区
gzip_http_version 1.0#压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2#压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用

#upstream的动态负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
upstream www.example.com {
server 192.168.80.121:80 weight=1;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}

#虚拟主机的配置
server {
#监听端口
listen 80;
#域名可以有多个,用空格隔开
server_name www.example.com example.com;
#设置默认主页
index index.html index.htm index.php;
#所有静态文件直接访问的物理磁盘的位置
root /data/www/example;
location ~ .*\.(php|php5)?${
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
#图片缓存时间设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*\.(js|css)?${
expires 1h;
}
#日志格式设定
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
#定义本虚拟主机的访问日志
access_log /var/log/nginx/ha97access.log access;

#对 "/" 启用反向代理
location / {
proxy_pass www.example.com # http://127.0.0.1:80;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host;
client_max_body_size 10m#允许客户端请求的最大单文件字节数
client_body_buffer_size 128k#缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90#nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90#后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90#连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k#设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k#proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k#高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
}

#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
}

#本地动静分离反向代理配置
#所有jsp的页面均交由tomcat或resin处理
location ~ .(jsp|jspx|do)?$ {
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_pass 127.0.0.1:8080;
}
#所有静态文件由nginx直接读取不经过tomcat或resin
location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
{
expires 15d;
}
location ~ .*.(js|css)?$
{
expires 1h;
}
}
}

1、"server" 包含多个 "location","location" 属性用于匹配 uri,语法:

location [ = | ~ | ~* | ^~uri {
...
}
  • 【=】表示精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;

  • 【^~】表示如果该符号后面的字符是最佳匹配,用于不含正则表达式的 uri 前缀,如果匹配成功,不再进行后续的查找;

  • 【~】表示用该符号后面的正则去匹配路径,区分大小写;

  • 【~*】表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个 "location" 的正则能匹配的话,则使用正则表达式最长的那个。

  • 如果 uri 包含正则表达式,则必须要有 ~ 或 ~* 标志。

 

2、Nginx 预定义了一些全局变量,可以在配置的任何位置使用它们,如下表:

其他预定义变量可在互联网上查询学习。

附录二 Nginx 配置虚拟主机头

使用文本编辑器打开配置文件:

[centos@host ~ ]$ sudo gedit /usr/local/nginx/conf/nginx.conf

修改或验证文件中的以下参数并保存:

http {
server {
# 监听端口
listen 80;
# 服务器域名(主机头)
server_name www.web1.net;
# 代理 Web 服务的 Url 前缀,一般是 Web 服务的虚拟目录(可以是正则表达式)。
location / {
proxy_pass http://127.0.0.1:81;
}
}
server {
# 监听端口
listen 80;
# 服务器域名(主机头)
server_name www.web2.net;
# 代理 Web 服务的 Url 前缀,一般是 Web 服务的虚拟目录(可以是正则表达式)。
location / {
proxy_pass http://127.0.0.1:82;
}
}
}
  • 两个 "server" 使用 "server_name" 定义的主机头来区分。 客户端需要在本地 DNS 文件(/etc/hosts)中定义域名解析记录,或者在网卡中设置能够解析主机头的私有 DNS 服务器。

  • 如果客户端通过 IP 地址访问,则等同于使用最后一个 "server" 的配置(本例中为: "server_name" 为 "www.web2.net" 的 "server")。

2、重新启动 Nginx 服务。

[centos@host ~ ]$ sudo systemctl restart nginx.service

附录三 扩展 Nginx 客户端身份认证

1、安装 httpd-tools 。

[centos@host ~ ]$ sudo dnf install httpd-tools

2、创建账户/口令数据文件。

[centos@host ~ ]$ sudo htpasswd -bc /usr/local/nginx/conf/auth.db root password

指令格式为:htpasswd -b[c] <数据文件位置> <账号> <口令>。参数 b 表示创建一组账号/口令,参数 c 表示创建数据文件 

3、设置 Nginx 配置文件参数。

使用文本编辑器打开配置文件: 

[centos@host ~ ]$ sudo gedit /usr/local/nginx/conf/nginx.conf 

修改或验证文件中的以下参数并保存:

http {
server {
......
location / {
......
auth_basic "input password";
auth_basic_user_file /usr/local/nginx/conf/auth.db;
}
}
}

4、重新启动 Nginx 服务。

[centos@host ~ ]$ sudo systemctl restart nginx.service

附录四 扩展 Nginx 跨域访问

 

1、设置 Nginx 配置文件参数。

使用文本编辑器打开配置文件:

[centos@host ~ ]$ sudo gedit /usr/local/nginx/conf/nginx.conf 

修改或验证文件中的以下参数并保存:

http {
server {
......
# 全局变量获得当前请求origin,带cookie的请求不支持 "*" 。
add_header 'Access-Control-Allow-Origin' $http_origin;
# 设置为 "true" 表示传递 cookie 。
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许跨域请求的方法。
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# 允许请求的 header,可以为 "*" 。
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

if ($request_method = 'OPTIONS') {
# OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;

return 204;
}

location / {
......
}
}
}

2、重新启动 Nginx 服务。

[centos@host ~ ]$ sudo systemctl restart nginx.service 

附录五 扩展 Nginx 网页压缩

1、设置 Nginx 配置文件参数。

使用文本编辑器打开配置文件:

[centos@host ~ ]$ sudo gedit /usr/local/nginx/conf/nginx.conf 

修改或验证文件中的以下参数并保存:

http {    server {        ......        # 是否开启 gzip , on 表示开启,off 表示禁用。默认off。        gzip on;        # 压缩 MIME 文件的类型,其中 text/html 被系统强制启用。        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;        location / {            ......        }    }}

2、重新启动 Nginx 服务。

[centos@host ~ ]$ sudo systemctl restart nginx.service

附录六 Nginx 四层网络协议负载均衡

1、设置 Nginx 配置文件参数。

使用文本编辑器打开配置文件:

[centos@host ~ ]$ sudo gedit /usr/local/nginx/conf/nginx.conf

修改或验证文件中的以下参数并保存:

#四层负载均衡(以 MySQL 为例)
stream{
upstream mysql {
server 192.168.80.121:3306 weight=1;
server 192.168.80.122:3306 weight=2;
server 192.168.80.123:3306 weight=3;
}

server {
#监听端口
listen 3306;
proxy_pass mysql;
}
}
[centos@host ~ ]$ sudo systemctl restart nginx.service
posted @ 2022-04-25 21:32  hanease  阅读(604)  评论(0编辑  收藏  举报