go-zero(八) 中间件的使用

go-zero 中间件

一、中间件介绍

中间件(Middleware)是一个在请求和响应处理之间插入的程序或者函数,它可以用来处理、修改或者监控 HTTP 请求和响应的各个方面。

1.中间件的核心概念

  1. 请求拦截:中间件能够在请求到达目标处理器之前,对请求进行分析、修改或记录。

  2. 响应拦截:同样,中间件也可以在响应返回给客户端之前,对响应进行处理,例如添加 headers、压缩响应体、格式化响应数据等。

  3. 链式调用:多个中间件可以串联在一起,形成一个中间件链,依次处理请求和响应。

2.中间件的用途

中间件可以用于以下多个方面:

  1. 日志记录:记录 HTTP 请求和响应的详细信息,例如请求路径、方法、状态码等。这有助于进行审计和调试。

  2. 认证和授权:验证请求是否具有必要的权限,确保用户或系统的身份是否合法。这对于保护敏感接口尤其重要。

  3. 请求限流:控制访问速率,避免服务被恶意请求或流量洪水淹没。这可以提高系统的稳定性和可用性。

  4. 跨域资源共享 (CORS):处理浏览器的跨域请求。中间件可以在响应中添加适当的 CORS 头,允许来自不同源的请求。

  5. 错误处理:捕获处理过程中的错误(如 panic)并生成适当的 HTTP 响应。这样可以确保系统在错误情况下不会崩溃,并能够正常返回相应。

  6. 数据格式化:统一请求和响应的数据格式,例如将响应数据转换为 JSON 格式,或者对请求中的参数进行验证和转换。

  7. 国际化 (i18n):处理用户的语言偏好和内容的本地化,使应用能够支持多语言。

3.中间件的工作流程

一般来说,工作流程如下:

  1. 用户发起请求,请求到达 Web 服务器。
  2. 中间件链开始处理:
    • 第一个中间件接收请求,进行相应的处理(如日志记录)。
    • 控制权传递给下一个中间件。
    • 这个过程可以一直持续,直到所有中间件处理完请求。
  3. 最终请求到达目标处理器,处理器生成响应。
  4. 响应同样会经过中间件链进行处理(如添加 headers)。
  5. 最终响应返回给用户。

二、go-zero内置中间件介绍

go-zero 提供了一系列内置的中间件, 之前我们使用的JWT鉴权就使用了内置的鉴权管理中间件 帮助我们实现了自动验证Token。

在 go-zero 中内置了如下中间件:

  • 鉴权管理中间件 AuthorizeHandler
  • 熔断中间件 BreakerHandler
  • 内容安全中间件 ContentSecurityHandler
  • 解密中间件 CryptionHandler
  • 压缩管理中间件 GunzipHandler
  • 日志中间件 LogHandler
  • ContentLength 管理中间件 MaxBytesHandler
  • 限流中间件 MaxConnsHandler
  • 指标统计中间件 MetricHandler
  • 普罗米修斯指标中间件 PrometheusHandler
  • panic 恢复中间件 RecoverHandler
  • 负载监控中间件 SheddingHandler
  • 超时中间件 TimeoutHandler
  • 链路追踪中间件 TraceHandler

这些中间件的具体实现可以去看github.com\zeromicro\go-zero@v1.7.3\rest\handler目录的内容。

1. 开/关中间件

以上中间件默认启用, 如果想要关闭其中的中间件,我们可以通过配置文件来控制。

如果你看过RestConf 的代码,就应该能看到,它里面包含了一个Middlewares 中间件的配置结构。

	RestConf struct {service.ServiceConfHost     string `json:",default=0.0.0.0"`Port     int/*....*///中间件配置相关的结构体Middlewares MiddlewaresConf// TraceIgnorePaths is paths blacklist for trace middleware.}

我们可以看下它的具体内容,可以看到这个结构体主要用来控制,这些中间件是否启动,默认都是开启状态:

MiddlewaresConf struct {Trace      bool `json:",default=true"`Log        bool `json:",default=true"`Prometheus bool `json:",default=true"`MaxConns   bool `json:",default=true"`Breaker    bool `json:",default=true"`Shedding   bool `json:",default=true"`Timeout    bool `json:",default=true"`Recover    bool `json:",default=true"`Metrics    bool `json:",default=true"`MaxBytes   bool `json:",default=true"`Gunzip     bool `json:",default=true"`}

那么如何控制这些中间件是否关闭就很简单了,例如我想关闭普罗米修斯指标中间件,打开yaml文件:

Middlewares:Prometheus: false #把值设置为false

关于内置中间件展示就介绍这么多,后面有机会给大家详细介绍下具体的使用方法。

三、自定义中间件

1.局部中间件

在 go-zero 中,我们通过 api 语言来声明 HTTP 服务,然后通过 goctl 生成 HTTP 服务代码。

type (RegisterRequest {//请求体定义了 Username 和Password 字段, 并且都设置了不能为空Username string `json:"username" validate:"required"`Password string `json:"password" validate:"required"`}RegisterResponse {//响应体 定义类一个Message  用来返回结果Message string `json:"message"`}
)type (LoginRequest {Username string `json:"username" validate:"required"`Password string `json:"password" validate:"required"`}LoginResponse {Token string `json:"token"`}
)@server (group:      user // 代表当前 service 代码块下的路由生成代码时都会被放到 user 目录下prefix:     /v1 //定义路由前缀为 "/v1"middleware: TestMiddleware    
)

在上面的例子中,我们声明了一个中间件TestMiddleware,然后在 @server 中通过 middileware 关键字来声明中间件。

需要说明的,我们这个中间件是局部中间件,仅对当前的server有效 #EE3F4D

使用以下命令更新代码:

goctl api go --api user.api --dir .

命令执行完后,会在项目中生成middleware文件夹,我们可以先看下routes.go文件,可以看到这路由前面帮我加了一个中间件

在这里插入图片描述

接下来我们打开middleware目录下的文件,我们简单的添加一个header信息,修改代码:

func (m *TestMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {// TODO generate middleware implement function, delete after code implementation//我们自定义一个header信息w.Header().Set("xxxx", "aaaabb")next(w, r)}
}

然后把中间件注册到服务中,打开servicecontext.go文件:

type ServiceContext struct {Config                config.ConfigUserModel             model.UsersModelUserRpc               user.UserTestMiddleware rest.Middleware  //定义中间件
}func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config:                c,UserModel:             model.NewUsersModel(sqlx.NewMysql(c.MysqlDB.DbSource)),UserRpc:               user.NewUser(zrpc.MustNewClient(c.UserRpcConf)),//初始化中间件TestMiddleware Middleware: middleware.NewTestMiddleware Middleware().Handle,}
}

运行项目测试
在这里插入图片描述

2. 全局中间件

下面我们演示下全局中间件

首先我们创建一个 Middleware 方法:

func GlobalMiddleware(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {logx.Info("全局中间件")next(w, r)}
}

然后将其注册到 go-zero 的 rest 中

func main() {flag.Parse()var c config.Configconf.MustLoad(*configFile, &c)server := rest.MustNewServer(c.RestConf)defer server.Stop()//使用Use 注册中间件server.Use(middleware.GlobalMiddleware)ctx := svc.NewServiceContext(c)handler.RegisterHandlers(server, ctx)fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)server.Start()
}

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

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

相关文章

vscode ctrl+/注释不了css

方式一.全部禁用插件排查问题. 方式二.打开首选项的json文件,注释掉setting.json,排查是哪一行配置有问题. 我的最终问题:需要将 "*.vue": "vue",改成"*.vue": "html", "files.associations": { // "*.vue": &qu…

使用 Jina Embeddings v2 在 Elasticsearch 中进行后期分块

作者:来自 Elastic Gustavo Llermaly 在 Elasticsearch 中使用 Jina Embeddings v2 模型并探索长上下文嵌入模型的优缺点。 在本文中,我们将配置和使用 jina-embeddings-v2,这是第一个开源 8K 上下文长度嵌入模型,首先使用 semant…

电视网络机顶盒恢复出厂超级密码大全汇总

部分电视机顶盒在按遥控器设置键打开设置时,会弹出设置密码弹窗,需输入密码才能操作其中内容。 如下图所示: 部分电视机顶盒在选择恢复出厂设置时,会出现设置密码弹窗,只有输入操作密码后才能进行恢复出厂设置的操作。…

cmake原理

CMake原理与快速入门 CMake是一个跨平台的构建(build)工具,完成代码编译、链接、打包过程。在开发AI应用平台时,由于开发的平台是在边缘设备运行的,而边缘设备的算力不高,所以对平台的效率要求比较高&…

SFTP全解析:深入了解组件功能与适用场景

文章目录 一、组件功能二、适用场景三、SFTP优势四、SFTP原理五.SFTP与同类产品对比六、部署方案1.裸金属部署2.k8s容器化部署 七、高可用方案八、监控方案九、常见问题及解决方法 一、组件功能 安全文件传输协议SFTP(SSH File Transfer Protocol)是文件传输协议(F…

java——Spring MVC的工作流程

Spring MVC的工作流程是基于模型-视图-控制器(MVC)设计模式的一个典型实现,以下是其主要工作流程步骤: 客户端请求提交: 用户通过浏览器向服务器发送请求,该请求首先到达Spring MVC的前端控制器DispatcherS…

Mutex::Autolock 和 std::lock_guard 的区别

Mutex::Autolock 和 std::lock_guard 都是 C 中用于管理互斥锁(mutex)的一种方式,它们的目标是自动获取和释放锁,避免手动管理锁的复杂性,从而防止死锁和遗漏解锁等问题。尽管它们有相似的功能,但二者也存在…

<项目代码>YOLOv8 红绿灯识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

mac下安装Ollama + Open WebUI + Llama3.1

本文介绍mac下安装Ollama Open WebUI Llama3.1 8b具体步骤。 目录 推荐配置Ollama Open WebUI Llama3.1简介安装Ollama安装Open WebUI 推荐配置 m1以上芯片,16g内存,20g以上硬盘空间 Ollama Open WebUI Llama3.1简介 Ollama: 下载,管理…

Linux 无图形界面磁盘空间排查与优化实践20241127

Linux 无图形界面磁盘空间排查与优化实践 引言:磁盘空间问题的痛点与挑战 🔍 常见问题 当系统磁盘空间超过 90% 时,不仅可能导致性能下降,还可能让关键操作无法正常完成。这种情况下,如何高效且精准地排查磁盘占用来…

【AI】JetsonNano启动时报错:soctherm OC ALARM

1、问题描述 将JetsonNano烧写SD卡镜像为Ubuntu20.04后,启动时报错:soctherm OC ALARM,启动失败;然后系统一直重启 2、原因分析 “soctherm OC ALARM”是检测到系统温度超过安全阈值时发出的过热警告。 “soctherm”代表系统…

SycoTec 4060 ER-S德国高精密主轴电机如何支持模具的自动化加工?

SycoTec 4060 ER-S高速电主轴在模具自动化加工中的支持体现在以下几个关键方面: 1.高精度与稳定性:SycoTec 4060 ER-S锥面跳动小于1微米,确保了加工过程中的极高精度,这对于模具的复杂几何形状和严格公差要求至关重要。高精度加工…

d3-contour 生成等高线图

D3.js 是一个强大的 JavaScript 库,用于创建动态、交互式数据可视化。d3-contour 是 D3.js 的一个扩展模块,用于生成等高线图(contour plots)。 属性和方法 属性 x: 一个函数,用于从数据点中提取 x 坐标。y: 一个函…

Docker 部署 MongoDB

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: GitCode💫 Gitee &#x1f…

鸿蒙MVVM模式介绍与使用

文章目录 鸿蒙MVVM模式介绍与使用背景MVVM模式介绍相关装饰器介绍State状态变量Prop、Link的作用 MVVM架构模式的实现以及相关装饰器的使用具体实现效果 总结 鸿蒙MVVM模式介绍与使用 背景 最近在学习鸿蒙开发,想到了以前写安卓移动端应用时经常会用到的MVVM架构模式,就想着能…

解决SpringBoot连接Websocket报:请求路径 404 No static resource websocket.

问题发现 最近在工作中用到了WebSocket进行前后端的消息通信,后端代码编写完后,测试一下是否连接成功,发现报No static resource websocket.,看这个错貌似将接口变成了静态资源来访问了,第一时间觉得是端点没有注册成…

【RISC-V CPU 专栏 -- 香山处理器介绍】

文章目录 RISC-V 香山处理器介绍雁栖湖处理器南湖处理器RISC-V 香山处理器介绍 相信很多小伙伴对于“香山”都不陌生,它是一款开源RISC-V处理器核,香山的每一代架构,都是采用了湖的名字,第一代架构被命名为雁栖湖,第二代架构则叫做 “南湖”。 “雁栖湖”这款处理器的 R…

网络安全原理与技术思考题/简答题

作业1(第1章、第2章、第8章) 1. 网络安全的基本属性有哪些?简单解释每个基本属性的含义。网络安全的扩展属性包括哪些? 基本属性: 1.机密性(Confidentiality): 含义:确保信息不被未授权的用户…

小米note pro一代(leo)线刷、twrp、magisk、TODO: android源码编译

本文主要说android5 整体思路 android 5.1 twrp magisk Zygisk(Riru) Dreamland(xposed) Riru不支持android5.1, 因此只能选择Zygisk : 如果你正在使用 Android 5,你必须使用 Zygisk 因为 Riru 并不支持 Android 5. 基于magisk之上的xposed 其中提到的 作者…

英语知识网站:Spring Boot技术构建

6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…