青少年编程与数学 02-004 Go语言Web编程 10课题、中间件

青少年编程与数学 02-004 Go语言Web编程 10课题、中间件

  • 一、中间件(Middleware)
      • Web应用中的中间件:
      • 消息队列中的中间件:
      • 其他上下文中的中间件:
  • 二、工作机制
      • 请求处理流程
      • 中间件的工作机制
      • 示例:Express.js 中间件
  • 三、常用功能
  • 四、应用示例
      • 1. 安装Gin
      • 2. 创建中间件
        • 日志记录中间件(logger.go)
        • 请求限流中间件(limiter.go)
        • CORS中间件(cors.go)
      • 3. 主程序(main.go)
      • 4. 运行项目

课题摘要:本文介绍了中间件的概念、工作机制和常用功能,并提供了一个使用Gin框架的中间件应用示例。中间件在Web开发中用于处理请求和响应,可以执行多种任务,如身份验证、日志记录、错误处理等。它们作为请求处理管道的一部分,允许在请求到达最终处理函数之前或响应返回给客户端之前进行操作。文章展示了如何在Gin框架中创建和使用日志记录、请求限流和CORS处理中间件,以及如何在主程序中应用这些中间件。通过这个示例,开发者可以了解如何在Gin框架中集成中间件来增强Web服务器的功能。


一、中间件(Middleware)

中间件(Middleware)是一种在软件架构中处于两个层次或组件之间,用于处理请求和响应的软件。它提供了一种机制,可以在请求到达最终处理程序之前或响应返回给客户端之前,对它们进行处理。中间件的使用可以在不同的上下文中有不同的含义,但在Web开发中,它通常指的是以下概念:

Web应用中的中间件:

在Web应用中,中间件是一个函数,它接收一个请求(Request)和一个响应(Response)对象,以及一个用于调用下一个中间件的函数作为参数。中间件可以执行以下任务:

  1. 执行操作:在请求到达最终的处理程序之前或响应返回给客户端之前,执行某些操作。
  2. 修改请求和响应:检查、修改或添加请求和响应的内容。
  3. 终止请求-响应周期:在中间件中直接发送响应,不再调用链中的下一个中间件或处理程序。
  4. 错误处理:捕获和处理请求-响应周期中发生的错误。
  5. 日志记录:记录请求和响应的详细信息,用于调试和监控。
  6. 身份验证和授权:检查用户是否有权访问特定的资源。
  7. 跨域资源共享(CORS):处理跨域请求的问题。
  8. 状态监控:监控应用的性能和健康状况。

消息队列中的中间件:

在消息队列系统中,中间件是一种软件,它管理不同应用程序之间的消息传递。它提供了消息的路由、过滤、转换和持久化等功能。

其他上下文中的中间件:

在不同的技术领域,中间件可能有不同的含义,例如:

  • 数据库中间件:管理数据库和应用程序之间的交互。
  • 网络中间件:处理网络通信和数据传输。
  • 操作系统中间件:提供操作系统服务的抽象。

中间件的主要优点是它提供了一种解耦和模块化的方式来处理请求和响应,使得代码更加清晰、可维护和可扩展。在现代Web框架中,中间件是构建大型、复杂Web应用的关键组件。

二、工作机制

在Web开发中,中间件作为请求处理管道的一部分,允许你在请求到达最终的处理函数(或路由处理器)之前,以及在响应返回给客户端之前,对请求和响应进行操作。以下是中间件在Web开发中工作的基本流程:

请求处理流程

  1. 接收请求:用户的请求首先到达Web服务器。
  2. 路由匹配:服务器将请求路由到相应的处理函数。
  3. 中间件链:在到达最终的处理函数之前,请求会通过一系列中间件。
  4. 执行中间件:每个中间件可以对请求进行读取、修改或添加信息。
  5. 调用下一个中间件:如果中间件不终止请求-响应周期,它会调用下一个中间件,直到链中的最后一个中间件。
  6. 最终处理函数:请求通过所有中间件后,到达最终的处理函数。
  7. 生成响应:处理函数生成响应。
  8. 中间件链的逆向执行:响应可能会通过中间件链的逆序执行,允许中间件对响应进行操作或修改。

中间件的工作机制

  • 非侵入性:中间件通常作为独立的函数或对象存在,它们可以被重用和共享。
  • 顺序执行:中间件按照定义的顺序执行,这对于请求和响应的处理非常重要。
  • 调用下一个中间件:每个中间件都有一个机制来调用链中的下一个中间件,通常是通过一个回调函数或传递一个函数引用。
  • 终止请求-响应周期:中间件可以决定是否继续执行链中的下一个中间件,或者直接发送响应并结束请求-响应周期。
  • 错误处理:中间件可以捕获和处理请求处理过程中的错误,并生成相应的错误响应。

示例:Express.js 中间件

以下是Node.js的Express框架中中间件的一个简单示例:

const express = require('express');
const app = express();// 中间件1:记录请求时间
app.use((req, res, next) => {console.log('Time: ', Date.now());next(); // 调用下一个中间件
});// 中间件2:请求日志
app.use((req, res, next) => {console.log(`${req.method} ${req.url}`);next(); // 调用下一个中间件
});// 最终处理函数
app.get('/', (req, res) => {res.send('Hello World!');
});app.listen(3000, () => {console.log('Server is running on port 3000');
});

在这个示例中,两个中间件被添加到中间件链中。每个中间件都打印一些信息,然后调用next()来传递控制权给下一个中间件。最终,请求到达根路由'/'的处理函数,生成响应。

中间件的这种工作方式使得Web应用可以灵活地添加各种功能,如身份验证、日志记录、错误处理等,而不需要修改核心的处理逻辑。

三、常用功能

在实际的Web开发中,中间件被用来实现多种处理,以增强应用的功能、安全性、性能和可维护性。以下是一些常见的处理任务,通常通过中间件来实现:

  1. 请求路由

    • 将不同的HTTP请求路由到相应的处理函数。
  2. 身份验证和授权

    • 验证用户身份,确保只有授权用户才能访问特定的资源。
  3. 日志记录

    • 记录请求和响应的详细信息,用于调试、监控和审计。
  4. 错误处理

    • 捕获和处理请求处理过程中的错误,并返回适当的错误响应。
  5. 数据验证

    • 验证传入数据是否符合预期的格式和类型,确保数据的完整性。
  6. 请求限流

    • 控制请求的频率,防止服务过载。
  7. 跨域资源共享(CORS)

    • 处理跨域请求,允许或限制外部域的资源访问。
  8. 会话管理

    • 管理用户会话,处理登录状态和会话持久化。
  9. 缓存

    • 缓存请求结果以提高响应速度和减少数据库负载。
  10. 静态文件服务

    • 提供静态文件(如图片、CSS、JavaScript文件)的服务。
  11. 压缩

    • 压缩响应数据,减少传输数据量,提高加载速度。
  12. 安全增强

    • 实施安全措施,如HTTPS重定向、XSS防护、CSRF令牌等。
  13. 请求和响应修改

    • 修改请求头、请求体或响应头、响应体。
  14. API版本管理

    • 管理API的不同版本,便于向后兼容和版本迁移。
  15. 负载均衡

    • 分配请求到多个服务器,以平衡负载。
  16. 数据库连接管理

    • 管理数据库连接池,优化数据库资源的使用。
  17. 消息队列集成

    • 集成消息队列服务,处理异步任务和事件。
  18. 服务监控和追踪

    • 集成监控和追踪系统,如Prometheus、Zipkin,以监控服务健康状况和性能。
  19. 国际化和本地化

    • 处理多语言支持,根据用户偏好返回本地化内容。
  20. API网关功能

    • 提供API网关功能,如请求路由、负载分配、API组合和协议转换。
  21. 配置管理

    • 动态加载和更新配置,而无需重新启动服务。
  22. 文件上传和下载管理

    • 处理文件上传和下载请求。

通过使用中间件,开发者可以将这些通用功能抽象出来,使得代码更加模块化和可重用,同时也简化了业务逻辑的处理。不同的Web框架和库提供了不同的中间件支持和实现方式,开发者可以根据具体需求选择合适的中间件来实现上述功能。

四、应用示例

下面是一个使用Gin框架构建Web服务器并使用多个中间件的完整示例。这个示例将包括日志记录、请求限流、CORS处理和简单的请求处理中间件。

1. 安装Gin

首先,确保你已经安装了Gin:

go get -u github.com/gin-gonic/gin

2. 创建中间件

我们将创建几个中间件文件:

日志记录中间件(logger.go)
package middlewareimport ("github.com/gin-gonic/gin""time"
)func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 请求到达时间start := time.Now()// 处理请求c.Next()// 记录请求信息latency := time.Since(start)reqMethod := c.Request.Methodpath := c.Request.URL.PathstatusCode := c.Writer.Status()println(reqMethod + " " + path + " " + strconv.Itoa(statusCode) + " " + latency.String())}
}
请求限流中间件(limiter.go)
package middlewareimport ("github.com/gin-gonic/gin""net/http""sync/atomic""time"
)var limit int64 = 10 // 每秒允许的请求数
var lastTimestamp int64
var count int64func Limiter() gin.HandlerFunc {return func(c *gin.Context) {now := time.Now().Unix()if now-atomic.LoadInt64(&lastTimestamp) > 1 {atomic.StoreInt64(&lastTimestamp, now)atomic.StoreInt64(&count, 0)}if atomic.AddInt64(&count, 1) > limit {c.JSON(http.StatusTooManyRequests, gin.H{"error": "Too many requests"})c.Abort()return}c.Next()}
}
CORS中间件(cors.go)
package middlewareimport ("github.com/gin-gonic/gin""net/http"
)func CORS() gin.HandlerFunc {return func(c *gin.Context) {c.Writer.Header().Set("Access-Control-Allow-Origin", "*")c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")if c.Request.Method == "OPTIONS" {c.AbortWithStatus(http.StatusNoContent)return}c.Next()}
}

3. 主程序(main.go)

main.go中,我们将使用上述中间件:

package mainimport ("github.com/gin-gonic/gin""myproject/middleware"
)func main() {r := gin.Default()// 使用CORS中间件r.Use(middleware.CORS())// 使用日志记录中间件r.Use(middleware.Logger())// 使用请求限流中间件r.Use(middleware.Limiter())// 定义路由r.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Welcome to the Gin server with middleware!",})})// 启动服务器r.Run(":8080")
}

4. 运行项目

保存所有文件,并在终端运行以下命令:

go run main.go

现在,你的Web服务器应该在localhost:8080上运行,并且已经应用了CORS、日志记录和请求限流中间件。

这个示例展示了如何在Gin框架中集成多个中间件来增强Web服务器的功能。你可以根据需要添加更多的中间件来实现其他功能。

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

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

相关文章

Webpack学习笔记(2)

1.什么是loader? 上图是Webpack打包简易流程,webpack本身只能理解js和json这样的文件,loader可以让webpack解析其他类型文件,并且将文件转换成模块供我们使用。 test识别出那些文件被转换,use定义转换时使用哪个loader转换 上图…

【WebDriver】浏览器驱动下载及其配置

一、Windows电脑环境搭建-Chrome浏览器 行业内,Chrome (谷歌) 浏览器对于自动化程序来讲是比较稳定的. 自动化程序推荐使用 Chrome 浏览器的原因有几个: 开发者工具:Chrome 提供强大的开发者工具,方便调试和测试自动化脚本。 稳…

list使用

目录 list介绍 list使用 list创建 list迭代器 容量操作 元素访问 修改元素 其他操作 list介绍 ● list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代 ● list的底层是双向链表结构,双向链表中每个元素存…

【AIGC】如何高效使用ChatGPT挖掘AI最大潜能?26个Prompt提问秘诀帮你提升300%效率的!

还记得第一次使用ChatGPT时,那种既兴奋又困惑的心情吗?我是从一个对AI一知半解的普通用户,逐步成长为现在的“ChatGPT大神”。这一过程并非一蹴而就,而是通过不断的探索和实践,掌握了一系列高效使用的技巧。今天&#…

windows 使用python共享网络给另外一个网卡

# -*- coding: utf-8 -*- import subprocessdef open_share(to_shared_adapter, from_shared_adapter):"""打开以太网的网络共享:return: None"""powershell_script f"""# Register the HNetCfg library (once)# regsvr32 hnetc…

devops-部署Harbor实现私有Docker镜像仓库

文章目录 概述下载配置安装安装后生成的文件使用和维护Harbor参考资料 概述 Harbor是一个开源注册中心,它使用策略和基于角色的访问控制来保护工件,确保镜像被扫描并且没有漏洞,并将镜像签名为可信的。Harbor是CNCF的一个毕业项目&#xff0…

Java深拷贝和浅拷贝区别?

大家好,我是锋哥。今天分享关于【Java深拷贝和浅拷贝区别?】面试题。希望对大家有帮助; Java深拷贝和浅拷贝区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Java中,深拷贝(Deep Copy)和浅拷贝&am…

Linux文件属性 --- 硬链接、所有者、所属组

三、硬链接数 1.目录 使用“ll”命令查看,在文件权限的后面有一列数字,这是文件的硬链接数。 对于目录,硬链接的数量是它具有的直接子目录的数量加上其父目录和自身。 下图的“qwe”目录就是“abc”目录的直接子目录。 2.文件 对于文件可…

MobileLLM开发安卓AI的体验(一)

MobileLLM是一个在安卓端跑的大语言模型,关键它还有调动api的能力 https://github.com/facebookresearch/MobileLLM 项目地址是这个。 看了下,似乎还是中国人团队 article{liu2024mobilellm, title{MobileLLM: Optimizing Sub-billion Parameter Langua…

【WRF安装】WRF编译错误总结1:HDF5库包安装

目录 1 HDF5库包安装有误:HDF5 not set in environment. Will configure WRF for use without.HDF5的重新编译 错误原因1:提示 overflow 错误1. 检查系统是否缺少依赖库或工具2. 检查和更新编译器版本3. 检查 ./configure 报错信息4. 检查系统环境变量5.…

大模型微调---Prompt-tuning微调

目录 一、前言二、Prompt-tuning实战2.1、下载模型到本地2.2、加载模型与数据集2.3、处理数据2.4、Prompt-tuning微调2.5、训练参数配置2.6、开始训练 三、模型评估四、完整训练代码 一、前言 Prompt-tuning通过修改输入文本的提示(Prompt)来引导模型生…

【UE5】pmx导入UE5,套动作。(防止“气球人”现象。

参考视频:UE5Animation 16: MMD模型與動作導入 (繁中自動字幕) 问题所在: 做法记录(自用) 1.导入pmx,删除这两个。 2.转换给blender,清理节点。 3.导出时,内嵌贴图,选“复制”。 …

005 QT常用控件Qwidget_上

文章目录 前言控件概述QWidgetenable属性geometry属性windowTitle属性windowlcon属性 小结 前言 本文将会向你介绍常用的Qwidget属性 控件概述 Widget 是 Qt 中的核心概念. 英文原义是 “⼩部件”, 我们此处把它翻译为 “控件” . 控件是构成⼀个图形化界面的基本要素. QWi…

gitlab初始化+API批量操作

几年没接触gitlab了,新版本装完以后代码提交到默认的main分支,master不再是主分支 项目有几十个仓库,研发提交代码后仓库地址和之前的发生了变化 有几个点 需要注意 1、修改全局默认分支 2、关闭分支保护 上面修改了全局配置不会影响已经创…

如何用上AI视频工具Sora,基于ChatGPT升级Plus使用指南

没有GPT,可以参考这个教程:详情移步至底部参考原文查看哦~ 1.准备工作 详情移步至底部参考原文查看哦~ 详情移步至底部参考原文查看哦~ 4.Sora使用 详情移步至底部参考原文查看哦 参考文章:【包教包会】如何用上AI视频工具Sora&#xff…

如何查看K8S集群中service和pod定义的网段范围

在我们创建部署K8S集群的开头时候 不是需要在master节点上执行一条这样的命令嘛? kubeadm init --apiserver-advertise-address192.168.60.130 --control-plane-endpointcluster-master --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers -…

使用 Marp 将 Markdown 导出为 PPT 后不可编辑的原因说明及解决方案

Marp 是一个流行的 Markdown 演示文稿工具,能够将 Markdown 文件转换为 PPTX 格式。然而,用户在使用 Marp 导出 PPT 时,可能会遇到以下问题: 导出 PPT 不可直接编辑的原因 根据 Marp GitHub 讨论,Marp 导出的 PPTX 文…

redis 缓存使用

工具类 package org.springblade.questionnaire.redis;import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factor…

level2逐笔委托查询接口

沪深逐笔委托队列查询 前置步骤 分配数据库服务器 查询模板 以下是沪深委托队列查询的请求模板&#xff1a; http://<数据库服务器>/sql?modeorder_book&code<股票代码>&offset<offset>&token<token>查询参数说明 参数名类型说明mo…

游戏AI实现-寻路算法(DFS)

​深度优先搜索算法&#xff08;英语&#xff1a;Depth-First-Search&#xff0c;缩写为DFS&#xff09;是一种用于遍历或搜索树或图的算法。 寻路地图搭建&#xff1a; 游戏AI实现-寻路地图搭建-CSDN博客 算法过程&#xff1a;遍历方向为从竖直向上沿顺时针方向 1.首先将开…