字节赫兹 框架教程 一 Engine

基本特性

Engine

server.Hertz 是 Hertz 的核心类型,它由 route.Engine 以及 signalWaiter 组成,Hertz 服务器的启动、路由注册、中间件注册以及退出等重要方法均包含在 server.Hertz 中。以下是 server.Hertz 的定义:

type Hertz struct {
    *route.Engine 
    // 用于接收信号以实现优雅退出 
    signalWaiter func (err chan error) error
}

配置信息

配置项默认值说明
WithTransportnetwork.NewTransporter更换底层 transport
WithHostPorts:8888指定监听的地址和端口
WithKeepAliveTimeout1mintcp 长连接保活时间,一般情况下不用修改,更应该关注 idleTimeout
WithReadTimeout3min底层读取数据超时时间
WithIdleTimeout3min长连接请求链接空闲超时时间
WithMaxRequestBodySize4 * 1024 * 1024配置最大的请求体大小
WithRedirectTrailingSlashtrue自动根据末尾的 / 转发,例如:如果 router 只有 /foo/,那么 /foo 会重定向到 /foo/ ;如果只有 /foo,那么 /foo/ 会重定向到 /foo
WithRemoveExtraSlashfalseRemoveExtraSlash 当有额外的 / 时也可以当作参数。如:user/:name,如果开启该选项 user//xiaoming 也可匹配上参数
WithUnescapePathValuestrue如果开启,请求路径会被自动转义(eg. ‘%2F’ -> ‘/')。如果 UseRawPath 为 false(默认情况),则 UnescapePathValues 实际上为 true,因为 .URI().Path() 将被使用,它已经是转义后的。设置该参数为 false,需要配合 WithUseRawPath(true)
WithUseRawPathfalse如果开启,会使用原始 path 进行路由匹配
WithHandleMethodNotAllowedfalse如果开启,当当前路径不能被匹配上时,server 会去检查其他方法是否注册了当前路径的路由,如果存在则会响应"Method Not Allowed",并返回状态码 405; 如果没有,则会用 NotFound 的 handler 进行处理
WithDisablePreParseMultipartFormfalse如果开启,则不会预处理 multipart form。可以通过 ctx.Request.Body() 获取到 body 后由用户处理
WithStreamBodyfalse如果开启,则会使用流式处理 body
WithNetwork“tcp”设置网络协议,可选:tcp,udp,unix(unix domain socket),默认为 tcp
WithExitWaitTime5s设置优雅退出时间。Server 会停止建立新的连接,并对关闭后的每一个请求设置 Connection: Close 的 header,当到达设定的时间关闭 Server。当所有连接已经关闭时,Server 可以提前关闭
WithTLSnil配置 server tls 能力,详情可见 TLS
WithListenConfignil设置监听器配置,可用于设置是否允许 reuse port 等
WithALPNfalse是否开启 ALPN
WithTracer[]interface{}{}注入 tracer 实现,如不注入 Tracer 实现,默认关闭
WithTraceLevelLevelDetailed设置 trace level
WithWriteTimeout无限长写入数据超时时间
WithRedirectFixedPathfalse如果开启,当当前请求路径不能匹配上时,server 会尝试修复请求路径并重新进行匹配,如果成功匹配并且为 GET 请求则会返回状态码 301 进行重定向,其他请求方式返回 308 进行重定向
WithBasePath/设置基本路径,前缀和后缀必须为 /
WithMaxKeepBodySize4 * 1024 * 1024设置回收时保留的请求体和响应体的最大大小。单位:字节
WithGetOnlyfalse如果开启则只接受 GET 请求
WithKeepAlivetrue如果开启则使用 HTTP 长连接
WithAltTransportnetwork.NewTransporter设置备用 transport
WithH2Cfalse
WithReadBufferSize4 * 1024设置读缓冲区大小,同时限制 HTTP header 大小
WithRegistryregistry.NoopRegistry, nil设置注册中心配置,服务注册信息
WithAutoReloadRenderfalse, 0设置自动重载渲染配置
WithDisablePrintRoutefalse设置是否禁用 debugPrintRoute
WithOnAcceptnil设置在 netpoll 中当一个连接被接受但不能接收数据时的回调函数,在 go net 中在转换 TLS 连接之前被调用
WithOnConnectnil设置 onConnect 函数。它可以接收来自 netpoll 连接的数据。在 go net 中,它将在转换 TLS 连接后被调用
WithDisableHeaderNamesNormalizingfalse设置是否禁用 Request 和 Response Header 名字的规范化 (首字母和破折号后第一个字母大写)

初始化服务

// Default 用于初始化服务,默认使用了 Recovery 中间件以保证服务在运行时不会因为 panic 导致服务崩溃。
func Default(opts ...config.Option) *Hertz 
// New 用于初始化服务,没有使用默认的 Recovery 中间件。
func New(opts ...config.Option) *Hertz

例子

func main() {
    h := server.New()
    h.Spin()
}

成功效果:
在这里插入图片描述

服务运行与退出

// Spin 函数用于运行 Hertz 服务器,接收到退出信号后可退出服务。
// 在使用 服务注册发现 的功能时,Spin 会在服务启动时将服务注册进入注册中心,并使用 signalWaiter 监测服务异常。
func (h *Hertz) Spin()
// Run 函数用于运行 Hertz 服务器,接收到退出信号后可退出服务。该函数不支持服务的优雅退出,除非有特殊需求,不然一般使用 Spin 函数用于运行服务。
func (engine *Engine) Run() (err error)
// SetCustomSignalWaiter 函数用于自定义服务器接收信号后的处理函数,若没有设置自定义函数,Hertz 使用 waitSignal 函数作为信号处理的默认实现方式,
func (h *Hertz) SetCustomSignalWaiter(f func(err chan error) error)

中间件

func (engine *Engine) Use(middleware ...app.HandlerFunc) IRoutes

Use 函数用于将中间件注册进入路由。

Hertz 支持用户自定义中间件,Hertz 已经实现了一些常用的中间件,详情见 hertz-contrib。

Hertz 支持的中间件的使用方法包括全局注册、路由组级别和单一路由级别的注册。

Use 函数中 middleware 的形参必须为 app.HandlerFunc 的 http 处理函数:

type HandlerFunc func (ctx context.Context, c *app.RequestContext)

函数签名:

func (engine *Engine) Use(middleware ...app.HandlerFunc) IRoutes

示例代码:

func main() {
    h := server.New()
    // 将内置的 Recovery 中间件注册进入路由
    h.Use(recovery.Recovery())
    // 使用自定义的中间件
    h.Use(exampleMiddleware())
    h.Spin()
}

func exampleMiddleware() app.HandlerFunc {
    return func(ctx context.Context, c *app.RequestContext) {
        // 在 Next 中的函数执行之前打印日志
        hlog.Info("print before...")
        // 使用 Next 使得路由匹配的函数执行
        c.Next(ctx)
    }
}

在这里插入图片描述

流式处理

Hertz 支持 Server 的流式处理,包括流式读和流式写。

注意:由于 netpoll 和 go net 触发模式不同,netpoll 流式为 “伪” 流式(由于 LT 触发,会由网络库将数据读取到网络库的 buffer 中),在大包的场景下(如:上传文件等)可能会有内存问题,推荐使用 go net

流式读

代码实例

func main() {
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"), server.WithStreamBody(true), server.WithTransport(standard.NewTransporter))

	h.POST("/bodyStream", handler)

	h.Spin()
}

func handler(ctx context.Context, c *app.RequestContext) {
	// Acquire body streaming
	bodyStream := c.RequestBodyStream()
	// Read half of body bytes
	p := make([]byte, c.Request.Header.ContentLength()/2)
	r, err := bodyStream.Read(p)
	if err != nil {
		panic(err)
	}
	left, _ := ioutil.ReadAll(bodyStream)
	c.String(consts.StatusOK, "bytes streaming_read: %d\nbytes left: %d\n", r, len(left))
}

在这里插入图片描述

底层网络库

func (engine *Engine) GetTransporterName() (tName string)
func SetTransporter(transporter func (options *config.Options) network.Transporter)
GetTransporterName

获取当前使用的网络库名称,现在有原生的 go net 和 netpoll 两种。

linux 默认使用 netpoll, windows 只能使用 go net。

如果对如何使用对应的网络库有疑惑,请查看 此处。

函数签名:

func (engine *Engine) GetTransporterName() (tName string)

示例代码:

h := server.New()
tName := h.GetTransporterName()
SetTransporter

SetTransporter 用于设置网络库。

注意:SetTransporter 只设置 Engine 的全局默认值,所以在初始化 Engine 时使用 WithTransporter 来设置网络库会覆盖掉 SetTransporter 的设置。

函数签名:

func SetTransporter(transporter func (options *config.Options) network.Transporter)

示例代码:

route.SetTransporter(standard.NewTransporter)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过去日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值