总字符数: 10.98K

代码: 6.19K, 文本: 2.21K

预计阅读时间: 37 分钟

Nginx安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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平滑升级

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 下载高版本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信号控制

从容关闭旧进程

具体语法: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配置文件详解

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

nginx配置连接数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 表示开启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

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head>
<title>server1 首页</title>/ head>
<body>
<h1>server1 首页</h1></body>
</html>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 下面我们回到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服务在运行的时候,会有各种操作,操作的信息会记录到日志文件中,日志文件的记录是有格式的.那我们如何设置日志文件的格式呢?

1
2
3
# 使用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"';

access_log指令

1
2
3
4
# 语法:
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以日期命名存放

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

系统自动切割

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

opt/目录下编写sh脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 进入目录
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/ {...}

  2. location区分普通匹配和正则匹配

    1
    2
    3
    4
    5
    6
    用前缀"~"" \~*"修饰的为正则匹配
    ~ 前缀表示区分大小写的正则匹配
    ~* 前缀表示不区分大小写的正则匹配
    除上面修饰的前缀("=""^~",或没有前缀修饰)都为普通匹配
    = 前缀表示精确匹配
    ^~前缀表示uri以某个常规字符串开头,可以理解为url的普通匹配

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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. 普通匹配,最大前缀匹配原则

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      server {
        location /prefix/ {
               #规则A
        }
        location /prefix/mid/ {
               #规则B
        }
       }
      请求ur1为:/prefix/mid/t.html
      此请求匹配的是规则B,是以最大的匹配原则进行的,跟顺序无关
    2. 正则匹配 为顺序匹配

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      server {
           location ~ \.(gifljpglpngljscss)$
      {
        #规则C
        }
        location~* \.png$
      {
        #规则D
        }
       }
      请求http://localhost/1.png,匹配的是规则c,因为规则c在前面,即叫做顺序匹配
    3. 在实际场景中,通常至少有三个匹配规则定义

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      #直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理.
      #这里是直接转发给后端应用服务器了,也可以是一个静态首页
      #第一个必选规则
      location =/ {
      ····
      }
      #第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
      #有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
      location ^~ /static/ {
      root /webroot/static/;
      }
      location ~* \.(gifjpgjpegpngcssjsico)$ {
      root /webroot/res/;
      }
      #第三个规则就是通用规则,用来转发动态请求到后端应用服务器
      #非静态文件请求就默认是动态请求,自己根据实际把握
      #毕竟目前的一些框架的流行、带.php,.jsp后缀的情况很少了
      location / {
      ·····
      }

负载均衡

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

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

1
2
3
4
5
6
7
8
9
10
11
 upstream myproxy{
  server 10.10.1.2:8080;
  server 10.10.1.3:8080;
 }
 server{
  listen 80;
  server\_name wordpress-1258894728.cos.ap-beijing.myqcloud.com;
  location / {
  proxy\_pass http://myproxy;
  }
 }

负载均衡方案

  1. 随机(轮询)

    1
    2
    3
    4
    upstream myproxy{
    server 10.10.1.2:8080;
    server 10.10.1.3:8080;
    }
  2. 权重

    1
    2
    3
    4
    upstream myproxy{
    server 10.10.1.2:8080 weight=5;
    server 10.10.1.3:8080 weight=10;
    }
  3. ip_hash

    1
    2
    3
    4
    5
    upstream myproxy{
    ip_hash;
    server 10.10.1.2:8080;
    server 10.10.1.3:8080;
    }