首页 > 其他分享 >Mygin中间件优化及sync.Pool上下文复用

Mygin中间件优化及sync.Pool上下文复用

时间:2024-01-30 15:00:13浏览次数:24  
标签:case return func 中间件 sync Mygin context http

本篇是mygin的第六篇,参照gin框架,感兴趣的可以从 Mygin第一篇 开始看,Mygin从零开始完全手写,在实现的同时,带你一窥gin框架的核心原理实现。

目的

  • 中间件Middleware优化
  • 默认log日志中间件
    在上篇 Mygin实现中间件Middleware 中间件Middleware很生硬,完全依赖循环,如果某个中间件想要cover住全部中间件,比如我想记录,整个请求的耗时时间,以便针对优化的功能。因此需要把之前生硬的方式做一些修改。

修改

1.实例化上下文修改
//实例化一个下上文
	c := &Context{
		Request:  r,
		Writer:   w,
		Params:   params,
		handlers: handlers,
		index:    -1, //默认下标为-1
	}
2.修改上下文Next方法
// Next 执行链中的剩余处理程序。
func (c *Context) Next() {
	c.index++
	//遍历handlers
	for c.index < int8(len(c.handlers)) {
		//真正调用执行handler方法
		c.handlers[c.index](c)
		c.index++
	}
}

日志

参照(复制)gin中的写法,新建mygin/logger.go日志中间件文件。

  • mygin/logger.go
package mygin

import (
	"fmt"
	"net/http"
	"time"
)

const (
	green   = "\033[97;42m" // 绿色
	white   = "\033[90;47m" // 白色
	yellow  = "\033[90;43m" // 黄色
	red     = "\033[97;41m" // 红色
	blue    = "\033[97;44m" // 蓝色
	magenta = "\033[97;45m" // 洋红色
	cyan    = "\033[97;46m" // 青色
	reset   = "\033[0m"     // 重置颜色
)

type LogFormatterParams struct {
}

// MethodColor 方法颜色获取
func (l *LogFormatterParams) MethodColor(method string) string {
	switch method {
	case http.MethodGet:
		return blue
	case http.MethodPost:
		return cyan
	case http.MethodPut:
		return yellow
	case http.MethodDelete:
		return red
	case http.MethodPatch:
		return green
	case http.MethodHead:
		return magenta
	case http.MethodOptions:
		return white
	default:
		return reset
	}
}

// StatusCodeColor 状态颜色获取
func (l *LogFormatterParams) StatusCodeColor(code int) string {
	switch {
	case code >= http.StatusOK && code < http.StatusMultipleChoices:
		return green
	case code >= http.StatusMultipleChoices && code < http.StatusBadRequest:
		return white
	case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
		return yellow
	default:
		return red
	}
}

// LoggerFunc 记录日志的方法
func (l *LogFormatterParams) LoggerFunc() HandlerFunc {
	return func(context *Context) {
		// 启动时间
		start := time.Now()

		// 后续处理请求
		context.Next()

        //后续处理请求 结束时间
		now := time.Now()

		str := fmt.Sprintf("[MyGIN] %v |%s %3d %s| %13v  |%s %-7s %s %#v\n",
			now.Format("2006/01/02 - 15:04:05"),
			l.StatusCodeColor(context.status), context.status, reset,
			now.Sub(start), //耗时
			l.MethodColor(context.Request.Method), context.Request.Method, reset,
			context.Request.URL.Path,
		)
		fmt.Println(str)
	}
}

日志中间件

测试

测试代码

package mygin

import (
	"net/http"
	"path"
	"testing"
)

func TestMyGin06(t *testing.T) {
	r := Default()
	r.Use()
	//测试需要登录
	group := r.Group("/api", func(context *Context) {
		//todo....
		context.String(http.StatusOK, "api Group 中间件失败了....\n")
		context.Abort()
	})

	group.Use()

	//这个回调不会执行
	group.GET("/hello/:name", func(context *Context) {
		name := context.Params.ByName("name")
		context.String(http.StatusOK, path.Join("hello ", name, "!"))
	})

	//测试没有发生Abort
	group2 := r.Group("/api2", func(context *Context) {
		//todo....
		context.String(http.StatusOK, "api Group 中间件成功了....\n")
	})

	//这个回调会执行
	group2.GET("/hello2/:name", func(context *Context) {
		name := context.Params.ByName("name")
		context.String(http.StatusOK, path.Join("hello2 ", name, "!\n"))
	})

	// 启动服务器并监听端口
	r.Run(":8088")
}
启动测试
go test
curl请求测试
curl -i http://localhost:8088/api2/hello2/scott
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 30 Jan 2024 06:56:03 GMT
Content-Length: 49

api Group 中间件成功了....
hello2 /scott/!
➜  ~ curl -i http://localhost:8088/api/hello/scott
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 30 Jan 2024 06:56:26 GMT
Content-Length: 33

api Group 中间件失败了....
查看控制台输出

标签:case,return,func,中间件,sync,Mygin,context,http
From: https://www.cnblogs.com/pengb/p/17997115

相关文章

  • 无涯教程-ExpressJS - 中间件(Middleware)
    中间件(Middleware)函数是可以访问请求对象(requestobject),响应对象(responseobject)以及应用程序的请求(request)-响应(response)中的下一个中间件函数。这些函数用于修改req和res对象,以执行诸如解析请求正文(responstbodies),添加响应标头(responseheaders)等任务。这......
  • 专栏:数据库、中间件的监控一网打尽
    前言对于数据库、中间件的监控,目前社区里最为完善的就是Prometheus生态的各个Exporter,不过这些Exporter比较分散,不好管理,如果有很多目标实例需要监控,就要部署很多个Exporter,要是能有一个大一统的Exporter,具备所有这些Exporter的能力就好了。还真有,而且还不止一个,一个是 G......
  • 专栏:数据库、中间件的监控一网打尽
    前言对于数据库、中间件的监控,目前社区里最为完善的就是Prometheus生态的各个Exporter,不过这些Exporter比较分散,不好管理,如果有很多目标实例需要监控,就要部署很多个Exporter,要是能有一个大一统的Exporter,具备所有这些Exporter的能力就好了。还真有,而且还不止一个,一个是......
  • go中间件实现登录验证
    一、概述在java中可以使用过滤器、拦截器实现登录验证(验证token的有效性、判断哪些路径需要登录、哪些路径不需要登录)等等的一些公共性的验证操作。go语言中有没有类似的东西呢,答案是有的,go语言中可以使用中间件来完成这个操作。接下来使用gin+中间件的形式来验证t......
  • rsync基本使用
    参考:https://www.cnblogs.com/f-ck-need-u/p/7220009.htmlrsync官方网站:https://www.samba.org/ftp/rsync/rsync.html参数说明Local:rsync[OPTION...]SRC...[DEST]Accessviaremoteshell:Pull:rsync[OPTION...][USER@]HOST:SRC...[DEST]Push:rsync[OPT......
  • net8 对接webapi接口通过 GetFromJsonAsAsyncEnumerable方法直接得到对象,无需进行反序
    调用API直接获取到对象现在有一个接口返回如下图中的数据:如果是在8以前的版本中获取该接口的数据,需要先获取到接口内容,然后进行反序列化,代码如下conststringRequestUri="http://localhost:5145/user";usingvarclient=newHttpClient();varstream=awaitclient......
  • 事务提交之后再执行某些操作 → 引发对 TransactionSynchronizationManager 的探究
    开心一刻昨晚,小妹跟我妈聊天小妹:妈,跟你商量个事,我想换车,资助我点呀妈:哎呀,你那分扣的攒一堆都够考清华的,还换车资助点,有车开就不错了小妹:你要是这么逼我,别说哪天我去学人家傍大款啊妈:哎呀妈,你脸上那褶子比你人生规划都清晰,咋地,大款缺地图呀,找你?小妹:......
  • FreeFileSync文件同步软件使用
    设置FFS程序下载安装程序出现两个程序。FreeFileSync是主程序,RealTimeSync用来设置自动同步打开FreeFileSync主程序,点击蓝色设置按钮比较设置界面同步设置界面一般设置双向,即只要有一边变化即同步。为了保险起见,设置保留历史版本最后确定设置需要同步的文件夹......
  • C# AsyncLocal 是如何实现 Thread 间传值
    一:背景1.讲故事这个问题的由来是在.NET高级调试训练营第十期分享ThreadStatic底层玩法的时候,有朋友提出了AsyncLocal是如何实现的,虽然做了口头上的表述,但总还是会不具体,所以觉得有必要用文字+图表的方式来系统的说一下这个问题。二:AsyncLocal线程间传值1.线程间传值途径在C#编......
  • synchronized详解
    synchronized?是Java中的关键字,是一种同步锁。主要应用于多线程环境下保证线程的安全性。四种用法修饰一个代码块         被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;synchronized(this)classSyncTh......