「Go框架」gin框架是如何处理panic的?

本文我们介绍下recover在gin框架中的应用。 首先,在golang中,如果在子协程中遇到了panic,那么主协程也会被终止。如下:

package main

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

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

    // 在子协程中引起panic,主协程也会退出
	go func() {
		panic("hello world")
	}()
    
	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

panic被描述为不可处理的错误。在web服务中就是服务会崩溃。当然,这在生产环境下是不可接受的。那么,如何能够做到发生panic时技能捕获该panic又能让服务继续健康运行呢?
这就是golang中提供的recover函数了。recover函数能够捕获Panic错误并恢复程序的正常运行。
接下来,我们看下recover函数在gin框架中是如何应用的。
首先,要提到的就是gin框架中的recovery中间件。在gin中,是通过使用该中间件来捕获panic,并保证服务不down机的。 如果使用gin.Default()函数进行构建gin对象,那么默认就注册了Recovery中间件。

func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
    //  注册了Recovery中间件
	engine.Use(Logger(), Recovery())
	return engine
}

其次,我们来看下Recovery()中间件都做了些什么。

Recovery()函数定义如下:

func Recovery() HandlerFunc {
	return RecoveryWithWriter(DefaultErrorWriter)
}

这里的DefaultErrorWriter是默认的输出端,即os.Stderr。即指错误的输出到什么地方。

接下来看RecoveryWithWriter函数中的实现

// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
	if len(recovery) > 0 {
		return CustomRecoveryWithWriter(out, recovery[0])
	}
	return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}

这里有一个参数是defaultHandleRecovery,我们看下它的实现:

func defaultHandleRecovery(c *Context, err any) {
	c.AbortWithStatus(http.StatusInternalServerError)
}

就是写入了一个代表内部服务器错误的状态码500,并结束了本次请求。

这里关键点是CustomRecoveryWithWriter的实现,代码很长,我们分段来看。如下:
在这里插入图片描述
主要分三部分:

将日志输出到out中,这里是上述提到的DefaultErrorWriter,即os.Stderr。
defer延迟执行部分。
c.Next()正常请求处理器部分。

这里需要注意的点就是:

recover函数需要再defer中调用。因为defer是在函数返回时才调用,所以当发生panic时会导致函数返回,这样才能捕获panic。
作为中间件运行,说明每次请求的处理器都被中间件包装了,也就相当于每个请求处理器都有这个defer函数。
在defer函数中,如果捕获了panic,则将panic的详细详细记录下来,可以发送到指定的输出中,即函数中指定的out参数(默认是os.Stderr),也可以指定其他的文件或Sentry等。

在gin中,正是该中间件的应用,确保了web服务的健壮性。当然,其他的web框架也有同样的机制,实现原理也是一样的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

20:kotlin 类和对象 --泛型(Generics)

类可以有类型参数 class Box<T>(t: T) {var value t }要创建类实例&#xff0c;需提供类型参数 val box: Box<Int> Box<Int>(1)如果类型可以被推断出来&#xff0c;可以省略 val box Box(1)通配符 在JAVA泛型中有通配符?、? extends E、? super E&…

[STM32-1.点灯大师上线】

学习了江协科技的前4课&#xff0c;除了打开套件的第一秒是开心的&#xff0c;后面的时间都是在骂娘。因为51的基础已经几乎忘干净&#xff0c;c语言已经还给谭浩强&#xff0c;模电数电还有点底子&#xff0c;硬着头皮上吧。 本篇主要是讲述学习点灯的过程和疑惑解释。 1.工…

为什么每天都要做晨会?揭秘研发团队的默契背后

嗨&#xff0c;亲爱的小米粉丝们&#xff01;欢迎来到小米科技的微信公众号&#xff0c;我是小米&#xff0c;一个对技术充满热情、乐于分享的小伙伴。今天&#xff0c;我们要聊的话题是在研发过程中为什么每天都要进行晨会。 晨会是什么&#xff1f; 首先&#xff0c;我们得…

springboot的常用注解

声明解释这个对象&#xff08;类或者其他&#xff09;组件相关 名称作用Controller用于修饰MVC中controller层的组件SpringBoot中的组件扫描功能会识别到该注解&#xff0c;并为修饰的类实例化对象&#xff0c;通常与RequestMapping联用&#xff0c;当SpringMVC获取到请求时会…

用友NC word.docx接口存在任意文件读取漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 一、产品介绍 用友 NC Cloud&#xff0c;大型企业数字化平台&#xff…

DC电源模块的常见故障有哪些?

BOSHIDA DC电源模块的常见故障有哪些&#xff1f; DC电源模块是电子设备中常见的电源供应模块&#xff0c;它可以将交流电转化为直流电供给设备使用。然而&#xff0c;由于长期的使用和外界环境等因素的影响&#xff0c;DC电源模块也会出现各种故障。下面我们来介绍一下常见的…

CentOS 7 虚拟机java项目部署tomcat

首先安装java环境 下载安装包:jdk-19_linux-x64_bin.tar.gz_免费高速下载|百度网盘-分享无限制 (baidu.com) 将安装包上传到虚拟机 解压 tar zxvf jdk-19_linux-x64_bin.tar.gz 移动文件到 mv jdk-19.0.1 /usr/jdk-19.0.1 编辑配置文件 vim /etc/profile export JAVA…

卷积神经网络中用1*1 卷积有什么作用或者好处呢?

一、来源&#xff1a;[1312.4400] Network In Network &#xff08;如果11卷积核接在普通的卷积层后面&#xff0c;配合激活函数&#xff0c;即可实现network in network的结构&#xff09; 二、应用&#xff1a;GoogleNet中的Inception、ResNet中的残差模块 三、作用&#x…

16、fixture的其它使用特点

官方实例 # content of test_use_more_fixture.py import pytest# Arrange pytest.fixture def first_entry():return "a"# Arrange pytest.fixture def second_entry():return 2# Arrange pytest.fixture def order(first_entry, second_entry):return [first_entr…

Ubuntu20.04安装向日葵、开机自启、解决windows系统远程黑屏(笔记)

这里写目录标题 动机1. Ubuntu20.04 安装向日葵2. 设置开机自启3. 解决windows不可远程的问题4. 大公告成 动机 办公室有个工作站&#xff0c;要比我的笔记本的CPU稍微好一点&#xff0c;用来跑陆面过程。我信心满满的装了个Ubuntu20.04双系统,但是发现向日葵安装不上了。我少…

基于CentOS7.9搭建LNMP

今天为大家搭建一下基于CentOS7.9服务器部署LNMP,方便未来基于lnmp部署应用程序。 1.CentOS7.9基础配置 为了实现基于CentOS7.9服务器部署LNMP,CentOS7.9服务器需要满足一定的基础需要。具体参考:Linux常规基础配置_linux操作系统配置_小黑要上天的博客-CSDN博客 2.服务器…

lv11 嵌入式开发 RTC 17

目录 1 RTC简介 ​编辑2 Exynos4412下的RTC控制器 2.1 概述 2.2 特征 2.3 功能框图 3 寄存器介绍 3.1 概述 3.2 BCD格式的年月日寄存器 3.3 INTP中断挂起寄存器 3.4 RTCCON控制寄存器 3.5 CURTICCNT 作为嘀嗒定时器使用的寄存器 4 RTC编程 5 练习 1 RTC简介 RTC(…

linux部署前端静态页面(实战)

Linux基本命令&#xff08;学习笔记&#xff09;零基础入门linux系统运维_linux find exec rm_Z_Xshan的博客-CSDN博客 如果linux不熟可以看我之前写的入门教程 感谢支持&#xff01;&#xff01; 一、服务器 这里去购买云服务器&#xff0c;如果是练习可以用虚拟机&#xff…

06、pytest将多个测试放在一个类中

官方用例 # content of test_class.py # 实例1 class TestClass:def test_one(self):x "this"assert "h" in xdef test_two(self):x "hello"assert hasattr(x,"check")# content of test_class_demo.py # 每个测试都有唯一的类实例…

《形式语言与自动机理论(第4版)》笔记(二)

文章目录 [toc]前导《形式语言与自动机理论&#xff08;第4版&#xff09;》笔记&#xff08;一&#xff09; 第三章&#xff1a;有穷状态自动机3.1|语言的识别3.2|有穷状态自动机即时描述 s e t ( ) set() set()例题问题 1 1 1解答问题 2 2 2解答 3.3|不确定的有穷状态自动机构…

机器学习——logistic回归

在之前实验接触到的机器学习算法都是的目的都是对数据集进行分类&#xff0c;即预测得到的结果是数据样本所属的类别&#xff0c;预测输出结果是离散的集合&#xff0c;比如{‘是’&#xff0c;‘不是’}。这次实验学习的是回归模型&#xff0c;与分类模型不同的是&#xff0c;…

邻接矩阵深度优先遍历

深度优先遍历&#xff08;Depth-First Search&#xff0c;DFS&#xff09;是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都己被探寻过&#xff0c;搜索将回溯到发现节点v的那条边的起始节点。 在用邻接矩阵表示的图中进行深度优先遍历…

第N个泰波那锲数

1.题目解析 动态规划算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 为了填写当前状态的时候&#xff0c;所需要的状态已经计算过了&#xff01;&#xff01;&#xff01; 5.返回值 题目要求 状态表示 ------------------------------------------------------…

单机游戏推荐:巨击大乱斗 GIGABASH 中文安装版

在泰坦之中称霸天下吧&#xff01;《GigaBash 巨击大乱斗》是一款多人战斗擂台游戏&#xff0c;有着受特摄片启发的巨型怪兽&#xff0c;具有传奇色彩的英雄&#xff0c;震天动地的特别攻击&#xff0c;以及可以完全摧毁的擂台场景。 ​游戏特点 怪物大解放 多达10个独特的角…

U2 文法和语言

文章目录 一、预备知识1、字母表和符号串2、符号串形式定义3、符号串相等4、延申 二、文法1、 一些概念2、文法的定义3、推导的形式定义4、规范推导5、语言的形式定义6、递归文法7、BNF范式总结 三、短语、简单短语和句柄四、语法树(推导树)1、概念2、语法树推导--句型的推导3、…