Nginx

nginx

官网

狂神说文章

狂神说视频

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。2011年6月1日,nginx 1.0.4发布。

nginx的主要功能是web服务器的反向代理

反向代理 在用户请求服务器之前,先经一个代理服务器 再由这个代理服务器去决定请求那台服务器
代理服务器的作用可以是:负载均衡、网络代理等

安装

在官方下载地址下载对应压缩包

1690019659785

解压就行

启动

在windows里双击nginx.exe启动服务

然后我们在浏览器的80端口就能看到初始页面

配置

修改Nginx 配置文件(conf/nginx.conf) 文件以完成我们所需的的功能

保存并退出 Nginx 配置文件后,执行命令 nginx -t 测试配置文件语法是否有误,没有问题的 话,执行命令 nginx -s reload ,重新加载配置文件

关闭

输入nginx命令 nginx -s stop(快速停止nginx) 或 nginx -s quit(完整有序的停止nginx)

使用taskkill taskkill /f /t /im nginx.exe

taskkill是用来终止进程的,/f是强制终止 ./t终止指定的进程和任何由此启动的子进程。/im示指定的进程名称 .

实例:

案例使用的例子

编译后的二进制文件

windows版本

linux版本

源码

 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
package main

import (
	"net/http"
	"sync"

	"github.com/gin-gonic/gin"
)

var (
	cnt    int
	rwlock sync.RWMutex
)

func sayHello(c *gin.Context) {
	rwlock.Lock()
	cnt++
	rwlock.Unlock()

	c.JSON(http.StatusAccepted, gin.H{
        // 三个服务 分别对应 server1\server2\server3
		"message": "这里是server1",
		"访问计数":    cnt,
	})
}

func main() {
	r := gin.Default()

	r.GET("/", sayHello)

    // 三个服务对应 9091\9092\9093
	r.Run(":9091")
}

01-挂载静态页面

在解压路径下有一个 html文件夹 这是用来放静态页面的

里面默认有一个index和一个错误页面

在这个文件夹下 路径与域名相对应

在html文件夹下创建一个test文件夹 以及一个test.html文件

html
|-- 50x.html
|-- index.html
`-- test
    `-- test.html
 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
<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <title>测试用html页面</title>
        <style type="text/css">
                h1{
                   font: 96px "微软雅黑";/*设置字体和字体大小*/
                   margin:50px auto; /*设置元素外边距*/
                   font-weight: 500; /*设置字体粗细*/
                   text-align: center; /*设置文字居中*/
                   color: #f08080; /*设置文字颜色*/
                   -webkit-animation:swing 2s infinite;/*设置动画*/
                }
                @-webkit-keyframes swing{/*创建动画*/
                   20%{
                      -webkit-transform:rotate(15deg);
                   }40%{
                      -webkit-transform:rotate(-15deg);
                   }60%{
                      -webkit-transform:rotate(5deg);
                   }80%{
                      -webkit-transform:rotate(-5deg);
                   }100%{
                      -webkit-transform:rotate(0deg);
                   }
                }
        </style>
</head>
<body>
        <h1>妹红祈祷中</h1>
</body>
</html>

然后

1
2
3
4
# 检查是否出错 -t指test(大概)
nginx -t
# 没有错就重新加载
nginx -s reload

随后就可以直接在nginx的80端口访问到它了

image-20230727193102043

02-代理端口

算是反向代理 在访问nginx监听的网址(端口)时 把别的网址代理到自己的端口上

windows的话 因为默认配置里没有include /etc/nginx/conf.d/*.conf;这一行 所以要么自己写进去设置一个配置目录 要么直接把配置追加到nginx.conf后面

linux在conf.d文件夹下写个配置文件 proxy.conf 叫什么不影响

当然 linux直接追加到nginx.conf或者default.conf后面也是可行的 但是这么做有点不够 优~雅~

1
2
3
4
5
6
7
8
server {
    # 8081是nginx宿主机的端口
    listen 8081;
    location / {
        # 这是要代理的网址 可以是其他服务器转发的
        proxy_pass http://127.0.0.1:9091;
    }
}

重载配置

1
2
3
4
# 检查是否出错 -t指test(大概)
nginx -t
# 没有错就重新加载
nginx -s reload

它的效果是当访问127.0.0.1:8081(假设你的nginx在本机上)时 会得到 127.0.0.1:9091的页面

03-连接池

通常来说一个服务往往会有很多提供者 而不是一个网址 这时可以使用连接池 来把不同的服务 统一到自己的端口上

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 定义一个 连接池 取名为 server23_pool
upstream server23_pool{
    # 其中包括两个server
    server 127.0.0.1:9092;
    server 127.0.0.1:9093;
    # 当然把上面那个例子中使用的8081放入连接池也是可以的
    # server 127.0.0.1:8081;
    # 走自己不会死循环 走了8082后会继续轮询一次 到9092去 相当于直接跳过
    # server 127.0.0.1:8082;
}

server {
    listen 8082;
    location / {
        proxy_pass http://server23_pool;
    }
}

重载配置

1
2
3
4
# 检查是否出错 -t指test(大概)
nginx -t
# 没有错就重新加载
nginx -s reload

结果:

在访问8082端口时 返回的页面时server2和server3轮询的

轮询:nginx默认策略,其他的负载均衡策略详见05-负载均衡

1690460295747

04-端口转发

假如有3个web项目 要实现不同的网址 访问不同的页面

即 三个网址都指向nginx的端口 由nginx根据网址转发到 server1\2\3 3个不同的服务

最终效果

访问01.server.com:80 能进入到 nginx代理的 9091端口的服务1

访问02.server.com:80 能进入到 nginx代理的 9092端口的服务2

访问03.server.com:80 能进入到 nginx代理的 9093端口的服务3

1690457818570

第一步 启动服务

把要部署的服务启动起来 如果使用静态文件的话可以忽略这步

第二步 配置文件

 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
50
51
52
53
54
55
56
57
# server01_pool server01连接池
upstream server01_pool{
    server 127.0.0.1:9091;
}

# server02_pool server02连接池
upstream server02_pool{
    server 0.0.0.0:9092;
}

# server03_pool server03连接池
upstream server03_pool{
    server 0.0.0.0:9093;
}


server {
    listen       80;
    # 当以01.server.com访问时
    server_name  01.server.com;
    # 日志文件的配置 可以是任意的绝对路径或相对路径 但要保证前置文件夹存在
    access_log /mhWorkspace/logs/server01.log;
    error_log /mhWorkspace/logs/server01.error;

    # 设置代理端口
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://server01_pool;
    }
}

server {
    listen       80;
    server_name  02.server.com;
    access_log /mhWorkspace/logs/server02.log;
    error_log /mhWorkspace/logs/server02.error;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://server02_pool;
    }
}

server {
    listen       80;
    server_name  03.server.com;
    access_log /mhWorkspace/logs/server03.log;
    error_log /mhWorkspace/logs/server03.error;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://server03_pool;
    }
}
1
2
3
4
# 检查是否出错 -t指test(大概)
nginx -t
# 没有错就重新加载
nginx -s reload

此时服务端的反向代理已经完成 但依旧无法通过 curl或者浏览器去访问 因为域名解析还没有完成

第三步 域名解析

如果使用了公网的域名 就把它dns解析一下 到服务器的公网ip

image-20230727185125733

如果只是本机的学习的话 可以直接改hosts文件

hosts文件地址

windows在C:\Windows\System32\drivers\etc\hosts

linux在/etc/hosts

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      8ae86f41e715

# 在后面追加你的本机ip 一般192或者168开头的
# 127.0.0.1也是可以的
172.17.0.2      01.server.com
172.17.0.2      02.server.com
172.17.0.2      03.server.com

05-负载均衡

对于连接池中的服务提供者 分配它们的工作量的算法

01-轮询(默认)

连接池中不做额外配置就是轮询 按照连接池中ip写的顺序逐个执行 轮完最后一个回到第一个

如果服务器性能差不多就用这个就好了

02-权重(weight)

按照权重比例去分配任务

配置文件 在03-连接池的配置上 加了两个权重 服务2权重5 服务3权重1 8081的服务1没配权重

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
server {
    listen 8081;
    location / {
        proxy_pass http://127.0.0.1:9091;
    }
}

upstream server23_pool{
    server 127.0.0.1:9092 weight=5;
    server 127.0.0.1:9093 weight=1; 
    server 127.0.0.1:8081;
    # server 127.0.0.1:8082; 
}

server {
    listen 8082;
    location / {
        proxy_pass http://server23_pool;
    }
}

结果 如下

1690461769880

服务2大约是服务1、3的5倍 虽然没有找到确定的资料 不过不写权重大概默认就是1了

03-ip_hash

根据访问者的ip去决定连哪台服务器 一个ip会一直连接到同一台服务器 可以用来处理Session丢失的问题 可以和weight搭配使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
server {
    listen 8081;
    location / {
        proxy_pass http://127.0.0.1:9091;
    }
}

upstream server23_pool{
    ip_hash;
    server 127.0.0.1:9092 weight=2;
    server 127.0.0.1:9093; 
    server 127.0.0.1:8081;
    server 127.0.0.1:8082; 
}

server {
    listen 8082;
    location / {
        proxy_pass http://server23_pool;
    }
}

最终的结果是一直访问同一个服务器

04-最少连接(least_conn)

web请求会被优先转发到连接数最少的服务器上

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
server {
    listen 8081;
    location / {
        proxy_pass http://127.0.0.1:9091;
    }
}

upstream server23_pool{
    least_conn;
    server 127.0.0.1:9092 weight=2;
    server 127.0.0.1:9093; 
    server 127.0.0.1:8081;
    server 127.0.0.1:8082; 
}

server {
    listen 8082;
    location / {
        proxy_pass http://server23_pool;
    }
}

运行结果:

image-20230727214320499

对于最少连接 我推测的实现思路应该是:

每次访问 连接计数值最低的服务器 然后该服务器的连接计数加 1/werght(可能会乘上一个公倍数让它成为整数) 值相同就按照默认顺序

在docker中使用

拉取镜像

1
docker pull nginx:latest

启动镜像

1
docker run -itd --rm -p 80:80 --name nginx nginx

nginx容器主要的配置:

• 配置,默认位置:/etc/nginx/nginx.conf

• 网站,默认位置:/usr/share/nginx

• 模块,默认位置:/etc/nginx/modules

其他的和外面使用一样

<html>
<link rel="stylesheet" href="./css/neno-text-style.css">
<body>
<p class="neon">【前端实验室】分享前端最新、最实用前端技术</p>
</body>
</html>
updatedupdated2023-08-132023-08-13