Nginx - 反向代理、负载均衡、动静分离、底层原理(案例实战分析)

news2024/11/29 6:24:40

目录

Nginx 开始

概述

安装(非 Docker)

配置环境变量

常用命令

配置文件概述

location 路径匹配方式

配置反向代理

实现效果

准备工作

具体配置

效果演示

配置负载均衡

实现效果

准备工作

具体配置

实现效果

其他负载均衡策略

配置动静分离

概念

实现效果

准备工作

403 错误,怎么办?

效果演示

底层原理

原理说明

master - worker 模式的好处

worker 的数量设置成多少合适

一个请求占用多少个worker_connection(worker 连接数)

假设 nginx 有 1 个 master 和 4 个 worker,每个 worker 支持的最大连接数是 1024,那么 nginx 的最大并发数是多少?


Nginx 开始


概述

a)简述

Nginx 是一个高性能的 HTTP 和反向代理服务器,特点是占用内存少,并发能力强(有报告表明支持高达 50 000 个并发连接数).

 b)何为正向代理

正向代理:代理客户端(在浏览器中配置代理服务器). 通过代理服务器进行互联网访问.

例如,在中国大陆是不能直接访问到谷歌,因此就需要在浏览器中配置代理服务器,通过代理服务器来访问谷歌.

c)何为反向代理

反向代理:代理服务器. 客户端无需做任何 配置,只需要将请求发送给反向代理服务器,呦反向代理服务器将请求发送给真实服务器(暴露代理服务器地址,隐藏真实服务器 IP 地址).

例如,客户端要给 8080 端口的 tomcat 发送请求,可以不直接访问 tomcat(出于安全考虑),而是通过将请求发送给 9090 的代理服务器,再由 9090 的代理服务器将请求转发给 8080 端口的 tomcat.

d)安装:直接通过 docker 安装(记得挂载配置文件数据卷).

安装(非 Docker)

a)官网下载:nginx: download

b)将下载好的文件上传到终端:

Ps:想了一下,又把文件移到了服务器的 ~/apps 目录下. 

c)解压

tar -zxvf nginx-1.26.1.tar.gz

d)下载 nginx 运行环境

依次运行以下命令:

yum -y install gcc gcc-c++ autoconf automake make
yum -y install openssl openssl-devel

 e)进入到刚解压的文件中,进行基本配置(输入如下命令)

./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module

配置configure

  •  --prefix:代表安装的路径
  • --with-http_ssl_module:安装ssl
  • --with-http_stub_status_module:查看nginx的客户端状态

f)在解压文件的目录中可以观察到多出了一个 makefile 文件:

接着输入以下命令:

#编译安装nginx
make & make install 

Ps:上一步编译如果出现了错误 “make: *** No rule to make target `build', needed by `default'. Stop”.,解决如下:

  1. 安装配置:yum -y install make zlib-devel gcc-c++ libtool openssl openssl-devel
  2. 重新./configure :./configure 
  3. 编译:make & make install 

f)进入到安装目录(上面 "--prefix=/usr/local/nginx" 配置的就是安装目录)

cd /usr/local/nginx/

g)接着进入sbin目录下,执行以下命令启动 nginx

h)最后直接输入服务器的 ip 就可以访问了(只输入服务器 ip,默认走 80 端口)

Ps:如果访问不了,就去关闭一下防火墙吧~

配置环境变量

a)cd /etc 进入到 etc 目录中

b)找到 profile 文件

c)添加如下信息

# Nginx 的安装目录
export NGINX_HOME=/usr/local/nginx
# Nginx 环境变量配置
export PATH=${NGINX_HOME}/bin:${NGINX_HOME}/sbin:$PATH

d)刷新环境变量

source /etc/profile

e)验证:切换到任意目录下,输入如下命令

常用命令

Note:使用的前提是必须先进入到 /usr/local/nginx/sbin 目录中(配置了环境变量可以忽略,之后都演示配置后的)

a)查看 nginx 版本

nginx -v

b)停止 nginx

nginx -s stop

c)启动 nginx

nginx

d)重新加载 nginx

nginx -s reload

将来我们会经常修改 nginx 的配置文件,每次修改后就需要重新加载 ngxin 才能生效.

配置文件概述

a)nginx 配置文件位置

/usr/local/nginx/conf/nginx.conf

b)nginx 默认配置文件内容(去掉注释):

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    sendfile        on;
 
    keepalive_timeout  65;
 
    server {
        listen       80;
        server_name  localhost;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
 
}

c)nginx 配置文件三部分组成:

        1)全局块:从配置文件开始到 events 块之前的内容.  主要用来设置影响 nginx 服务器整体运行的配置指令,例如 "worker_processes 1;" (worker_processes 值越大,可以支持的并发处理量越大). 如下:

worker_processes  1;   # 服务器并发处理能力,值越大并发能力越强(受自身配置限制)

        2)events 块:主要用来影响 nginx 服务器与用户的网络连接,例如 "worker_connections 1024;" 表示支持的最大连接数. 如下:

events {
    worker_connections  1024; #最大连接数1024个,需灵活配置
}

        3)http 块:nginx 中配置最频繁的地方,http 块中包括 http 全局块、server 块.

http 全局块如下:

http {
    include       mime.types;      # 文件扩展名与文件类型映射表
    default_type  application/octet-stream;  # 访问到未定义的扩展名的时候,就默认为下载该文件
 
    sendfile        on; # 日志自定义
 
    keepalive_timeout  65; # 超时时间

http 块中的 server 块如下:

    server {
        listen       80; # 目前监听的端口号
        server_name  localhost; # 主机名称

server 块中又包括 server 全局块 和 location 块. 

全局 server 块如下:

    server {
        listen       80; # 目前监听的端口号
        server_name  localhost; # 主机名称

location 块如下:

   location / {     #表示默认首页
            root   html;
            index  index.html index.htm;

root 指定了服务器的根目录,上述 "root html" 表示 nginx 安装目录的路径下的 html 目录(以 nginx 安装目录为相对路径).

location 路径匹配方式

语法如下:

location { = | ~ | ~* | ^~ } uri {
    # ...
}

a)=:表示不含正则表达式的 uri ,要求请求字符串和 uri 严格匹配,如果匹配成功,就停止继续向后匹配,并立即处理该请求.

例如如下:

location = /exact-match {
    # 配置处理精确匹配的请求
    proxy_pass http://backend_server;
}

只有请求 URI 完全是 /exact-match 时,才会匹配这个 location 块,其他类似的请求(如 /exact-match/ 或 /exact-match123 )不会匹配。

b)~:用于表示 uri 包含正则表达式,并且区分大小写.

例如如下:

location ~ \.php$ {
    # 配置处理所有以 .php 结尾的请求,例如 /index.php 或者 /foo.php
    fastcgi_pass php_backend;
}

 c)~*:用于表示 uri 包含正则表达式,并且不区分大小写.

d)^~:不含正则表达式的 uri,要求 Nginx 服务器扎到表示 uri 和请求字符串匹配度最高的 location 后,立即使用 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配.

location ^~ /static/ {
    # 配置处理所有以 /static/ 开头的请求
    root /data/static;
}

例如 static/css/styles.css 或者 /static/js/app.js

配置反向代理

实现效果

打开浏览器,在浏览器地址栏中,

输入 env-base:9000/aaa 跳转到 env-base:8080(tomcat8080 的页面)

输入 env-base:9000/bbb 跳转到 env-base:8081(tomcat8081 的页面)

Ps:env-base 为配置 nginx 的服务器 ip

准备工作

a)准备两个 tomcat 服务器,一个 8080,一个 8081

这里使用 docker,直接运行以下命令

# 1.先简单启动
docker run --name tomcat -p 8080:8080 -d tomcat:8.0

# 2.在宿主机中创建将来容器的映射文件
mkdir -p ~/test/tomcat8080
mkdir -p ~/test/tomcat8081

# 3.将容器中的文件拷贝到宿主机
docker cp tomcat:/usr/local/tomcat/webapps/ ~/test/tomcat8080
docker cp tomcat:/usr/local/tomcat/webapps/ ~/test/tomcat8081

# 4.删除旧的容器
docker rm -f tomcat

# 5.启动新容器
docker run --name tomcat8080 -p 8080:8080  \
-v ~/test/tomcat8080/webapps:/usr/local/tomcat/webapps \
-e TZ=Asia/Shanghai \
-d tomcat:8.0

docker run --name tomcat8081 -p 8081:8080  \
-v ~/test/tomcat8081/webapps:/usr/local/tomcat/webapps \
-e TZ=Asia/Shanghai \
-d tomcat:8.0

正常访问:

 

b)由于将来访问 env-base:8080 或者 env-base:8081 实际上都是访问 webapps 下的目录,因此为了演示不同效果,就在前面创建的 tomcat8080 和 tomcat8081 的 webapps 目录下创建两个不同的文件(aaa、bbb)和两个不同的 HTML(a.html 和 b.html):

  • ~/test/tomcat8080/webapps/aaa/a.html
  • ~/test/tomcat8081/webapps/bbb/b.html

效果如下:

具体配置

编辑 nginx 配置文件,进行反向代理配置

    server {
        listen       9000;
        server_name  env-base;

        location ~ /aaa/ {
            proxy_pass http://127.0.0.1:8080;
        }

        location ~ /bbb/ {
            proxy_pass http://127.0.0.1:8081;
        }
    }

使用 nginx -s reload 命令重新加载 nginx

效果演示

e)上述原理

        location ~ /aaa/ {
            proxy_pass http://127.0.0.1:8080;
        }

由于 ~ /aaa/ 是正则表达式,表示只要路径中含有 /aaa/ 就会被代理

  • 例如输入 env-base:9000/aaa/a.html 就会被代理成 127.0.0.1:8080/aaa/a.html(可以正常访问)
  • 例如输入 env-base:9000/abc/aaa/a.html 就会被代理成 http://127.0.0.1:8080/abc/aaa/a.html(404 错误)

配置负载均衡

实现效果

浏览器地址栏输入地址 http://env-base:9000/ccc/c.html 实现负载均衡效果,平均分配到 8080 和 8081 端口中.

准备工作

  1. 准备两个 tomcat 服务器,一台 8080,一台 8081.(在上一章配置反向代理,我们已经准备好了两个 tomcat 容器,路径分别为 "~/test/tomcat8080"、"~/test/tomcat8081")
  2. 在两个 tomcat 中 webapps 目录中,创建名称是 ccc 文件夹,在 ccc 文件夹中创建 c.html ,用于测试.

tomcat8080 访问如下:

tomcat8081 访问如下:

具体配置

实现效果

默认按照轮询的策略分配

第一次:

第二次:

其他负载均衡策略

默认负载均衡的策略是轮询,除此之外,还有其他策略,如下:

a)weight 权重

另外可以通过 weight 来控制需要负载均衡的权重.  权重越大,访问到的概率越大.

比如将权重都配置为 1,表示两者访问到的概率相同.

    upstream group1 {
        server 192.168.0.12:80 weight=1;
        server 192.168.0.12:81 weight=1;
    }
    server {
        listen       80;
        server_name  localhost;

        default_type  text/html;
        location /a {
            proxy_pass "https://group1";
        }
    }

 或者将 80 端口的权重改为 10,让其访问到的概率大一些.

    upstream group1 {
        server 192.168.0.12:80 weight=10;
        server 192.168.0.12:81 weight=1;
    }
    server {
        listen       80;
        server_name  localhost;

        default_type  text/html;
        location /a {
            proxy_pass "https://group1";
        }
    }

b)ip_hash

每个请求按访问 ip 的hash 结果分配,这样子访客固定访问一个后端服务器,可以解决session问题

举个例子:

A用户固定ip,第一次访问到8080 tomcat,那么后面就都是访问到这台机器.

upstream myserver {
    ip_hash;
    server 127.0.0.1:8080;
	server 127.0.0.1:8081;
}

c)fair

根据后端响应时间来分配请求,处理时间短的优先分配.

upstream myserver {
    server 127.0.0.1:8080;
	server 127.0.0.1:8081;
	fair;
}

配置动静分离

概念

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度.

实际上就是将来客户端会先访问 nginx,如果要访问的是静态资源,就会代理到对应放静态资源的 服务器(如 html、css、js); 如果是动态资源,就会代理到对应放动态资源的服务器(如 jsp、sevlet)

另外,这也是一种可以直接通过 url 访问服务器上对应的静态资源的方法(如 图片、html、css).

实现效果

在浏览器中输入地址 http://env-base/image/1.png 访问到服务器上 ~/data/image/1.png 图片

在浏览器中输入地址 http://env-base/www/index.html 访问到服务器上 ~/data/www/index.html 页面.

准备工作

在服务器上的  ~/data/image/ 目录下,准备一个 1.png 图片.

在服务器上的 ~/data/www/ 目录下,准备一个 index.html 页面.

d)具体配置

重启 nginx. 

1)

location /www/ {

        root  /root/data/;

}

表示如果将来浏览器中输入的 uri 是 /www/ ,则匹配服务器上 /root/data 目录下的 /www/ 目录中.

2) autoindex on; 表示开启自动显示索引. 

403 错误,怎么办?

a)先提一嘴,如果出现了 403 错误,是因为 静态资源不可以访问在某个家目录下,如 /root 也就是 ~/ 目录下.

可以在 nginx.conf 文件中指定用户

# user nobody

修改为 

user root; # 设置为 root 用户

b)也有可能是权限不足,通过 chmod 755 -R 所在文件夹 即可提升权限,解决问题.

c)如果还是不行,可能是操作系统设定 SELinux,这是 Linux 系统的选项,为了保护服务求防止文件被随意获取的机制.

通过 getenforce 就可以查看到默认是开启的(Enforcing),需要改成 disabled 状态

要想要永久关闭,就需要进入配置文件 /etc/sysconfig/selinux 将 SELINUX=enforcing 改为SELINUX=disabled

如下:

重启机器,这时候因该就没问题了.

效果演示

autoindex on 的效果如下:

访问到具体图片:

以及 html

底层原理

原理说明

nginx 处理请求是以 master - work 的方式,如下图:

当 nginx 服务器接收到请求之后,就会有 master 进程分发给 worker 进程(这里类似于于,master 给多个 worker 通知说 “我这里有资源了,你们快来”,然后抢到的那个 worker 进程就会来处理这个请求),接着有以下情况:

  • 如果请求的是静态资源:那么 worker 就直接从当前服务器上取到并返回即可.
  • 如果请求的是动态资源(需要访问类似于 Tomcat 服务器,去数据库中取数据):那么 worker 进程就会通过配置的反向代理,去 Tomcat 服务器上取资源.

master - worker 模式的好处

a)可以使用 nginx -s reload 热部署.

如果有一个 worker 正在处理请求,那么此时我们就不希望通过 重启 nginx 的方式来重新加载配置.  而如果有 多个worker,此时只有一个 worker 正在处理请求,那么就可以让其他 worker 来加载新的配置,然后 master 接收到有新的请求时,就只给加载了新的配置文件的 worker 进行通知即可.

b)多进程隔离.

每一个 worker 是独立的进程,如果其中一个 worker 出现问题,其他  worker都是独立的,继续进程争抢,实现请求过程.  不会像一个进程的下的多个线程,其中一个线程出了问题,其他线程可能都会遭殃.

worker 的数量设置成多少合适

a)在配置文件中可以这样配置 worker 的数量.

# 设置 worker 数量
worker_process 4;
# worker 绑定 cpu (4 worker 绑定 4 个 cpu)
worker_cpu_affinity 0001 0010 0100 1000

# worker 绑定 cpu (4 worker 绑定 8 个 cpu 中的 4 个)
worker_cpu_affinity 00000001 00000010 00000100 00001000

 b)设置成多少合适?

Nginx 和 redis 类似都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,但是每个进程只有一个主线程,通过异步非阻塞的方式来处理请求.

每个 worker 的线程可以把 cpu 的性能发挥到极致,所以 worker 的数量 和 服务器的 cput 数量相等最合适.  设置少了会浪费 cpu,设置多了会造成 cpu 频繁上下文切换带来的损耗.

一个请求占用多少个worker_connection(worker 连接数)

2 或者 4 个,原因如下:

2个:如果访问静态资源,只需要 client 给 worker 发送请求,worker 返回静态资源即可.

4个:如果访问动态资源,例如 Java 代码,也就是 Tomcat 服务器,那么不止需要 client 给 worker 发送请求,还需要 worker 去请求 tomcat.  这一来一回,加起来就是 4 个连接.

假设 nginx 有 1 个 master 和 4 个 worker,每个 worker 支持的最大连接数是 1024,那么 nginx 的最大并发数是多少?

a)静态资源的最大并发数是:worker_connections * worker_processes / 2

对应上述就是 1024 * 4 / 2

b)动态资源的最大并发数是:worker_connections * worker_processes / 4.

对应上述就是 1024 * 4 / 4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1851123.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文了解Linux中的内存映射

目录 一、概念 工作原理: 特点: 适用场景: 二、详解mmap()函数 1. mmap的基本概念 2. mmap的特点 3. mmap的用途 4. mmap的优缺点 三、实验 实验一:基础读写实验 实验二:证明开始显…

计算机组成原理 —— 存储系统(主存储器基本组成)

计算机组成原理 —— 存储系统(主存储器基本组成) 0和1的硬件表示整合结构寻址按字寻址和按字节寻址按字寻址按字节寻址区别总结 字寻址到字节寻址转化 我们今天来看一下主存储器的基本组成: 0和1的硬件表示 我们知道一个主存储器是由存储体…

plt绘制网格图

代码 obj "accu" for (epoch,lr) in config:with open(data/epoch_{}_lr_{}_Adam.pkl.format(epoch,lr),rb) as f:data pickle.load(f) plt.plot(range(1,epoch1),data[obj],labelflr{lr})plt.title(obj"-epoch") plt.xlabel("epoch"…

Linux系统及常用命令介绍

一.介绍 Linux一套免费使用和自由传播的类Unix操作系统,是一个遵循POSIX的多用户、多任务、支持多线程和多CPU的操作系统。Linux系统的说明可以自行百度,知道这几点即可: 1.Linux中一切都是文件; 2.Linux是一款免费操作系统&…

云资源管理系统-项目部署

云资源管理系统-项目部署 大家好,我是秋意零。 今天分享个人项目同时也是个人毕设项目,云平台资源管理系统。该系统具备对OpenStack最基本资源的生命周期管理,如:云主机、云盘、镜像、网络。 该篇主要介绍,项目在Li…

STM32读取芯片内部温度

基于stm32f103cbt6这款芯片,原理部分请参考其他文章,此文章为快速上手得到结果,以结果为导向。 1.基础配置 打开stm32cubemx只需要勾选中 ADC1 Temperature Sensor Channel 2.代码分析 /** 函数名:float GetAdcAnlogValue(voi…

《计算机英语》 Unit 3 Software Engineering 软件工程

Section A Software Engineering Methodologies 软件工程方法论 Software development is an engineering process. 软件开发是一个工程过程。 The goal of researchers in software engineering is to find principles that guide the software development process and lea…

开启数字新纪元:全球首款开源AI女友,你的私人数字伴侣

在这个数字化飞速发展的时代,人工智能已经不再是科幻小说中的幻想,而是实实在在走进了我们的生活。今天,我们要介绍的,不仅仅是一项技术革新,更是一场关于陪伴的革命——全球首款开源AI女友,DUIX,已经横空出世! 🚀 革命性的开源平台 DUIX,由硅基智能精心打造,不…

GLM-4V模型学习

智谱AI引领技术前沿,推出了新一代预训练模型GLM-4系列,其中的GLM-4-9B作为开源版本,展现了其在人工智能领域的深厚实力。在语义理解、数学运算、逻辑推理、代码编写以及广泛知识领域的数据集测评中,GLM-4-9B及其人类偏好对齐的版本…

慎投!新增7本期刊被“On Hold“,14本影响因子下降!

本周投稿推荐 SSCI • 中科院2区,6.0-7.0(录用友好) EI • 各领域沾边均可(2天录用) CNKI • 7天录用-检索(急录友好) SCI&EI • 4区生物医学类,0.5-1.0(录用…

大学生须知~~毕业行李太多,怎么拿回家

一年一度的暑假来临了,大学生们又该放假了,可是回家行李这么多,怎么邮寄才便宜呢?? 记得找惠发快递呀!因为我们平台是跟快递总部合作的,不管你寄大件还是快递都很便宜,而且没有单量…

转--Hadoop集群部署案例

模块简介 本模块主要练习Hadoop集群部署。 模块知识 ● 使用Linux基础命令 ● Hadoop集群搭建部署知识 环境准备 三台CentOS7操作系统的虚拟机 可以是3个Docker容器,也可以是三个VMWare/VirtualBox的虚拟机。三台虚拟机的最低配置为1核1G 20G。如果是虚拟机中…

20分钟攻破DISCUZ论坛并盗取数据库(web安全白帽子)

20分钟攻破DISCUZ论坛并盗取数据库(web安全白帽子) 1 快速搭建discuz论坛1.1 攻击思路1.2 快速搭建实验环境1.2.1,漏洞概述1.2.2,在centos7虚拟机上搭建LAMP环境1.2.3,上传到discuz_X2_SC_UTF8.zip 到Linux系统/root下…

Android 添加自己的时钟小部件

小部件,也叫微件, 它的介绍参考官网 应用 widget 概览 https://developer.android.google.cn/develop/ui/views/appwidgets/overview?hlzh-cn 直接上图,原生系统上,时钟应用的小部件效果。 我也整一个。 1.创建小部件布局文…

C#使用轻量级深度学习模型进行车牌颜色识别和车牌号识别

看到这个文章时候请注意这个不涉及到车牌检测,这个仅仅是车牌颜色和车牌号识别,如果想涉及到车牌检测可以参考这个博客:[C#]winform部署yolov7CRNN实现车牌颜色识别车牌号检测识别_c# yolo 车牌识别-CSDN博客 【训练源码】 https://github.…

已解决java.rmi.activation.ActivationException异常的正确解决方法,亲测有效!!!

已解决java.rmi.activation.ActivationException异常的正确解决方法,亲测有效!!! 问题分析 java.rmi.activation.ActivationException 是与Java RMI(远程方法调用)的激活机制相关的一种已检查异常。这个异…

【面试干货】Hashtable 与 HashMap 的区别

【面试干货】Hashtable 与 HashMap 的区别 1、线程安全性2、对null值的处理3、遍历方式4、遍历示例5、总结 💖The Begin💖点点关注,收藏不迷路💖 在Java中,Hashtable和HashMap都是基于哈希表实现的Map接口。然而&#…

代码随想录算法训练营第31天| 134. 加油站、135. 分发糖果、860.柠檬水找零、 406.根据身高重建队列

134. 加油站 题目链接:134. 加油站 文档讲解:代码随想录 状态:so easy 思路:每次遍历时,如果当前的油量差(currTank)小于0,说明从当前起点无法到达下一个加油站。此时,将…

Python --- 如何修改Jupyter Notebook保存文件的路径?

如何修改Jupyter Notebook在本地保存文件的默认路径? 一直以来都比较喜欢jupter notebook,自从用了以后就爱上了。平时用的时候,因为大多都是临时调用,每次在界面里直接new一个新的file就开干。 曾经也想过我创建的这些python文件…

代码随想录第31天|贪心算法

134. 加油站 参考 思路: 以每个油站相差作为判断, 比如: gas [5 8 2 8]cost [6 5 6 6] [-1 3 -4 2]错误 : 把相差最大点当作起点判断能否绕一圈 : 相加数组是否小于0局部最优: 当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i1,因为从i…