二.Nginx相关知识

Nginx安装

cd /opt
# Nginx下载
wget http://nginx.org/download/nginx-1.13.0.tar.gz
# 解压
tar -zxvf nginx-1.13.0.tar.gz
# 安装依赖
yum -y install gcc gcc-c++ ncurses-devel perl pcre pcre-devel zlib gzip zlib-devel
# Nginx编译
./configure --prefix=/usr/local/nginx
# 安装Nginx
make & make install
# 安装路径:/usr/local/nginx
conf 存放配置文件
html 网页文件
logs 存放日志
sbin shell启动、停止等脚本

Nginx平滑升级

把服务器从低版本升级为高版本,强行停止服务器,会影响正在运行的进程.平滑升级不会停掉正在进行中的进程,这些进程会继续处理请求.但不会再接受新请求,这些老的进程在处理完请求之后会停止.此平滑升级过程中,新开的进程会被处理.

# 下载高版本nginx
wget http://nginx.org/download/nginx-1.13.1.tar.gz
# configure
./configure
# 编译平滑升级不要进行安装,不要make install
make
# 进入objs目录有高版本的nginx
cd objs
# 备份低版本的nginx
cp /usr/sbin/nginx ./nginx.old
# 执行强制覆盖
cp -rfp objs/nginx /usr/sbin/
# 测试一下新复制过来文件生效情况
/usr/local/nginx/sbin/nginx -t
ps -ef | grep nginx
# 执行信号平滑升级
kill -USR2 主程序进程号
# 给nginx发送USR2信号后,nginx会将1ogs/nginx.pid文件重命名为nginx.pid.oldbin,然后用新的可执行文件启动一个新的nginx主进程和对应的工作进程,并新建一个新的nginx.pid保存新的主进程号
ps -ef | grep nginx
kill -WINCH 旧的主进程号
# 旧的主进程号收到WINCH信号后,将旧进程号管理的旧的工作进程优雅的关闭.即一段时间后旧的工作进程全部关闭,只有新的工作进程在处理请求连接.这时,依然可以恢复到旧的进程服务,因为旧的进程的监听socket还未停止.处理完后,工作进程会自动关闭
ps -ef | grep nginx
KILL -QUIT 旧的主进程号
# 给旧的发送QUIT信号后,旧的主进程退出,并移除nginx.pid.oldbin文件,nginx升级完成
# 升级完成后,看一下升级后的版本
/usr/sbin/nginx -v

# 中途停止升级,回滚到旧的nginx不在升级
# 在以上 kill -WINCH 旧的主进程号 这个步骤时,如果想回到旧的nginx,不再进行升级
# 1. 给旧的主进程号发送HUP命令,此时nginx不重新读取配置文件的情况下重新启动旧主进程的工作进程.
kill -HUP 旧主进程号
# 2. 优雅的关闭新的主进程
kill -QUIT 新主进程号

Nginx命令

  1. nginx启动
    • nginx/nginx -c nginx配置文件
  2. nginx重启(重启是建立在nginx服务器已经启动的基础上)
    • nginx -s reload
  3. nginx停止
    • nginx -s stop stop是快速关闭,不管有没有正在处理的请求
    • nginx -s quit quit是一个优雅的关闭方式,Nginx在退出前完成已经接受的连接请求
  4. nginx 重启打开日志
    • nginx -s reopen
  5. nginx检查配置文件
    • nginx -t

Nginx信号控制

信号类型说明
INT,TERM快速关闭信号
QUIT从容关闭信号
HUP从容重启信号,一般用于修改配置文件后重启
USR1重读日志,一般用于日志的切割
USR2平滑升级信号
WINCH从容关闭旧进程

具体语法:kill -信号选项 nginx的主进程号

例:kill -INT 26661

ps -ef | grep nginx获得进程号

  1. 从容"优雅"停止
    • kill -QUIT master进程号
    • Nginx服务可以正常地处理完当前所有请求再停止服务
    • 步骤:首先会关闭监听端口,停止接收新的连接,然后把当前正在处理的连接全部处理完,最后再退出进程
  2. 快速停止
    • kill -TERM master进程号
    • kill -INT master进程号
    • 快速停止服务时,worker进程与master进程在收到信号后会立刻跳出循环,退出进程
  3. 强制停止
    • kill -9 nginx系统强杀nginx进程
  4. 重启nginx
    • kill -HUP master进程号

Nginx基本配置

Nginx配置文件详解

# Nginx的主配置文件是:nginx.conf,nginx.conf主要组成如下:
# 全局区有一个工作子进程,一般设置为CPU数*核数
worker_processes 1;
events {
    # 一般是配置nginx进程与连接的特性
    # 如1个word能同时允许多少连接,一个子进程最大允许连接1024个连接
    worker_connections 1024;
}
# 配置HTTP服务器配置段
http {
    # 配置虚拟主机段
    server {
        # 定位,把特殊的路径或文件再次定位。
        location {
        }
    }
    server {
    }
}

nginx配置连接数

# 表示开启nginx的worker进程的个数,nginx启动会开两种进程,master进程用来管理调度,worker进程用来处理请求:
worker_processes:1;
# 两种设置方法,比如
# 方法一:
worker_processes auto;
# 表示设置服务器cpu核数匹配开启nginx开启的worker进程数
# 查看cpu核数:cat /proc/cpuinfo
# 方法二:nginx设置cpu亲和力
worker_processes 8;
worker_cpu_affinity 00000001 0000010 00000100 00001000 00010000 00100000 01000000 10000000;
# 00000001表示启用第一个CPU内核,00000010表示启用第二个CPU内核,以此类推
# worker_cpu_affinity:表示开启八个进程,第一个进程对应着第一个CPU内核,第二个进程对应着第二个CPU内核,以此类推.
# 这种设置方法更高效,因将每个cpu核提供给固定的worker进程服务,减少cpu上下文切换带来的资源浪费
# 如果服务器cpu有限 比如:2核CPU,开启2个进程,设置如下
worker_processes 2;
worker_cpu_affinity 01 10;
# 比如:4核CPU,开启4个进程,设置如下
worker_processes 2;
worker_cpu_affinity 0001 0010 0100 1000;
# 1个worker进程能够最大打开的文件数(线程数)worker_connections 65535 (参考worker_rlimit_nofile)

nginx作为http服务器

最大的客户端连接数 max_cloents = worker_processes * worker_connections/2

nginx作为反向代理服务器的时候

最大的客户端连接数 max_cloents = worker_processes * worker_connections/4

由此,我们可以进算出nginx作为http服务器最大并发量(作为反向代理服务器自己类推),可以作为压测和线上环境的优化提供一些理论依据:

单位时间keepalive_timeoutnginx最大并发量CC = worker_processes * worker_connections/2=8*65535/2

每秒并发量CS:CS = worker_processes * worker_connections/(2*65)

虚拟主机

虚拟主机(英语:virtual hosting)或称 共享主机(shared web hosting),又称虚拟服务器,是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术.虚拟主机之间完全独立,并可由用户自行管理,虚拟并非指不存在,而是指空间是由实体的服务器延伸而来,其硬件系统可以是基于服务器群,或者单个服务器。

其技术是互联网服务器采用的节省服务器硬件成本的技术,虚拟主机技术主要应用于HTTP,FTP,EMAIL等多项服务,将一台服务器的某项或者全部服务内容逻辑划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源.如果划分是系统级别的,则称为虚拟服务器.

配置虚拟主机

我们先配置在一个nginx中配置一个虚拟主机,编辑nginx.conf配置文件,在http模块中,配置server模块,一个server模块就针对一个虚拟主机. 我们模拟一个独立的网站,此网站域名访问为www.server1.com;网站的根目录放到nginx目录下htm1/server1目录,我们创建一个首页index.htmlserver1中,编辑index.html

<!DOCTYPE html>
<html>
<head>
<title>server1 首页</title>/ head>
<body>
<h1>server1 首页</h1></body>
</html>

下面我们回到nginx.conf配置文件中,配置server模块

# 下面我们回到nginx.conf配置文件中,配置server模块
server {
# 监听80端口
listen 80;
# 虚拟主机名,可以为域名或ip地址
server_name www.server1.com;
# 默认请求路由,以后文章中会重点介绍
location / {
        # 网站的根目录
        root html/server1; 
        # 默认首页文件名
		index index.html index.htm;
    }
}
server {
# 监听80端口
listen 80;
# 虚拟主机名,可以为域名或ip地址
server_name www.server2.com;
# 默认请求路由,以后文章中会重点介绍
location / {
        # 网站的根目录
        root html/server2; 
        # 默认首页文件名
		index index.html index.htm;
    }
}

注意:在配置server模块时,监听的端口listenserver_name组合起来是唯一的,如果server_name一样,那么listen监听的端口就不一样:如端口一样,server_name就不一样.这是很好理解的,虚拟主机的请求映射系统才能够判别。

日志文件格式配置

nginx服务在运行的时候,会有各种操作,操作的信息会记录到日志文件中,日志文件的记录是有格式的.那我们如何设置日志文件的格式呢?

# 使用log_format指令进行配置文件格式
# nginx的1og_format有很多可选的参数用于指示服务器的活动状态,默认的是:
log_format main '$remote_addr - $remote_user [$time_local] "$request"' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
参数说明示例
$remote_addr客户端地址211.28.65.253
$remote_user客户端用户名称--
$time_local访问时间和时区16/Sep/2021:17:00:01 +0800
$request请求的URI和HTTP协议"GET /article.html HTTP/1.1"
$http_host请求地址,即浏览器中你输入的地址(IP或域名)www.jiangjiyue.com 192.168.100.100
$statusHTTP请求状态200
$upstream_statusupstream状态200
$body_bytes_sent发送给客户端文件内容大小1547
$http_refererurl跳转来源https://www.baidu.com/
$http_user_agent用户终端浏览器等信息"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
$ssl_protocolSSL协议版本TLSv1
$ssl_cipher交换数据中的算法RC4-SHA
$upstream_addr后台upstream的地址,即真正提供服务的主机地址10.10.10.100:80
$request_time整个请求的总时间 0.205
$upstream_response_time请求过程中,upstream响应时间0.002
$http_x_forwarded_for反向代理服务器转发客户端地址的参数--

假设将Nginx服务器作为Web服务器,位于负载均衡设备、SquidNginx反向代理之后,不能获取到客户端的真实IP地址.原因是经过反向代理后,由于在客户端和Web服务器之间增加了中间层,因此Web服务器无法直接拿到客户端的IP. 通过$remote_addr变量拿到的将是反向代理服务器的IP地址.

但是,反向代理服务器在转发请求的HTTP头信息中,可以增加X-Forwanded-For信息,用以记录原有的客户端IP地址和原来客户端请求的服务器地址。 这时候,要用log_format指令设置日志格式,让日志记录X-Forearded-For信息中的IP地址,即客户的真实IP.

access_log指令

# 语法:
access_log path [format [buffer=size [flush=time]]];
access_log path format gzip[=level] [buffer=size] [flush=time];
access_log off;

配置段:

gzip压缩等级。 buffer设置内存缓存区大小。 flush保存在缓存区中的最长时间。不记录日志:access_log off; 使用默认combined格式记录日志:access_log logs/access.logaccess_log logs/access.log combined;值得注意的是,Nginx进程设置的用户和组必须对日志路径有创建文件的权限,否则,会报错. 此外,对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭.可以使用open_log file_cache来设置日志文件缓存(默认是off).

日志切割

wordpress.log---->wordpress-2021-09-16.log以日期命名存放

# 将log文件修改为想存放的日志格式
mv mv access.log access-2021-09-16.log
# 查看Nginx进程号
ps -ef | grep nginx
# 发送重读日志信号
kill -USR1 nginx进程号
# 通过mv命令 把当前的log文件重读命令,再用信号控制指令 发送重读日志指令 产生了新的日志log文件

系统自动切割

利用sh脚本的方式执行刚才的手动操作,在每天凌晨执行一个计划任务调用sh脚本,就完成了系统自动切割日志文件

opt/目录下编写sh脚本

# 进入目录
cd /opt
# 创建脚本文件
touch cutlog.sh
# 打开文件
vim cutlog.sh
# 以下是文件内容
#!/bin/bash
# 根据自己的logs路径修改一下路径
LOGS_PATH=/usr/local/nginx/logs/wordpress
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
# 根据自己的日志文件名修改下方access.log名称
mv ${LOGS_PATH}/wordpress_access.log ${LOGS_PATH}/wordpress_access_${YESTERDAY}.1og
#向 Nginx主进程发送USR1信号。USR1信号是重新打开日志文件
kill -USR1 $(cat /usr/local/nginx/nginx/logs/nginx.pid) 
# 保存并退出(按ESC键输入)
:wq
# 给sh脚本赋予权限
chmod +x cutlog.sh
# 设置定时任务
vim /etc/crontab
# 定时每天00:00以root身份执行脚本/opt/cutlog.sh
0 0 * * * root /opt/cutlog.sh
# 实现定时定点自动切割日志文件

location配置详解

  1. 语法规则:location [=|~|~*|^~] /uri/ {...}

    构成:

    指令前缀uri
    location[=|~|~*|^~]/uri
  2. location区分普通匹配和正则匹配
    用前缀“~”和“ \~*”修饰的为正则匹配
    ~ 前缀表示区分大小写的正则匹配
    ~* 前缀表示不区分大小写的正则匹配
    除上面修饰的前缀(“=”和“^~”,或没有前缀修饰)都为普通匹配
    = 前缀表示精确匹配
    ^~前缀表示uri以某个常规字符串开头,可以理解为url的普通匹配

    location作用于server模块,且支持多个location模块

    server {
           location /test {
    	             root html/p;
    	             index index.html index.htm;
    	}
            location = /50x.html {
    	              root html;
    	}
            location / {
    		root html/server1;
    		index index.html index.htm;
             }
    }
  3. 匹配的原则
    1. 普通匹配,最大前缀匹配原则
      server {
        location /prefix/ {
               #规则A
        }
        location /prefix/mid/ {
               #规则B
        }
       }
      请求ur1为:/prefix/mid/t.html
      此请求匹配的是规则B,是以最大的匹配原则进行的,跟顺序无关
    2. 正则匹配 为顺序匹配
      server {
           location ~ \.(gifljpglpngljs|css)$ 
            {
                       #规则C
           }
           location~* \.png$ 
            {
                         #规则D
             }
       }
      请求http://localhost/1.png,匹配的是规则c,因为规则c在前面,即叫做顺序匹配
    3. 如果location有普通匹配也有正则匹配,那匹配的原则为
      匹配模式顺序
      location = /uri=开头表示精确匹配,只有完全匹配上才能生效.
      location ^~ /uri^~开头对URL路径进行前缀匹配,并且在正则之前.
      location ~ pattern~开头表示区分大小写的正则匹配.
      location ~* pattern~*开头表示不区分大小写的正则匹配.
      location /uri不带任何修饰符,也表示前缀匹配,但是在正则匹配之后。
      location /通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中default。

      首先匹配=,其次匹配^~,其次是按文件中顺序的正则匹配,不带前缀的普通匹配,最后是交给/通用匹配.当有匹配成功时候,停止匹配,按当前匹配规则处理请求.

      # 如下匹配规则
      location = / {
      	return 200 '规则A';
      }
      location = /login {
      	return 200 '规则B';
      }
      location ^~ /static/ {
      	return 200 '规则C';
      }
      location ~ \.(gif|jpg|png|js|css)$ {
      	return 200 '规则D';
      }
      location ~* \.js ${
      	return 200 '规则E';
      location / {
      	return 200 '规则F';
      }
      
      地址规则
      http://localhost/将匹配规则A
      http://localhost/login将匹配规则B
      http://localhost/register将匹配规则F
      http://localhost/static/a.html将匹配规则c
      http://localhost/a.css匹配规则D
      http://localhost/b.js则优先匹配到规则D
      http://localhost/static/c.js则优先匹配到规则C
      http://localhost/a.3.jS则匹配规则E 而不会匹配规则D,因为规则E不区分大小写
      http://localhost/category/id/1则最终匹配到规则F,因为以上规则都不匹配
    4. 在实际场景中,通常至少有三个匹配规则定义
      #直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理。
      #这里是直接转发给后端应用服务器了,也可以是一个静态首页
      #第一个必选规则
      location =/ {
          ····
      }
      #第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
      #有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
      location ^~ /static/ {
      	root /webroot/static/;
      }
      location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
      	root /webroot/res/;
      }
      #第三个规则就是通用规则,用来转发动态请求到后端应用服务器
      #非静态文件请求就默认是动态请求,自己根据实际把握
      #毕竟目前的一些框架的流行、带.php,.jsp后缀的情况很少了
      location / {
          ·····
      }

负载均衡

负载平衡(Load balancing)是一种电脑技术,用来在多个电脑(电脑集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。 使用带有负载平衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载平衡服务通常是由专用软件和硬件来完成。 主要作用是将大量作业合理地分摊到多个操作单元上进行执行,用于解决互联网架构中的高并发高可用的问题。

    nginx实现负载均衡原理,用户访问首先访问到nginx服务器,然后nginx服务器再从应用服务器集群中选择压力比较小的服务器,然后将该访问请求引向该服务器.如果应用服务器集群中某一台服务器崩溃,那么从待选择服务器列表中将该服务器删除,也就是说一个服务器崩溃了,那么nginx服务器不会把请求引向到该服务器。

     upstream myproxy{
         server 10.10.1.2:8080;
         server 10.10.1.3:8080;
     }
     server{
         listen 80;
         server_name www.jiangjiyue.com;
         location / {
             proxy_pass http://myproxy;
         }
     }

    负载均衡方案

    1. 随机(轮询)
      upstream myproxy{
      	server 10.10.1.2:8080;
      	server 10.10.1.3:8080;
      }
    2. 权重
      upstream myproxy{
      	server 10.10.1.2:8080 weight=5;
      	server 10.10.1.3:8080 weight=10;
      }
    3. ip_hash
      upstream myproxy{
          ip_hash;
          server 10.10.1.2:8080;
          server 10.10.1.3:8080;
      }

      版权声明:
      作者:江霁月
      链接:https://www.jiangjiyue.com/maintenance/gateway/435.html
      来源:江霁月的私人小屋
      文章版权归作者所有,未经允许请勿转载。

      THE END
      分享
      二维码
      打赏
      < <上一篇
      下一篇>>
      文章目录
      关闭
      目 录