Nginx

Nginx

Nginx是一款轻量级Web服务器/反向代理服务器,占用内存少,并发能力强

下载和安装

源码安装
  1. 官网下载

    老版本下载

  2. 安装依赖包

    GCC编译器:Nginx是使用C语言编写的程序,因此想要运行Nginx就需要安装一个编译工具。GCC就是一个开源的编译器集合,用于处理各种各样的语言,其中就包含了C语言。

    PCRE:Nginx在编译过程中需要使用到PCRE库(perl Compatible Regular Expressoin 兼容正则表达式库),因为在Nginx的Rewrite模块和http核心模块都会使用到PCRE正则表达式语法。

    zlib:在Nginx的各个模块中需要使用gzip压缩

    OpenSSL:是一个开放源代码的软件库包,应用程序可以使用这个包进行安全通信,并且避免被窃听。

    1
    2
    # -y表示需要用户确认的地方默认yes
    yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
  3. 解压nginx安装包

    最好放到一个特定的目录下管理,以后删除还需要

    1
    tar -zxvf nginx-1.16.1.tar.gz
  4. 进入目录执行命令来安装nginx

    1
    2
    3
    4
    检查环境,配置环境变量,设置安装到哪
    ./configure --prefix=安装路径
    编译安装
    make && make install
yum安装

相比源码安装,会添加有很多额外的配置信息

  1. 通过yum进行安装

    1
    yum install -y nginx
  2. 查看安装的目录

    1
    whereis nginx
  3. 启动

    1
    2
    3
    4
    # 默认安装到了/usr/sbin,配置文件在/etc/ngin/nginx.conf
    cd /usr/sbin
    # 启动
    ./nginx

卸载

源码方式
  1. 停止nginx

    1
    ./nginx -s stop
  2. 删除nginx文件夹

    1
    rm -rf nginx/
  3. 到之前解压出来的源码目录下

    1
    make clean
yum方式
  1. 停止nginx

    1
    2
    ./nginx -s stop
    service nginx stop
  2. 删除nginx自动启动

    1
    chkconfig nginx off
  3. 删除nginx本地文件

    1
    2
    3
    rm -rf /usr/sbin/nginx
    rm -rf /etc/nginx
    rm -rf /etc/init.d/nginx
  4. yum清理

    1
    yum remove nginx

目录结构

  • conf/nginx.conf nginx配置文件
  • conf/mime.types HTTP协议中Content-Type的值和文件后缀名对应关系
  • html 存放静态文件
  • logs 存放日志
  • sbin 二进制文件,用于启动、停止nginx

启动/关闭方式

信号控制方式
信号 作用
TERM/INT 立即关闭整个服务
QUIT “优雅”地关闭整个服务
HUP 重读配置文件并使用服务对新配置项生效
USR1 重新打开日志文件,可以用来进行日志切割
USR2 平滑升级到最新版的nginx
WINCH 所有子进程不在接收处理新连接,相当于给work进程发送QUIT指令

通过kill -signal PID来使用

命令方式

./nginx -h 查看所有参数

-t:检查配置文件是否有错误

-s:signal信号,后面可以跟stop[快速关闭]、quit[优雅关闭]、reopen[重新加载日志文件]、reload[重新加载配置文件]

-c:指定配置文件

平滑升级

不需要停止nginx服务器就可以升级版本

  1. 准备两个版本的Nginx分别是 1.14.2和1.16.1,1.14.2的编译安装,1.16.1的只需要编译

    1
    2
    3
    4
    5
    6
    # 1.14.2
    ./configure
    make && make install
    # 1.16.1
    ./configure
    make
  2. 首先备份老版本的nginx下的sbin/nginx

    1
    2
    cd /usr/local/nginx/sbin
    mv nginx nginxold
  3. 拷贝新版本的nginx的/objs/nginx到老版本nginx的sbin/目录下

    1
    2
    cd ~/nginx/core/nginx-1.16.1/objs
    cp nginx /usr/local/nginx/sbin
  4. 执行make upgrade进行升级

  5. ./nginx -v查看版本

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nginx目录下

1.查看nginx版本
./sbin/nginx -v

2.测试配置文件是否有错
./sbin/nginx -t

3.启动nginx服务
./sbin/nginx

4.停止nginx服务
./sbin/nginx -s stop

5.修改过配置文件后,重新加载配置文件
./sbin/nginx -s reload

配置文件

分为三大块:全局块、events块、http块

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
worker_processes  1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;

server {
listen 80;
# 支持正则,以~开头,如:~^www\.\w+\.com;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

}
全局块
user指令

指定启动运行工作进程的用户及用户组,这样对于系统的权限访问控制的更加精细,也更加安全。

  1. 在配置文件中设置用户信息

    1
    user www;
  2. 创建一个linux用户

    1
    useradd www
  3. 创建/home/www/html/index.html 文件,在www用户目录下用户有访问权限

    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

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    body {
    width: 35em;
    margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif;
    }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>

    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>

    <p><em>Thank you for using nginx.</em></p>
    <p><em>I am WWW</em></p>
    </body>
    </html>
  4. 修改配置,测试访问

    1
    2
    3
    4
    location / {
    root /home/www/html;
    index index.html index.htm;
    }
work process指令
  1. master_process on|off:用来指定是否开启工作进程,默认on
  2. worker_processes num/auto:配置Nginx生成工作进程的数量,建议将该值和服务器CPU的内核数保存一致

这两个配置完要停止nginx再启动才会生效

其他指令
指令 作用
daemon on|off 设定Nginx是否以守护进程的方式启动,默认on
pid file 配置Nginx当前master进程的进程号ID存储的文件路径
error_log file [日志级别] 配置Nginx的错误日志存放路径,日志级别越低显示的信息越多
include file 引入其他配置文件
events块

主要用来设置nginx和用户的网络连接

指令 作用
accept_mutex on|off 设置Nginx网络连接序列化。off时为当来了一个请求,会唤醒多个worker来竞争; on时则将会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收
multi_accept on|off 设置一个工作进程是否允许同时接收多个网络连接
worker_connections number 配置单个worker进程最大的连接数,默认512
use method 设置Nginx服务器选择哪种事件驱动来处理网络消息,select/poll/epoll/kqueue

例子

1
2
3
4
5
6
events {
accept_mutex on;
multi_accept on;
use epoll;
worker_connections 1024;
}
http块
指定MIME-Type

通过default_type mime-type;来指定返回数据的类型,可以配置在http、server、location中

例子

1
2
3
4
5
6
7
8
9
location /get_text {
#这里也可以设置成text/plain
default_type text/html;
return 200 "This is nginx's text";
}
location /get_json{
default_type application/json;
return 200 '{"name":"TOM","age":18}';
}
自定义服务日志
指令 作用
access_log path [format] 设计用户访问请求日志的位置,后面可以跟日志输出格式
log_format name 指定日志的输出格式
sendfile on|off 是否使用sendfile()传输文件,该属性可以大大提高Nginx处理静态资源的性能
keepalive_timeout time 设置长连接的超时时间
keepalive_requests number 设置一个keep-alive连接使用的次数
server块和location块

server块

指令 作用
listen address[:port] 配置监听端口
server_name name 设置虚拟主机服务名称。可用正则,如果同时匹配多个,则选最精确的

location块

  1. location [ = |~ |* |^ |@ ] uri{…}

    设置请求的URI,=精确匹配,正则,*正则不区分大小写,^~用于不包含正则表达式的uri前(和不加符号功能一致,但如果模式匹配,就停止搜索其他模式)

  2. root / alias path

    root的处理结果是: root路径+location路径
    alias的处理结果是:使用alias路径替换location路径
    alias是一个目录别名的定义,root则是最上层目录的含义。
    如果location路径是以/结尾,则alias也必须是以/结尾,root没有要求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 浏览器'/images/1.png' 匹配到 '/usr/local/nginx/html/images/1.png'
    location /images {
    root /usr/local/nginx/html;
    }

    # 浏览器'/images/1.png' 匹配到 '/usr/local/nginx/html/1.png'
    location /images {
    alias /usr/local/nginx/html;
    }
  3. index path

    设置网站的默认首页

  4. error_page code … [=[response]] uri

    设置网站的错误页面

    后面可以跟具体地址、重定向地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server {
    error_page 404 http://www.baidu.com;
    }

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

    还可以用来修改状态码

    1
    2
    3
    4
    5
    6
    7
    # 返回的状态码为200
    server{
    error_page 404 =200 /50x.html;
    location =/50x.html{
    root html;
    }
    }
静态资源优化配置语法
1
2
3
4
5
6
# 开启高效的文件传输模式,类似
sendfile on;
# 必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输效率,缓存满了才发送
tcp_nopush on;
# 该指令必须在keep-alive连接开启的情况下才生效,来提高网络包传输的'实时性'
tcp_nodeplay on;
1
2
3
4
5
6
7
8
9
10
11
12
13
# 开启压缩功能
gzip on;
# 配置需要压缩的文件类型,如application/javascript text/html
gzip_types MIME类型;

# 设置Gzip压缩程度,1最低
gzip_comp_level 1-9;
# 是否携带“Vary:Accept-Encoding”头域的响应头部,用来告诉接收方使用了压缩处理
gzip_vary on|off;
# 通过正则匹配User-Agent头里的信息来,选择性地关闭Gzip功能
gzip_disable regex;
# 设置当文件大小大于length时才压缩
gzip_min_length length;
添加模块步骤

以添加http_gzip_static_module为例

  1. 查询当前Nginx的配置参数

    1
    nginx -V
  2. 将nginx安装目录下sbin目录中的nginx二进制文件进行更名(保存旧的)

    1
    mv nginx nginxold
  3. 进入Nginx的安装目录

    1
    cd /root/nginx/core/nginx-1.16.1
  4. 执行make clean清空之前编译的内容

    1
    make clean
  5. 使用configure来配置参数

    1
    ./configure --with-http_gzip_static_module 后面把第一步查到的配置参数加上
  6. 使用make命令进行编译

    1
    make
  7. 将objs目录下的nginx二进制执行文件移动到nginx安装目录下的sbin目录中

    1
    mv objs/nginx /usr/local/nginx/sbin
  8. 执行更新命令

    1
    make upgrade
  9. 修改配置文件

    1
    2
    3
    4
    # 开启gzip_static
    gzip_static on;
    # reload重新加载配置文件,之后如果存在gz压缩好的文件,就会直接返回压缩好的
    # gzip压缩文件指令:gzip 文件路径
缓存相关指令
  1. 指定缓存时间,填off不缓存
1
expires [modified] time
  1. 添加响应头

    1
    add_header name value

    Cache-Control作为响应头信息,可以设置如下值

    指令 说明
    must-revalidate 可缓存但必须再向源服务器进行确认
    no-cache 缓存前必须确认其有效性
    no-store 不缓存请求或响应的任何内容
    no-transform 代理不可更改媒体类型
    public 可向任意方提供响应的缓存
    private 仅向特定用户返回响应
    proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
    max-age=<秒> 响应最大Age值
    s-maxage=<秒> 公共缓存服务器响应的最大Age值

跨域问题

同源: 协议、域名(IP)、端口相同即为同源

如果从服务器A的页面发送异步请求到服务器B获取数据,如果服务器A和服务器B不满足同源策略,则就会出现跨域问题。

解决方式

添加Access-Control-Allow-Origin来设置允许跨域访问的源地址信息

添加Access-Control-Allow-Methods来设置允许跨域访问的请求方式

例如

1
2
3
4
5
6
7
location /getUser{
# *表所有地址都可以
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
default_type application/json;
return 200 '{"id":1,"name":"TOM","age":18}';
}

防盗链

盗链:将别人网页的内容放到自己的页面上

防盗链原理

通过判断HTTP的头信息Referer来判断获取资源的请求来源,只对允许的来源开放链接

防盗链步骤

例子

1
2
3
4
5
6
7
8
location /images {
valid_referers none blocked www.baidu.com 192.168.200.222 *.example.com example.* www.example.org ~\.google\.;
if ($invalid_referer){
return 403;
}
root /usr/local/nginx/html;

}

Rewrite功能配置

主要的作用是用来实现URL的重写

可以用来做域名跳转、域名镜像、给每个模块设置独立域名、合并目录

规则
  1. set

    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
    set $variable value


    server {
    listen 8081;
    server_name localhost;
    location /server {
    set $name Tom;
    set $age 18;
    default_type text/plain;
    return 200 $name=$age;
    }
    }
    nginx有预设的全局变量
    例:用全局变量记录日志
    log_format main '$remote_addr - $request - $status - $request_uri - $http_user_agent';

    server {
    listen 8081;
    server_name localhost;
    location /server {
    access_log logs/access.log main;
    set $name Tom;
    set $age 18;
    default_type text/plain;
    return 200 $name=$age;
    }
    }
  2. if

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if  (condition){...}

    1. 如果变量名对应的值为空或者是0if都判断为false,其他条件为true
    2. 使用"=""!="比较变量和字符串是否相等,满足条件为true,不满足为false

    if ($request_method = POST){
    return 405;
    }
    3. 使用正则表达式对变量进行匹配,匹配成功返回true,否则返回false。变量与正则表达式之间使用"~","~*","!~","!~\*"来连接。
    4. 判断请求的文件是否存在使用"-f""!-f", 判断请求的目录是否存在使用"-d""!-d"
  3. break

    1
    2
    该指令用于中断当前相同作用域中的其他Nginx配置
    会去找与访问路径对应目录下的index.html文件
  4. return

    1
    2
    3
    return code [text];
    return code URL;
    return URL;
  5. rewrite

    1
    2
    3
    4
    5
    6
    7
    rewrite regex replacement
    replacement:匹配成功后,用于替换URI中被截取内容的字符串
    flag:用来设置rewrite对URI的处理行为,可选值有如下:
    - last: 替换完后重新匹配
    - break: 替换完后去找与访问路径对应目录下的index.html文件
    - redirect:永久重定向
    - permanent:临时重定向
  6. rewrite_log

    1
    2
    3
    4
    5
    rewrite_log on\|off
    配置是否开启URL重写日志的输出功能
    rewrite_log的日志输出级别为notice
    所以需要设置日志输出级别为notice才能看到日志
    error_log logs/error.log notice;

反向代理

  1. proxy_pass

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    proxy_pass URL
    设置被代理服务器地址,可以是主机名称、IP地址加端口号形式


    server{
    listen 80;
    server_name localhost;
    location /server{
    #proxy_pass http://192.168.200.146;
    proxy_pass http://192.168.200.146/;
    }
    }
    url后面加/则最终找的是url/index.html,不加则为url/server/index.html
  2. proxy_set_header

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    proxy_set_header field value
    更改Nginx服务器接收到的客户端请求的请求头信息


    server {
    listen 8080;
    server_name localhost;
    default_type text/plain;
    return 200 $http_username;
    }
    server {
    listen 8081;
    server_name localhost;
    location /server {
    proxy_pass http://47.96.80.163:8080;
    proxy_set_header username Cat;
    }
    }
  3. proxy_redirect

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    proxy_redirect redirect replacement;
    redirect:目标,Location的值
    replacement:要替换的值
    重置头信息中的"Location""Refresh"的值


    服务端[192.168.200.146]
    server {
    listen 8081;
    server_name localhost;
    if (!-f $request_filename){
    return 302 http://192.168.200.146;
    }
    }
    代理服务端[192.168.200.133]
    server {
    listen 8081;
    server_name localhost;
    location / {
    proxy_pass http://192.168.200.146:8081/;
    proxy_redirect http://192.168.200.146 http://192.168.200.133;
    }
    }
  4. 具体案例

    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
    34
    35
    36
    37
    38
    39
    案例:将不同请求代理到不同服务器

    代理服务器
    server {
    listen 8082;
    server_name localhost;
    location /server1 {
    proxy_pass http://192.168.200.146:9001/;
    }
    location /server2 {
    proxy_pass http://192.168.200.146:9002/;
    }
    location /server3 {
    proxy_pass http://192.168.200.146:9003/;
    }
    }

    服务端
    server1
    server {
    listen 9001;
    server_name localhost;
    default_type text/html;
    return 200 '<h1>192.168.200.146:9001</h1>'
    }
    server2
    server {
    listen 9002;
    server_name localhost;
    default_type text/html;
    return 200 '<h1>192.168.200.146:9002</h1>'
    }
    server3
    server {
    listen 9003;
    server_name localhost;
    default_type text/html;
    return 200 '<h1>192.168.200.146:9003</h1>'
    }

第七层负载均衡

负载均衡作用
  1. 解决服务器的高并发压力,提高应用程序的处理性能。
  2. 提供故障转移,实现高可用。
  3. 通过添加或减少服务器数量,增强网站的可扩展性。
  4. 在负载均衡器上进行过滤,可以提高系统的安全性。
实例

被代理服务器:47.96.80.163:9001、47.96.80.163:9002、47.96.80.163:9003

负载均衡器:47.96.80.163:8081

默认方式为轮询

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
34
35
36
server {
listen 9001;
server_name localhost;
default_type text/html;
location / {
return 200 '<h1>9001</h1>';
}
}
server {
listen 9002;
server_name localhost;
default_type text/html;
location / {
return 200 '<h1>9002</h1>';
}
}
server {
listen 9003;
server_name localhost;
default_type text/html;
location / {
return 200 '<h1>9003</h1>';
}
}
upstream backend {
server 47.96.80.163:9001;
server 47.96.80.163:9002;
server 47.96.80.163:9003;
}
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://backend;
}
}
负载均衡状态
状态 概述
down 当前的server暂时不参与负载均衡
backup 预留的备份服务器,其他主服务器挂了才会被用到
max_fails 允许请求失败的次数
fail_timeout 经过max_fails次失败后, 服务暂停的时间
max_conns 限制最大的接收连接数

设置方式示例

1
2
3
4
5
upstream backend {
server 47.96.80.163:9001 down;
server 47.96.80.163:9002 backup;
server 47.96.80.163:9003 max_fails=3 fail_timeout=15;
}
负载均衡策略
算法名称 说明
轮询 默认方式
weight 权重方式
ip_hash 依据ip分配方式
least_conn 依据最少连接方式
url_hash 依据URL分配方式
fair 依据响应时间方式

示例

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 1.配置权重,权重越大被分配的概率越大,默认为1
upstream backend {
server 47.96.80.163:9001 weight=2;
server 47.96.80.163:9002;
server 47.96.80.163:9003;
}

# 2.配置ip_hash,同一个ip只会被分配到同一台服务器上
upstream backend {
ip_hash;
server 47.96.80.163:9001;
server 47.96.80.163:9002;
server 47.96.80.163:9003;
}

# 3.配置least_conn,会把请求转发给连接数较少的服务器上
# 适合请求处理时间长短不一造成服务器过载的情况
upstream backend {
least_conn;
server 47.96.80.163:9001;
server 47.96.80.163:9002;
server 47.96.80.163:9003;
}

# 4.配置url_hash,根据访问url的hash结果来分配请求
upstream backend {
hash $request_uri;
server 47.96.80.163:9001;
server 47.96.80.163:9002;
server 47.96.80.163:9003;
}

# 5.配置fair,智能的进行负载均衡
# 需要安装第三方模块
(1)下载 https://github.com/gnosek/nginx-upstream-fair,解压到linux,重命名为fair
(2)sbin/nginx -V 查看之前的参数信息,并备份原nginx文件
(3)到nginx源文件目录,./configure --add-module=fair所在路径 + 之前的参数信息
(4)修改src/http/ngx_http_upstream.h文件,找到ngx_http_upstream_srv_conf_s,
添加in_port_t default_port
(5)make
(6)将objs下的nginx复制到nginx文件夹下的sbin目录
(7)make upgrade
(8)测试
upstream backend {
fair;
server 47.96.80.163:9001;
server 47.96.80.163:9002;
server 47.96.80.163:9003;
}

第四层负载均衡

需要安装stream模块,在配置参数的时候加上--with-stream

示例

stream和http块是平级的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stream {
upstream redisbackend {
server 192.168.200.146:6379;
server 192.168.200.146:6378;
}
upstream tomcatbackend {
server 192.168.200.146:8080;
}
server {
listen 81;
proxy_pass redisbackend;
}
server {
listen 82;
proxy_pass tomcatbackend;
}
}

集成缓存

Module ngx_http_proxy_module (nginx.org)

相关指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# proxy_cache_path:缓存存放路径;
# levels:缓存文件层级,如2:1表示请求url经过MD5加密后取最后两个字符和倒数第三个字符来组成存放文件夹,如/ab/c;
# keys_zone:为缓存区设置名称和大小;
# inactive:缓存存活时间,超过存活时间没有被访问就会被删除;max_size:设置最大缓存空间
# proxy_cache:开启缓存
# proxy_cache_key:根据key值MD5哈希存缓存,默认$scheme$proxy_host$request_uri
# proxy_cache_valid:对不同返回状态码的URL设置不同的缓存时间,如404 1d、any 30s
proxy_cache_path /home/nginx/proxy_cache levels=2:1 keys_zone=cache:200m
inactive=1d max_size=20g;
server {
proxy_cache 缓存区名称;
proxy_cache_key web缓存的key值;
proxy_cache_vaild code time;
add_header nginx-cache "$upstream_cache_status"; # 添加头信息来查看是否使用了缓存
proxy_cache_min_uses number; # 访问number次后才会缓存
...
}

清除缓存

方式1:删除对应的缓存目录(删除所有缓存)

1
rm -rf 目录

方式2:ngx_cache_purge(删除指定缓存块的缓存)

github地址

安装ngx_cache_purge第三方模块

1
2
3
4
5
6
7
# 配置
# 之后浏览器访问对应路径就能删除缓存
server{
location ~/purge(/.*) {
proxy_cache_purge 缓存块名称 缓存的key;
}
}
设置不缓存的资源

1
2
3
4
5
6
7
8
9
10
11
server{
listen 8080;
server_name localhost;
location / {
if ($request_uri ~ /.*\.js$){
set $nocache 1;
}
proxy_no_cache $nocache $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $nocache $cookie_nocache $arg_nocache $arg_comment;
}
}

安全控制

Nginx使用SSL(Secure Sockets Layer),需要安装--with-http_ssl_module模块

相关指令

Module ngx_http_ssl_module (nginx.org)

搭建集群

使用Keepalived来解决,Keepalived 软件由 C 编写的,最初是专为 LVS 负载均衡软件设计的,Keepalived 软件主要是通过 VRRP 协议实现高可用功能。

VRRP(Virtual Route Redundancy Protocol)

1
2
虚拟路由冗余协议,VRRP可以把一个虚拟路由器的责任动态分配到局域网上的 VRRP 路由器中的一台。其中的虚拟路由即Virtual路由是由VRRP路由群组创建的一个不真实存在的路由,这个虚拟路由也是有对应的IP地址。而且VRRP路由1和VRRP路由2之间会有竞争选择,通过选择会产生一个Master路由和一个Backup路由。
Master路由和Backup路由之间会有一个心跳检测,Master会定时告知Backup自己的状态,如果在指定的时间内,Backup没有接收到这个通知内容,Backup就会替代Master成为新的MasterMaster路由有一个特权就是虚拟路由和后端服务器都是通过Master进行数据传递交互的,而备份节点则会直接丢弃这些请求和数据,不做处理,只是去监听Master的状态
安装keepalived
  1. 官网下载https://keepalived.org/,上传到linux服务器上

  2. 创建keepalived目录,将压缩包解压到目录

    1
    tar -zxf 压缩包名 -C keepalived/
  3. 编译、安装

    1
    2
    3
    4
    5
    6
    7
    cd keepalived/keepalived-2.0.20

    # sysconf:配置文件所在目录
    # prefix:keepalived要安装的目录
    ./configure --sysconf=/etc --prefix=/usr/local

    make && make install
配置keepalived

配置文件在/安装目录/keepalived/keepalived.conf

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
global全局部分:
global_defs {
#通知邮件,当keepalived发送切换时需要发email给具体的邮箱地址
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
#设置发件人的邮箱信息
notification_email_from zhaomin@itcast.cn
#指定smpt服务地址
smtp_server 192.168.200.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
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
VRRP部分,该部分可以包含以下四个子模块
1. vrrp_script
2. vrrp_sync_group
3. garp_group
4. vrrp_instance
我们会用到第一个和第四个,
#设置keepalived实例的相关信息,VI_1为VRRP实例名称
vrrp_instance VI_1 {
state MASTER #有两个值可选MASTER主 BACKUP备
interface ens33 #vrrp实例绑定的接口,用于发送VRRP包[当前服务器使用的网卡名称]
virtual_router_id 51#指定VRRP实例ID,范围是0-255
priority 100 #指定优先级,优先级高的将成为MASTER
advert_int 1 #指定发送VRRP通告的间隔,单位是秒
authentication { #vrrp之间通信的认证信息
auth_type PASS #指定认证方式。PASS简单密码认证(推荐)
auth_pass 1111 #指定认证使用的密码,最多8位
}
virtual_ipaddress { #虚拟IP地址设置虚拟IP地址,供用户访问使用,可设置多个,一行一个
192.168.200.222
}
}
启动keepalived
  1. 启动

    1
    2
    cd /安装目录/local/sbin
    ./keepalived
  2. ip a查看ip,虚拟IP(VIP)会在MASTER节点上,当MASTER节点上的keepalived出问题以后,因为BACKUP无法收到MASTER发出的VRRP状态通过信息,就会直接升为MASTER。VIP也会”漂移”到新的MASTER。

  3. 可以通过编写脚本来检测当nginx进程挂了的时候关闭keepalived,从而自动切换master到另一台nginx上

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 编写脚本ck_nginx.sh,该脚本的意思是检查nginx进程是否在运行,
    # 如果检测不到nginx进程,则关闭keepalived

    #!/bin/bash
    num=`ps -C nginx --no-header | wc -l`
    if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then
    killall keepalived
    fi


    # 给脚本设置权限
    chmod 755 ck_nginx.sh


    # 在keepalived配置文件中添加对应的配置像
    vrrp_script 脚本名称
    {
    script "脚本位置"
    interval 3 #执行时间间隔
    weight -20 #动态调整vrrp_instance的优先级
    }

制作下载站点

  1. 将要被下载的资源放到一个目录下

  2. 修改nginx配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    location /download{
    # 被下载资源路径
    root /usr/local;
    # 开启功能
    autoindex on;
    # 是否展示文件大小
    autoindex_exact_size on;
    # 目录列表的格式,可以是html/xml/json/jsonp,默认html
    autoindex_format html;
    # 是否在目录列表上显示时间
    autoindex_localtime on;
    }

Lua

Lua是用标准C语言编写并以源代码形式开发。设计的目的是为了嵌入到其他应用程序中,从而为应用程序提供灵活的扩展和定制功能。应用在游戏开发、独立应用脚本、web应用脚本、扩展和数据库插件、系统安全上。

官网

安装
  1. 下载压缩包到服务器

    1
    wget https://www.lua.org/ftp/lua-5.4.4.tar.gz
  2. 检查环境

    1
    make linux test
  3. 编译安装

    1
    make install
  4. 查看版本

    1
    lua -v
交互方式

1.交互式

通过命令lua进入控制台

1
2
# lua
> print("Hello World")

2.脚本式

创建hello.lua文件,编写脚本

1
2
3
4
5
6
7
8
9
10
11
# vim hello.lua

# 编写脚本
print("Hello World")

# 执行
chmod 755 hello.lua
lua hello.lua

# 也可以在文件开头指定解释器,执行的时候直接用文件名就行了
#!/usr/local/bin/lua
基本语法
注释

单行注释

1
-- 注释

多行注释

1
2
3
--[[

--]]

多行注释只需要在前面多加一个-就可以取消

运算符

逻辑运算符

1
2
3
and -->
or -->
not -->

其他运算符

1
2
.. 连接字符串
# 返回字符串或表的长度
定义变量

默认为全局变量,定义局部变量要在前面加local

1
2
a = 10;
local b = 20;
数据类型
1
2
3
4
5
6
7
8
nil(空,无效值)
boolean(布尔,true/false)
number(数值):只有false和nil为假
string(字符串)
function(函数)
table(表)
thread(线程)
userdata(用户数据)

可以用来表示数组、字典或混合使用,下标从1开始

1
2
3
4
5
6
7
8
9
10
11
12
13
# 定义一个表
arr = {}
arr = {"a", "b", "c"}
arr = {X = 10, Y = 20, Z = 30}
arr = {"a", X = 10, "b"}

# 获取表里的值
arr = {"a", X = 10, "b"}
arr[0] -- nil
arr[1] -- "a"
arr[2] -- "b"
arr["X"] -- 10
arr.X -- 10
方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 定义函数
function f(params)
-- 方法的内容
end

# 方法定义的参数并非都要传入,传入的会按顺序赋值,没赋值的参数为nil;如果传入的参数数量大于方法需要的参数数量,则会丢弃多出来的参数

# 可变长参数
function f(...)
a, b, c = ...;
print(a, b, c);
end

# 方法返回值数量也是可变的
function f()
return 1, 2, 3;
end
条件判断

if

1
2
3
4
5
6
7
if 条件 then
-- 代码
elseif 条件 then
-- 代码
else
-- 代码
end
循环

while

1
2
3
while 条件 do
-- 代码
end

repeat

直到满足条件才退出循环

1
2
3
repeat
-- 代码
until 条件

for

1
2
3
4
5
6
7
8
9
10
11
-- 循环从start开始到end结束;step为步长,默认为1
for param=start,end,step do
循环体
end

-- 遍历表
-- ipairs为迭代器,x为表
-- ipairs不能遍历出键值对,要遍历键值对要用pairs
for i,v in ipairs(x) do
循环体
end
OpenResty

OpenResty是一个基于Nginx与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。OpenResty内部已经集成了Nginx和Lua。

安装
  1. 下载、解压压缩包 OpenResty - Download

    1
    2
    wget https://openresty.org/download/openresty-1.15.8.2.tar.gz
    tar -zxvf openresty-1.15.8.2.tar.gz
  2. 进入openresty目录,编译安装

    1
    2
    ./configure
    make && make install
  3. 默认安装位置/usr/local/openresty/nginx/

    1
    cd /usr/local/openresty/nginx/
  4. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 修改配置
    location /lua{
    default_type 'text/html';
    content_by_lua 'ngx.say("<h1>HELLO,OpenRestry</h1>")';
    }

    # 测试
    ./sbin/nginx -t
    # 启动
    ./sbin/nginx

    # 浏览器访问
使用ngx_lua指令

init_by_lua

1
该指令在每次Nginx重新加载配置时执行,可以用来完成一些耗时模块的加载,或者初始化一些全局配置。

init_worker_by_lua

1
该指令用于启动一些定时任务,如心跳检查、定时拉取服务器配置等。

set_by_lua

1
该指令只要用来做变量赋值,这个指令一次只能返回一个值,并将结果赋值给Nginx中指定的变量。

rewrite_by_lua

1
该指令用于执行内部URL重写或者外部重定向,典型的如伪静态化URL重写,本阶段在rewrite处理阶段的最后默认执行。

access_by_lua

1
该指令用于访问控制。例如,如果只允许内网IP访问。

content_by_lua

1
该指令是应用最多的指令,大部分任务是在这个阶段完成的,其他的过程往往为这个阶段准备数据,正式处理基本都在本阶段。

header_filter_by_lua

1
该指令用于设置应答消息的头部信息。

body_filter_by_lua

1
该指令是对响应数据进行过滤,如截断、替换。

log_by_lua

1
该指令用于在log请求处理阶段,用Lua代码处理日志,但并不替换原有log处理。

balancer_by_lua

1
该指令主要的作用是用来实现上游服务器的负载均衡器算法

ssl_certificate_by_lua

1
该指令作用在Nginx和下游服务开始一个SSL握手操作时将允许本配置项的Lua代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
location /getByGender {
default_type 'text/html';
set_by_lua $name "
local uri_args = ngx.req.get_uri_args()
gender = uri_args['gender']
name = uri_args['name']
if gender=='1' then
return name..'先生'
elseif gender=='0' then
return name..'女士'
else
return name
end
";
header_filter_by_lua "
ngx.header.aaa='bbb'
";
return 200 $name;
}
ngx_lua操作Redis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
lua-resty-redis提供了访问Redis的详细API,包括创建对接、连接、操作、数据处理等。这些API基本上与Redis的操作一一对应。
1)redis = require "resty.redis"
2new
语法: redis,err = redis:new(),创建一个Redis对象。
3)connect
语法:ok,err=redis:connect(host,port[,options_table]),设置连接Redis的连接信息。
ok:连接成功返回 1,连接失败返回nil
err:返回对应的错误信息
4)set_timeout
语法: redis:set_timeout(time) ,设置请求操作Redis的超时时间。
5close
语法: ok,err = redis:close(),关闭当前连接,成功返回1,失败返回nil和错误信息
6)redis命令对应的方法
lua-resty-redis中,所有的Redis命令都有自己的方法,方法名字和命令名字相同,只是全部为小写。

ngx_lua操作mysql
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
34
35
36
37
38
39
40
41
42
43
44
45
46
1)引入"resty.mysql"模块
local mysql = require "resty.mysql"
2new
创建一个MySQL连接对象,遇到错误时,db为nil,err为错误描述信息
语法: db,err = mysql:new()
3connect
尝试连接到一个MySQL服务器
语法:ok,err=db:connect(options),options是一个参数的Lua表结构,里面包含数据库连接的相关信息
host:服务器主机名或IP地址
port:服务器监听端口,默认为3306
user:登录的用户名
password:登录密码
database:使用的数据库名
4)set_timeout
设置子请求的超时时间(ms),包括connect方法
语法:db:set_timeout(time)
5close
关闭当前MySQL连接并返回状态。如果成功,则返回1;如果出现任何错误,则将返回nil和错误描述。
语法:db:close()
6)send_query
异步向远程MySQL发送一个查询。如果成功则返回成功发送的字节数;如果错误,则返回nil和错误描述
语法:bytes,err=db:send_query(sql)
7)read_result
从MySQL服务器返回结果中读取一行数据。res返回一个描述OK包或结果集包的Lua表,语法:
res, err, errcode, sqlstate = db:read_result()
res, err, errcode, sqlstate = db:read_result(rows) :rows指定返回结果集的最大值,默认为4
如果是查询,则返回一个容纳多行的数组。每行是一个数据列的key-value对,如

{
{id=1,username="TOM",birthday="1988-11-11",salary=10000.0},
{id=2,username="JERRY",birthday="1989-11-11",salary=20000.0}
}
如果是增删改,则返回类上如下数据
{
insert_id = 0,
server_status=2,
warning_count=1,
affected_rows=2,
message=nil
}
返回值:
res:操作的结果集
err:错误信息
errcode:MySQL的错误码,比如1064
sqlstate:返回由5个字符组成的标准SQL错误码,比如42000

具体应用

  • 部署静态资源

    将静态资源放到html文件夹下

  • 反向代理

    正向代理:代理的是客服端,对客服端负责,帮助客服端访问服务器

    反向代理:代理的是服务端,对服务端负责,帮助服务器提供服务

    1
    2
    3
    4
    5
    6
    7
    #在配置文件中的http中配置反向代理,记得开放端口
    server {
    listen 80; #监听的端口,当访问这个端口时转发到指定服务器
    server_name localhost;
    location / {
    proxy_pass:http://192.168.229.130:8080; #转发的服务器
    }
  • 负载均衡

    基于反向代理,根据算法将用户请求分发到集群中的一台服务器上

    名称 说明
    weight 权重方式,值越大分配几率越高
    ip_hash 根据客户端ip
    least_conn 根据最少连接方式
    url_hash 根据url分配方式
    fair 根据响应时间方式
    轮询 默认
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #配置负载均衡
    upstream targetserver{ #upstream指令来定义一组服务器
    server 192.168.229.130:8080;
    server 192.168.229.131:8080;
    server 192.168.229.131:8081;
    }

    server {
    listen 80; #监听的端口,当访问这个端口时转发到指定服务器
    server_name localhost;
    location / {
    proxy_pass:http://targetserver; #转发的服务器
    }

记得./sbin/nginx -s reload重新加载


Nginx
http://xwww12.github.io/2022/08/20/中间件/Nginx/
作者
xw
发布于
2022年8月20日
许可协议