很干的 Nginx

🎨 前言

本篇文章有些概念性的东西,是结合自己的理解表达出来的,可能有些理解不到位的地方。希望多多指教,谢谢大家。

红包献上 🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧🧧

🎨 最小单元配置

worker_processes 1; # 工作的进程个数events {worker_connections 1024; # 一个进程可以创建多少个链接(默认 1024)
}http {# 引入其他配置(返回前端的头部信息,告诉浏览器返回的数据格式)include mime.types; # 如果没有命中 mime.types 的类型,则默认返回 application/octet-stream 的数据格式default_type application/octet-stream;# 数据零拷贝 (减少了 nginx 读取文件,拷贝文件,直接将文件返回给到前端)sendfile on;# 保存连接超时时间keepalive_timeout 65;# 虚拟主机server {# 监听端口listen 80;# 域名、主机名server_name localhost;location / { # / 转发# 指向 nginx 目录下的 html 目录root html;# 默认展示页index index.html index.htm}# 错误码为 500 502 503 504 会命中 50x.htmlerror_page 500 502 503 504 /50x.html# 访问 /50x.html 会被代理到 nginx 下的 html 目录下  location = /50x.html {root html}}
}

🎨 二级域名转发

根据不同的二级域名返回不同的站点

如:

  • 域名 blog.hhmax.xyz 返回博客站点
  • 域名 www.hhmax.xyz 返回主站站点

原理:将不同的二级域名都指向同一个 IP 地址,在通过 Nginx 在转发时,根据不同的二级域名,返回不同的站点

下面通过俩种方式进行演示:

🎉 内网模拟站点映射

C:\Windows\System32\drivers\etc\hosts 文件中添加

39.104.61.35 blog.hhmax.xyz
39.104.61.35 www.hhmax.xyz

测试是否映射成功

ping blog.hhmax.xyz

在这里插入图片描述

ping www.hhmax.xyz

在这里插入图片描述

接下来进行 Nginx 配置,配置内容如下:

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name www.hhmax.xyz;  location / {root html; # 转发到 nginx/html/index.html 或 index.htmindex index.html index.htm}   },server {listen: 80,server_name blog.hhmax.xyz;  location / {root blog; # 转发到 nginx/blog/index.html 或 index.htmindex index.html index.htm}   }       
}

🎉 外网模拟站点映射

需要购买域名以及一台服务器,并且服务器要备案成功才能映射成功

在这里插入图片描述

选中域名解析,并添加记录

在这里插入图片描述

需要设置的字段

  • 记录类型:这里选择 A - 将域名指向一个 IPV4 的地址
  • 主机记录:可以填写一个二级域名(即我们要设置的 blog 和 www)
  • 记录值:映射的地址(即我们要映射的服务器IP地址)

可添加多条记录,并映射到其他 IP 或相同 IP

接下来进行 Nginx 配置,配置内容如下:

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name www.hhmax.xyz;  location / {root html; # 转发到 nginx/html/index.html 或 index.htmindex index.html index.htm}   },server {listen: 80,server_name blog.hhmax.xyz;  location / {root blog; # 转发到 nginx/blog/index.html 或 index.htmindex index.html index.htm}   }       
}

注意:上述 Nginx 配置监听的端口是 80 端口,服务器可能需要开启

在这里插入图片描述

在这里插入图片描述


🎨 反向代理

🎉 正向代理

概念:代理服务器充当客户端的中间人,代表客户端向目标服务器发送请求。在正向代理中,客户端通过代理服务器来访问互联网上的资源,而不是直接与目标服务器通信

在这里插入图片描述

好处:隐藏客户端的真实 IP 地址和身份,增加了匿名性和安全性

🎉 反向代理

概念:代理服务器接收客户端请求,并将请求转发给后端服务器。在反向代理中,客户端不直接与后端服务器通信,而是与代理服务器进行通信

在这里插入图片描述

好处:

  • 可以实现负载均衡,将请求分发到多个后端服务器,提高系统的性能和可靠性(负载均衡
  • 可以缓存静态资源,减少后端服务器的负载(动静分离

Nginx 与 Tomcat 形成内网,Tomcat 不能直接绕过 Nginx 通过网关,发送消息。必须通过 Nginx 来发送消息。这种模式称为 隧道式代理

由此,也暴露出一个问题,当数据量很大时,尽管 Tomcat 的带宽有 100M,但 Nginx 的带宽只有 10 M。由于需要借助 Nginx 来向外传递数据,最终的传输数据没有设想的那么好。Tomcat 带宽再好,也要受限于 Nginx

为了解决上述的缺点:

衍生出一种模式: Nginx 只处理进来的请求,而出去的数据不经过 Nginx 进行转发。Tomcat 直接将数据通过网关发送给到用户(中间会经过其他网关进行转发)。这种模式称为 DR 模式

🎉 反向代理配置

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name blog.hhmax.xyz;  location / {# 当访问 blog.hhmax.xyz 是代理到 http://www.baidu.com    proxy_pass http://www.baidu.com} location /api { # 笔记# 当访问 blog.hhmax.xyz/api 是代理到 内网中的 http://127.0.0.1:3200    proxy_pass http://127.0.0.1:3200;}   }       
}

注意:上述例子中代理到后端服务 3200 端口也需要开放

在这里插入图片描述

在这里插入图片描述


🎨 负载均衡

概念:用于在多个服务器之间分配和平衡工作负载,以提高系统的性能、可靠性和可扩展性。当一个服务器无法处理所有的请求时,负载均衡将请求分发给其他可用的服务器,以确保每个服务器都能够处理适当的负载

🎉 普通轮询

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  # 轮询的服务器  upstream httpds {server 192.168.5.51:80;   server 192.168.6.51:80; server 192.168.7.51:80; }server {listen: 80,server_name blog.hhmax.xyz;  location / {proxy_pass http://httpds;}   }       
}

192.168.5.51:80192.168.6.51:80192.168.7.51:80 三台服务器提供的服务都一样。

🎉 权重轮询

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  # 权重值越大,被轮询到的可能性越大upstream httpds {server 192.168.5.51:80 weight=8;   server 192.168.5.51:80 weight=1; server 192.168.5.51:80 weight=7; }server {listen: 80,server_name blog.hhmax.xyz;  location / {proxy_pass http://httpds;}   }       
}

另外一些配置

  • down (若配置,则该台服务器不参与轮询
  • backup(若配置,则该台服务器为备用机,当其他轮询服务器不能使用时,才会使用该服务器)

具体使用如下:

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  upstream httpds {server 192.168.5.51:80 weight=8 down;   server 192.168.5.51:80 weight=1; server 192.168.5.51:80 weight=7 backup; }server {listen: 80,server_name blog.hhmax.xyz;  location / {proxy_pass http://httpds;}   }       
}

🎉 轮询缺点

由于是轮询,所以导致没法保存会话信息,如在 192.168.5.51:80 用户登录成功。当用户再次访问该站点时,被 Nginx 轮询到192.168.7.51:80 ,此时这台服务器是不知道用户已经登录了,所以需要重新在登录。

🎉 解决方案

随着技术的发展,为了解决轮询带来的会话信息无法保存,衍生出了两种方案来解决上述问题

  • 其一:借助 cookie、session、redis

流程:

  1. 用户输入其登录信息
  2. 服务器验证信息是否正确,并创建一个 session,并将其存入到 redis
  3. 服务器为用户生成一个 sessionId,将具有 sesssionId 的 cookie 将放置在用户浏览器中
  4. 在后续请求中,携带 cookie,访问服务器。哪怕是轮询到其他服务器,也可以通过 sessionId 去 redis 拿去登录信息
  5. 一旦用户注销应用程序,会话将在客户端和服务器端都被销毁

Node + Koa2 代码实现

// app.js
const app = new Koa()
const Koa = require('koa')
const redisStore = require('koa-redis')
const session = require('koa-generic-session')
//session 与  redis
app.keys = ['dfhQWE_123#ewr']
app.use(session({key: 'token.sid', //cookie name 默认是 `koa.sid`prefix: 'token:sess:', // redis key 的前缀,默认是 `koa:sess:`//配置cookiecookie:{path:"/",httpOnly:true,maxAge:24 * 60 * 60 * 1000 // 1 day},//配置redisstore: redisStore({all:`127.0.0.1:6379`})
}))// router
router.post('/login', async (ctx, next) => {const { account = '-', password = '-' } = ctx.request.body;if (config.account == account && config.password == password) {// TODO 将账号信息(id)保存到 session 中ctx.session.user = {account: config.account}ctx.body = {errorno: 0,message: '登录成功'}return}ctx.body = {errorno: 4001,message: '账号或密码错误'}
});// 中间件校验 loginCheck
module.exports = async (ctx, next) => {// // TODO:判断用户是否已经登录if (ctx.session.user) {await next()return} else {ctx.body = {errorno: 4000,message: '用户未登录'}}
}// 判断是否已经登录成功
router.post('/getNotes', loginCheck, async (ctx, next) => {const data = await searchData();ctx.body = {errorno: 0,message: '',data}
});
  • 其二:无状态的会话通信 (JWT)

流程:

  1. 用户输入其登录信息
  2. 服务器验证信息是否正确,并返回已签名的 Token
  3. Token 存储在客户端
  4. 之后的 HTTP 请求都将 Token 添加到请求头里
  5. 服务器解码 JWT,并且如果令牌有效,则接受请求
  6. 一旦用户注销,令牌将在客户端被销毁,不需要与服务器进行交互一个关键是,令牌是无状态的。后端服务器不需要保存令牌或当前session的记录

Node + Koa2 代码实现

// app.js
const app = new Koa()
const Koa = require('koa')
const jwtKoa = require('koa-jwt')
app.use(jwtKoa({secret:'1Hrj$_enferk' //密钥}
).unless({path:[/^\/users\/login/] //自定义哪些目录忽略 JWT 验证
}))//登录成功对信息进行加密
const jwt = require('jsonwebtoken')
token = jwt.sign(userInfo, '1Hrj$_enferk', { expiresIn: '1h' })// router
const until = require('util')
const verify = until.promisify(jwt.verify)
router.get('/getUserInfo', async (ctx, next) => {const token = ctx.header.authorizationtry {const payload = await verify(token.split(' ')[1], '1Hrj$_enferk')ctx.body = {errno:0,userInfo: payload}} catch (ex) {ctx.body = {errno:-1,msg:'失败'}}
})

🎉 方案对比

共同点:为了解决:登录和存储登录用户信息
不同点:

  • JWT 用户信息加密存储在客户端,不依赖 cookie ,可跨域
  • session 用户信息存储在服务端,依赖于 cookie,默认不可跨域

JWT 的优点:

  • 将加密信息存放在客户端,减少服务端的内存压力。
  • 不依赖于 cookie 可以将信息进行跨域分享。

JWT 的不足:

  • 服务端无法控制信息,一旦用户修改信息后,服务端无法第一时间修改加密信息。

Session 的优点:

  • 可以对用户信息进行控制。

Session 的不足:

  • 存储要依赖于 redis 和 cookie ,并且不能跨域。
  • 一旦上线启动多进程,而不依赖 redis 是无法实现多进程之间的信息共享。

🎨 动静分离

在还没有前后端分离的开发模式的情况下(MVC),一些静态资源都是集中和后端代码放在 Tomcat 。而这些静态资源大多数情况下都是不变的,如:图片,JavaScript 代码。

并且 Nginx 可以缓存静态资源,减少后端服务器的负载。因此,可以将一些静态资源放到 Nginx 中,从而使一些静态资源与业务逻辑进行抽离。

具体配置如下:

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name blog.hhmax.xyz;  location / {proxy_pass http://192.168.6.52     }location ~*/(css|img|js) {# 路径中有 /css /img /js 使会指向 nginx/html 中的 css、img、js     root html;index index.html index.htm     }   }       
}

随着技术的发展,特别是前后端分离的开发模式,上述情况也不复存在,后端也不用考虑到静态资源该怎么处理,都转移给到前端了


🎨 资源防盗链

保护网站资源不被其他网站盗用的技术措施

防盗链的实现原理:

  • 服务器收到请求后,获取请求头中的referer字段
  • 验证referer字段是否符合预设的规则,例如是否在允许的域名列表中
  • 如果referer验证通过,则允许访问资源;否则,拒绝访问或返回特定的错误页面

情况一:页面引用图片请求头中会携带 referer 头,值就是引用该资源的这个地址

在这里插入图片描述

情况二:单独复制该图片地址,重新打开窗口访问时,请求该图片时,referer 头就不会携带给到后端

在这里插入图片描述


配置一:两种情况都不能访问资源(图片)

 http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name blog.hhmax.xyz;  location /img {     valid_referers blog.hhmax.xyz;if ($invalid_referer) {return 403;}   # 路径中有 /nginx/img    root img;index index.html index.htm     }   }       
}

valid_referers:配置的值得跟 server_name 一样

在这里插入图片描述

配置二:仅第二种情况可以访问资源

http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name blog.hhmax.xyz;  location /img {     valid_referers none blog.hhmax.xyz;if ($invalid_referer) {return 403;}   # 路径中有 /nginx/img    root img;index index.html index.htm     }   }       
}

valid_referers:配置的值得跟 server_name 一样

配置后:

在这里插入图片描述

没有权限访问图片,也可以配置返回一个错误页面,或者一个错误图片

  • 错误页面
http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name blog.hhmax.xyz;  location /img) {     valid_referers blog.hhmax.xyz;if ($invalid_referer) {return 401;}         root img;index index.html index.htm     }error_page 401 /401.htmllocation = /401.html {root html;    }       }       
}
  • 错误图片
http {include mime.types; default_type application/octet-stream;sendfile on;keepalive_timeout 65;  server {listen: 80,server_name blog.hhmax.xyz;  location /img {     valid_referers blog.hhmax.xyz;if ($invalid_referer) {return ^/ /img/x.png break;}     root html;index index.html index.htm     }   }       
}

通过正常手段,访问或者引用资源(图片),通过上述方法是可以避免资源被盗用的。因为referer 字段通过某些手段是可以被伪造或篡改。因此防盗链并不能完全阻止盗链行为。为了增加安全性,可以结合其他技术手段,如加密链接、动态生成链接等,来提高防盗链的效果。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全面介绍MES车间班次管理

一、什么是MES车间班次管理? MES车间班次管理是指利用制造执行系统(MES)来有效管理车间内的工人班次安排和生产计划。它涉及到车间人员的计划排班、考勤管理、生产数据的采集和分析等一系列工作。 二、MES车间班次管理的功能: 1…

SpringBoot概述SpringBoot基础配置yml的使用多环境启动

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 SpringBoot简介 一、 SpringBoot概述1.1 起步依赖…

[MyBatis系列②]Dao层开发的两种方式

目录 1、传统开发 1.1、代码 1.2、存在的问题 2、代理开发 2.1、开发规范 2.2、代码 ⭐mybatis系列①:增删改查 1、传统开发 传统的mybatis开发中,是在数据访问层实现相应的接口,在实现类中用"命名空间.id"的形式找到对应的映…

docker可视化工具

安装Portainer 官方安装说明:https://www.portainer.io/installation/ [rootubuntu1804 ~]#docker pull portainer/portainer[rootubuntu1804 ~]#docker volume create portainer_data portainer_data [rootubuntu1804 ~]#docker run -d -p 8000:8000 -p 9000:90…

Python爬虫猿人学逆向系列——第六题

题目:采集全部5页的彩票数据,计算全部中奖的总金额(包含一、二、三等奖) 地址:https://match.yuanrenxue.cn/match/6 本题比较简单,只是容易踩坑。话不多说请看分析。 两个参数,一个m一个f&…

CSS中如何实现多列布局?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 多列布局(Multi-column Layout)⭐ column-count⭐ column-width⭐ column-gap⭐ column-rule⭐ column-span⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧…

QT中资源文件resourcefile的使用,使用API完成页面布局

QT中资源文件resourcefile的使用 之前添加图标的方法使用资源文件的方法创建资源文件资源文件添加前缀资源文件添加资源使用资源文件中的资源 使用API完成布局使用QHBoxLayout完成水平布局使用QVBoxLayout完成垂直布局使用QGridLayout完成网格布局 在Qt中引入资源文件好处在于他…

pnpm无法加载文件 (解决方法 )

现在要运行一个TS的项目,我的电脑上没有安装pnpm,导致我的vscode一直报错无法加载。 pnpm安装: npm install -g pnpm pnpm : 无法加载文件 pnpm : 无法加载文件 C:\Users\HP\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运…

若依前后端分离版本项目总结笔记

若依前后端分离学习笔试 1.路由问题 注意这个是前端找到你的路由的路径。 2.表格开关按钮快速实现 <el-table-column label"状态" align"center" key"status"><template slot-scope"scope"><el-switchv-model"s…

DevExpress WinForms数据编辑器组件,提供丰富的数据输入样式!(二)

DevExpress WinForms超过80个高影响力的WinForms编辑器和多用途控件&#xff0c;从屏蔽数据输入和内置数据验证到HTML格式化&#xff0c;DevExpress数据编辑库提供了无与伦比的数据编辑选项&#xff0c;包括用于独立数据编辑或用于容器控件(如Grid, TreeList和Ribbon)的单元格。…

柔性数组详解

柔性数组 1.前言 在c99标准中&#xff1a;允许结构体的最后一个变量是未知大小的数组&#xff0c;这就是柔性数组的来源。 例如&#xff1a; typedef struct type_a{ int i;int a[0];//柔性数组成员 }type_a;有些编译器可能会报错&#xff0c;那就使用下面这一种定义方式&…

房屋结构健康监测,科技助力让建筑更安全

房屋建筑是人们赖以生存的场所&#xff0c;然而当前我国许多房屋已经达到了使用寿命的中期&#xff0c;房屋的安全系数逐年降低&#xff0c;风险也随着时间的推移而累积。长期以来&#xff0c;我国的房屋普遍存在寿命短、隐患多的问题&#xff0c;“重建设&#xff0c;轻管理”…

4.网络设计与redis、memcached、nginx组件(一)

网络组件系列文章目录 第四章 网络设计与redis、memcached、nginx组件 文章目录 网络组件系列文章目录文章的思维导图前言一、网络相关的问题&#xff0c;网络开发中要处理那些问题&#xff1f;网络操作IO连接建立连接断开消息到达消息发送网络操作IO特性 二、网络中IO检测IO函…

ssm+vue毕业论文管理系统源码和论文

ssmvue毕业论文管理系统053 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 高校规模越来越大&#xff0c;学生越来越多&#xff0c;每年都有大批的大学生完成学业。毕业之前&#xff0c;各大高校设立…

浅谈Python网络爬虫应对反爬虫的技术对抗

在当今信息时代&#xff0c;数据是非常宝贵的资源。而作为一名专业的 Python 网络爬虫程序猿&#xff0c;在进行网页数据采集时经常会遭遇到各种针对爬虫行为的阻碍和限制&#xff0c;这就需要我们掌握一些应对反爬机制的技术手段。本文将从不同层面介绍如何使用 Python 进行网…

linux系统(centos、ubuntu、银河麒麟服务、uos、deepin)判断程序是否已安装,通用判断方法:使用所有应用和命令的判断

前言 项目中需要判断linux服务器中是否已经安装了某个服务 方法有很多种&#xff0c;但是很多都不通用&#xff0c; 脚本代码就不容易做成统一的 解决方案 用下面的脚本代码去进行判断 用jdk测试 脚本意思如下&#xff1a; 输入java -version命令&#xff0c;将返回的字…

spring boot 3使用 elasticsearch 提供搜索建议

业务场景 用户输入内容&#xff0c;快速返回建议&#xff0c;示例效果如下 技术选型 spring boot 3elasticsearch server 7.17.4spring data elasticsearch 5.0.1elasticsearch-java-api 8.5.3 pom.xml <dependency><groupId>org.springframework.boot</gr…

淘宝免费爬虫数据 商品详情数据 商品销售额销量API

场景&#xff1a;一个宽敞明亮的办公室&#xff0c;一位公司高管坐在办公桌前。 高管&#xff08;自言自语&#xff09;&#xff1a;淘宝&#xff0c;这个平台上商品真是琳琅满目&#xff0c;应该有不少销售数据吧。我该怎么利用这些数据呢&#xff1f; 突然&#xff0c;房间…

Qt 自定义菜单、右键菜单

在接触Qt这段时间以来&#xff0c;经常遇到菜单项的问题&#xff08;右键菜单、托盘菜单、按钮菜单等&#xff09;&#xff0c;QMenu用于菜单栏,上下文菜单,弹出菜单等&#xff0c;利用QMenuQAction就可以达到效果&#xff01; 右键菜单实现&#xff1a;通过重写contextMenuEv…

C++(8.21)c++初步

1.斐波那契&#xff1a; #include <iostream> #include<iomanip>using namespace std;int main() {cout << "Hello World!" << endl;int a[10];for(int i0;i<10;i){if(0i||1i){a[i]1;}elsea[i]a[i-1]a[i-2];cout <<setw(4) <&l…