Go语言内存管理详解 | 青训营笔记

229 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第7天

今天是大年初一,祝大家兔年吉祥,兔飞猛进啦~

一、重点内容:

  • 本次主要熟悉一下Hertz的使用,根据官方文档完成Hertz的练习并做下记录,为后续大项目打下扎实基础。同时也算对前期所学的内容进行一个复习和整理。

二、详细知识点介绍:

安装方法和过程就不介绍了,大家可以参考官方文档。下面直接开始Hertz的基本特性知识点介绍。

  1. 网络库
  • Hertz 默认集成了 Netpoll 和 Golang 原生网络库 两个网络库,用户可以根据自己的场景选择合适的网络库以达到最佳性能。对于 Server 来说,默认使用 netpoll。

  • 注意:

      1. 如果有启动 TLS Server 的需求,请使用 go net 网络库。netpoll 正在实现对 TLS 的支持。
      1. 由于网络库触发模式的不同:go net 为 ET 模型,netpoll 为 LT 模型,使得两个网络库的适用场景有一些不同。
  1. 路由
  • Hertz 提供了 GETPOSTPUTDELETEANY 等方法用于注册路由。
  • Hertz 提供了路由组( Group )的能力,用于支持路由分组的功能,同时中间件也可以注册到路由组上。通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。
  1. 中间件
  • 中间件简单分为服务端和客户端中间件。
  • Hertz 服务端中间件是 HTTP 请求-响应周期中的一个函数,提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求, 例如记录每个请求或者启用CORS。
middleware
  • 中间件会按定义的先后顺序依次执行,如果想快速终止中间件调用,可以使用以下方法,注意当前中间件仍将执行

    • Abort():终止后续调用
    • AbortWithMsg(msg string, statusCode int):终止后续调用,并设置 response中body,和状态码
    • AbortWithStatus(code int):终止后续调用,并设置状态码
  • 客户端中间件实现和服务端中间件不同。Client 侧无法拿到中间件 index 实现递增,因此 Client 中间件采用提前构建嵌套函数的形式实现。

  • 注意:必须执行 next 方法才能继续调用后续中间件。如果想停止中间件调用,在 next 之前返回就可以了。

  1. 协议
  • TLS

    • Hertz Server & Client 目前只有 标准网络库 支持 TLS,Netpoll 网络库的支持还在路上。 使用参考: Hertz 示例 和 Hertz 配置
  • ALPN

    • 开启 TLS 之后,可以通过开关控制 ALPN 是否开启(依赖当前是否通过 Protocol Suite 注册了所需要的所有协议 Servers)
  • Websocket

    • Hertz 基于hijack的方式实现了对 WebSocket 的支持。

三、实践练习例子:

  • 路由示例代码

package main

import ( "context" "github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/protocol/consts" )

func main(){ h := server.Default(server.WithHostPorts("127.0.0.1:8080"))

h.StaticFS("/", &app.FS{Root: "./", GenerateIndexPages: true})

h.GET("/get", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "get")
})
h.POST("/post", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "post")
})
h.PUT("/put", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "put")
})
h.DELETE("/delete", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "delete")
})
h.PATCH("/patch", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "patch")
})
h.HEAD("/head", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "head")
})
h.OPTIONS("/options", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "options")
})
h.Any("/ping_any", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "any")
})
h.Handle("LOAD","/load", func(ctx context.Context, c *app.RequestContext) {
	c.String(consts.StatusOK, "load")
})
h.Spin()

}

  • 服务端中间件实现代码
// 方式一
func MyMiddleware() app.HandlerFunc {
  return func(ctx context.Context, c *app.RequestContext) {
    // pre-handle
    // ...
    c.Next(ctx)
  }
}

// 方式二
func MyMiddleware() app.HandlerFunc {
  return func(ctx context.Context, c *app.RequestContext) {
    c.Next(ctx) // call the next middleware(handler)
    // post-handle
    // ...
  }
}
  • 客户端中间件实现代码
func MyMiddleware(next client.Endpoint) client.Endpoint {
  return func(ctx context.Context, req *protocol.Request, resp *protocol.Response) (err error) {
    // pre-handle
    // ...
    err = next(ctx, req, resp)
    if err != nil {
      return
    }
    // post-handle
    // ...
  }
}

四、课后个人总结:

  • 本次主要了解了Hertz的使用方法,为后续实践打下基础知识。
  • 后续会继续介绍和记录协议、校验、日志等使用方法,并配合例子实现。