开源 Golang 微服务入门一: HTTP 框架 Hertz

这篇具有很好参考价值的文章主要介绍了开源 Golang 微服务入门一: HTTP 框架 Hertz。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

从本篇笔记开始将介绍 Go 框架三件套(Web / RPC / ORM),框架的学习有助于后续课程的学习以及大项目的完成。本文主要介绍字节跳动的开源 Golang 微服务 HTTP 框架 Hertz。先了解一下三件套的相关基本知识,做一下铺垫:

Gorm

gorm是Golang语言中一个已经迭代数十年且功能强大、性能极好的ORM框架

ORM:Object Relational Mapping(对象关系映射),其主要作用是在编程中,把面向对象的概念跟数据库中表的概念对应起来,

简单来说,在golang中,自定义的一个结构体对应着一张表,结构体的实例则对应着表中的一条记录。

Kitex

Kitex是字节内部Golang微服务RPC框架 具有高性能、强可扩展的主要特点 支持多协议并且拥有丰富的开源扩展

Hertz

Hertz是字节内部的Http框架 参考了其他开源框架的优势 结合字节跳动内部的需求 具有高可用、高性能、高扩展性的特点

知识点介绍

Hertz 简介

Hertz 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttp、gin、echo 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。 如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。

架构设计:Hertz采用了4层分层设计(应用层、路由层、协议层、传输层),保证各个层级功能内聚,同时通过层级之间的接口达到灵活扩展的目标。

开源 Golang 微服务入门一: HTTP 框架 Hertz

框架特点:

  • 高易用性:在开发过程中,快速写出来正确的代码往往是更重要的。因此,在 Hertz 在迭代过程中,积极听取用户意见,持续打磨框架,希望为用户提供一个更好的使用体验,帮助用户更快的写出正确的代码。

  • 高性能:Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景相较于 go net,Hertz 在 QPS、时延上均具有一定优势。

  • 高扩展性:Hertz 采用了分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。同时得益于框架的分层设计,框架的扩展性也会大很多。

  • 多协议支持:Hertz 框架原生提供 HTTP1.1、ALPN 协议支持。除此之外,由于分层设计,Hertz 甚至支持自定义构建协议解析逻辑,以满足协议层扩展的任意需求。

  • 网络层切换能力:Hertz 实现了 Netpoll 和 Golang 原生网络库 间按需切换能力,用户可以针对不同的场景选择合适的网络库,同时也支持以插件的方式为 Hertz 扩展网络库实现。

功能特性

中间件

Hertz 除了提供 Server 的中间件能力,还提供了 Client 中间件能力。用户可以使用中间件能力将通用逻辑(如:日志记录、性能统计、异常处理、鉴权逻辑等等)和业务逻辑区分开,让用户更加专注于业务代码。Server 和 Client 中间件使用方式相同,使用 Use 方法注册中间件,中间件执行顺序和注册顺序相同,同时支持预处理和后处理逻辑。

Server 和 Client 的中间件实现方式并不相同。对于 Server 来说,我们希望减少栈的深度,同时也希望中间件能够默认的执行下一个,用户需要手动终止中间件的执行。因此,我们将 Server 的中间件分成了两种类型,即不在同一个函数调用栈(该中间件调用完后返回,由上一个中间件调用下一个中间件,如图 2 中 B 和 C)和在同一个函数调用栈的中间件(该中间件调用完后由该中间件继续调用下一个中间件,如图 2 中 C 和 Business Handler)。

开源 Golang 微服务入门一: HTTP 框架 Hertz

其核心是需要一个地方存下当前的调用位置 index,并始终保持其递增。恰好 RequestContext 就是一个存储 index 合适的位置。但是对于 Client,由于没有合适的地方存储 index,我们只能退而求其次,抛弃 index 的实现,将所有的中间件构造在同一调用链上,需要用户手动调用下一个中间件。

流式处理

Hertz 提供 Server 和 Client 的流式处理能力。HTTP 的文件场景是十分常见的场景,除了 Server 侧的上传场景之外,Client 的下载场景也十分常见。为此,Hertz 支持了 Server 和 Client 的流式处理。在内部网关场景中,从 Gin 迁移到 Hertz 后,CPU 使用量随流量大小不同可节省 30%—60% 不等,服务压力越大,收益越大。Hertz 开启流式功能的方式也很容易,只需要在 Server 上或 Client 上添加一个配置即可,可参考 CloudWeGo 官网 Hertz 文档的流式处理部分。

由于 Netpoll 采用 LT 的触发模式,由网络库主动将将数据从 TCP 缓冲区读到用户态,并存储到 buffer 中,否则 epoll 事件会持续触发。因此 Server 在超大请求的场景下,由于 Netpoll 持续将数据读到用户态内存中,可能会有 OOM 的风险。HTTP 文件上传场景就是一个典型的场景,但 HTTP 上传服务又是很常见的场景,因此我们支持标准网络库 go net,并针对 Hertz 做了特殊优化,暴露出 Read() 接口,防止 OOM 发生。

对于 Client,情况并不相同。流式场景下会将连接封装成 Reader 暴露给用户,而Client 有连接池管理,那这样连接就多了一种状态,何时关连接,何时复用连接成了一个问题。由于框架侧并不知道该连接何时会用完,框架侧复用该连接不现实,会导致串包问题。由于 GC 会关闭连接,因此我们起初设想流式场景下的连接交由用户后,由 GC 负责关闭,这样也不会导致资源泄漏。但是在测试后发现,由于 GC 存在一定时间间隔,另外 TCP 中主动关闭连接的一方需要等待 2RTT,在高并发场景下会导致 fd 被打满的情况。最终我们提供了复用连接的接口,对于性能有场要求用户,在使用完连接后可以将连接重新放入连接池中复用。

性能指标

Hertz 使用字节跳动自研高性能网络库 Netpoll,在提高网络库效率方面有诸多实践,参考已发布文章字节跳动在 Go 网络库上的实践。除此之外,Netpoll 还针对 HTTP 场景进行优化,通过减少拷贝和系统调用次数提高吞吐以及降低时延。为了衡量 Hertz 性能指标,我们选取了社区中有代表性的框架 Gin(net/http)和 Fasthttp 作为对比,如图3所示。可以看到,Hertz 的极限吞吐、TP99 等指标均处于业界领先水平。未来,Hertz 还将继续和 Netpoll 深度配合,探索 HTTP 框架性能的极限。

开源 Golang 微服务入门一: HTTP 框架 Hertz

快速开始

准备 Golang 开发环境

首先需要安装 Golang,推荐安装最新版本。可参考

2023 最新萌新学习 Golang 环境配置详细步骤,附带图文

目前,Hertz 支持 Linux、macOS、Windows 系统。

快速上手
  1. 安装命令行工具 hz

    确保环境变量已经正确定义,如下:

    go install github.com/cloudwego/hertz/cmd/hz\@latest
    
  2. 生成/编写示例代码

    • 在当前目录下创建 hertz_demo 文件夹,进入该目录中

    • 创建 main.go 文件

    • 在 main.go 文件中添加以下代码

    package main
    
    import (
    "context""github.com/cloudwego/hertz/pkg/app""github.com/cloudwego/hertz/pkg/app/server""github.com/cloudwego/hertz/pkg/common/utils""github.com/cloudwego/hertz/pkg/protocol/consts"
    )
    
    funcmain() {
    h := server.Default()
    
        h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
                ctx.JSON(consts.StatusOK, utils.H{"message": "pong"})
        })
    
        h.Spin()
    
    }
    
    • 生成 go.mod 文件
    go mod init hertz\_demo
    
    • 整理 & 拉取依赖
    go mod tidy
    
    • 打包并运行示例代码
    go build -o hertz\_demo
    go run hertz\_demo
    
    
    • 如果成功,将看到
    2023/01/30 11:26:27.824241 engine.go:617: \[Debug] HERTZ: Method=GET    absolutePath=/ping                     --> handlerName=main.main.func1 (num=2 handlers)
    2023/01/30 11:26:27.836518 engine.go:389: \[Info] HERTZ: Using network library=standard
    2023/01/30 11:26:27.837518 transport.go:65: \[Info] HERTZ: HERTZ: HTTP server listening on address=\[::]:8888
    
    • 对接口进行测试:
    curl <http://127.0.0.1:8888/ping>
    

    如果成功就可以看到以下输出:

    StatusCode        : 200
    StatusDescription : OK
    Content           : {"message":"pong"}
    RawContent        : HTTP/1.1 200 OK
    Content-Length: 18
    Content-Type: application/json; charset=utf-8
    Date: Mon, 30 Jan 2023 03:26:53 GMT
    Server: hertz
    
                        {"message":"pong"}
    
    Forms             : {}
    Headers           : {\[Content-Length, 18], \[Content-Type, application/json; charset=utf-8], \[Date, Mon, 30 Jan 2023 03:26:53 GMT], \[Server,\
    hertz]}
    Images            : {}
    InputFields       : {}
    Links             : {}
    ParsedHtml        : mshtml.HTMLDocumentClass
    RawContentLength  : 18
    

    到此就已经成功启动了 Hertz Server,并完成了一次调用。

路由

路由注册

Hertz 提供了 GET、POST、PUT、DELETE、ANY 等方法用于注册路由。

方法 介绍
Hertz.GET 用于注册 HTTP Method 为 GET 的方法
Hertz.POST 用于注册 HTTP Method 为 POST 的方法
Hertz.DELETE 用于注册 HTTP Method 为 DELETE 的方法
Hertz.PUT 用于注册 HTTP Method 为 PUT 的方法
Hertz.PATCH 用于注册 HTTP Method 为 PATCH 的方法
Hertz.HEAD 用于注册 HTTP Method 为 HEAD 的方法
Hertz.OPTIONS 用于注册 HTTP Method 为 OPTIONS 的方法
Hertz.Handle 这个方法支持用户手动传入 HTTP Method 用来注册方法,当用于注册普通的 HTTP Method 方法时和上述的方法作用是一致的,并且这个方法同时也支持用于注册自定义 HTTP Method 方法
Hertz.Any 用于注册所有 HTTP Method 方法
Hertz.StaticFile/Static/StaticFS 用于注册静态文件

示例代码:

package main

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

funcmain(){
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()

}

路由组

Hertz 提供了路由组( Group )的能力,用于支持路由分组的功能,同时中间件也可以注册到路由组上。

示例代码:

package main

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

funcmain(){
h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
v1 := h.Group("/v1")
v1.GET("/get", func(ctx context.Context, c \*app.RequestContext) {
c.String(consts.StatusOK, "get")
})
v1.POST("/post", func(ctx context.Context, c \*app.RequestContext) {
c.String(consts.StatusOK, "post")
})
v2 := h.Group("/v2")
v2.PUT("/put", func(ctx context.Context, c \*app.RequestContext) {
c.String(consts.StatusOK, "put")
})
v2.DELETE("/delete", func(ctx context.Context, c \*app.RequestContext) {
c.String(consts.StatusOK, "delete")
})
h.Spin()
}

路由类型

Hertz 支持丰富的路由类型用于实现复杂的功能,包括静态路由、参数路由、通配路由。

路由的优先级:静态路由 > 命名路由 > 通配路由

  • 静态路由如上文

  • 参数路由:

    • Hertz 支持使用 :name 这样的命名参数设置路由,并且命名参数只匹配单个路径段。

    • 如果我们设置/user/:name路由,匹配情况如下

      路径 是否匹配
      /user/gordon 匹配
      /user/you 匹配
      /user/gordon/profile 不匹配
      /user/ 不匹配
    • 通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。
    package main
    
    import (
    "context"
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/cloudwego/hertz/pkg/protocol/consts"
    )
    
    funcmain(){
    h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
    // This handler will match: "/hertz/version", but will not match : "/hertz/" or "/hertz"
    h.GET("/hertz/:version", func(ctx context.Context, c \*app.RequestContext) {
    version := c.Param("version")
    c.String(consts.StatusOK, "Hello %s", version)
    })
    h.Spin()
    }
    
通配路由
  • Hertz 支持使用 *path 这样的通配参数设置路由,并且通配参数会匹配所有内容。

  • 如果我们设置/src/*path路由,匹配情况如下

路径 是否匹配
/src/ 匹配
/src/somefile.go 匹配
/src/subdir/somefile.go 匹配
  • 通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。

    package main
    
    import (
    "context"
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/cloudwego/hertz/pkg/protocol/consts"
    )
    
    funcmain(){
    h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
    // However, this one will match "/hertz/v1/" and "/hertz/v2/send"
    h.GET("/hertz/:version/\*action", func(ctx context.Context, c \*app.RequestContext) {
    version := c.Param("version")
    action := c.Param("action")
    message := version + " is " + action
    c.String(consts.StatusOK, message)
    })
    h.Spin()
    }
    

参数绑定

代码绑定是Hertz超级赞的一部分,可以非常优雅的完成请求参数映射到结构体与请求参数的验证

此处参数绑定使用了 github.com/bytedance/g…

上面分别介绍了http中常见的参数获取api,hertz出了提供api获取参数信息,还提供了参数绑定功能,帮助我们直接将请求参数绑定到结构体上并校验参数的合法性。

func PersonBind(ctx context.Context, c \*app.RequestContext) {
type person struct {
Age  int    `path:"age" json:"age"`    // 从路径中获取参数
Name string `query:"name" json:"name"` // 从query中获取参数
City string `json:"city"`              // 从body中获取参数
}
var p person
if err := c.BindAndValidate(\&p); err != nil {
panic(err)
}
c.JSON(200, utils.H{
"person": p,
})
}

curl:

curl --location --request POST '<http://localhost:8888/person_bind/12?name=erik>' \
\--header 'Content-Type: application/json' \
\--data-raw '{
"city":"BeiJing"
}'

返回结果:

{
    "person": {
    "age": 12,
    "name": "erik",
    "city": "BeiJing"
    }
}

中间件

中间件首尾相连最终形成一个过滤器链,用户可以在中间件中设定一些通用的处理规则,比如:统一错误处理,用户信息验证,跨域处理等 Hertz提供了两个通用的中间件,一个是JWT验证,一个是Cors跨域中间件,开箱即用,详情可以参考:www.cloudwego.io/zh/docs/her…

使用跨域中间件示例
func main() {
h := server.Default()
// CORS for <https://foo.com> and <https://github.com> origins, allowing:
// - PUT and PATCH methods
// - Origin header
// - Credentials share
// - Preflight requests cached for 12 hours
h.Use(cors.New(cors.Config{
AllowOrigins:     \[]string{"<https://foo.com"}>,
AllowMethods:     \[]string{"PUT", "PATCH"},
AllowHeaders:     \[]string{"Origin"},
ExposeHeaders:    \[]string{"Content-Length"},
AllowCredentials: true,
AllowOriginFunc: func(origin string) bool {
return origin == "<https://github.com>"
},
MaxAge: 12 \* time.Hour,
}))
h.Spin()
}

错误处理

我们可以借助Hertz提供的中间件的能力,统一对错误进行处理。即在最外层的中间件捕获错误,然后根据错误类型做对应的处理。 这里需要借助三方库errors来获取go的错误堆栈,方便我们排查问题

  • 引入errors
go get github.com/pkg/errors

hertz的app.RequestContext提供了c.Error(err)方法用于保存业务中产生的错误,c.Errors()获取业务中产生的错误。所以如果程序运行时产生错误,我们可以将错误保存到app.RequestContext中,并在中间件中获取这个错误,判断错误的类型进行对应的处理。
统一异常处理中间件代码如下:

package middleware

import (
"context"
"errors"
"fmt"

    "github.com/bytedance/gopkg/util/logger"
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/common/utils"

)

func GlobalErrorHandler(ctx context.Context, c \*app.RequestContext) {
c.Next(ctx)

    if len(c.Errors) == 0 {
    	// 没有收集到异常直接返回
    	fmt.Println("retun")
    	return
    }
    hertzErr := c.Errors[0]
    // 获取errors包装的err
    err := hertzErr.Unwrap()
    // 打印异常堆栈
    logger.CtxErrorf(ctx, "%+v", err)
    // 获取原始err
    err = errors.Unwrap(err)
    // todo 进行错误类型判断
    c.JSON(400, utils.H{
    	"code":    400,
    	"message": err.Error(),
    })

}

配置中间件

package main

import (
"hertz\_demo/biz/middleware"

    "github.com/cloudwego/hertz/pkg/app/server"

)

func main() {
h := server.Default()
h.Use(middleware.GlobalErrorHandler)
register(h)
h.Spin()
}

业务代码中将错误存放到app.RequestContext中直接退出

err = c.BindAndValidate(&req)
if err != nil {
    fmt.Printf("%v", err.Error())
    _ = c.Error(errors.WithStack(err))
    return
}

参数校验异常时,异常堆栈信息如下:

validating: expr\_path=Name, cause=invalid
2022/07/25 23:41:47.977087 logger.go:190: \[Error] \[validating: expr\_path=Name, cause=invalid
hertz\_demo/biz/handler/person.PersonInfo
/Users/xxx/gopath/src/hertz\_demo/biz/handler/person/person\_service.go:23
github.com/cloudwego/hertz/pkg/app.(\*RequestContext).Next
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/app/context.go:611
hertz\_demo/biz/middleware.GlobalErrorHandler
/Users/xxx/gopath/src/hertz\_demo/biz/middleware/global\_error\_handler.go:14
github.com/cloudwego/hertz/pkg/app.(\*RequestContext).Next
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/app/context.go:611
github.com/cloudwego/hertz/pkg/app/middlewares/server/recovery.Recovery.func1
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/app/middlewares/server/recovery/recovery.go:51
github.com/cloudwego/hertz/pkg/app.(\*RequestContext).Next
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/app/context.go:611
github.com/cloudwego/hertz/pkg/route.(\*Engine).ServeHTTP
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/route/engine.go:607
github.com/cloudwego/hertz/pkg/protocol/http1.Server.Serve
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/protocol/http1/server.go:244
github.com/cloudwego/hertz/pkg/route.(\*Engine).Serve
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/route/engine.go:456
github.com/cloudwego/hertz/pkg/route.(\*Engine).onData
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/route/engine.go:353
github.com/cloudwego/hertz/pkg/network/netpoll.(\*transporter).ListenAndServe.func2
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/hertz\@v0.2.0/pkg/network/netpoll/transport.go:83
github.com/cloudwego/netpoll.(\*connection).onRequest.func2
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/netpoll\@v0.2.4/connection\_onevent.go:153
github.com/cloudwego/netpoll.(\*connection).onProcess.func1
/Users/xxx/gopath/pkg/mod/github.com/cloudwego/netpoll\@v0.2.4/connection\_onevent.go:176
github.com/bytedance/gopkg/util/gopool.(\*worker).run.func1.1
/Users/xxx/gopath/pkg/mod/github.com/bytedance/gopkg\@v0.0.0-20220623074550-9d6d3df70991/util/gopool/worker.go:69
github.com/bytedance/gopkg/util/gopool.(\*worker).run.func1
/Users/xxx/gopath/pkg/mod/github.com/bytedance/gopkg\@v0.0.0-20220623074550-9d6d3df70991/util/gopool/worker.go:70
runtime.goexit
/usr/local/go/src/runtime/asm\_amd64.s:1571]

响应结果:

{
    "code": 400,
    "message": "validating: expr\_path=Name, cause=invalid"
}

Hertz 代码生成工具 hz

与 Hertz 一并开源的还有一个易用的命令行工具 Hz,用户只需提供一个 IDL,根据定义好的接口信息,Hz 便可以一键生成项目脚手架,让 Hertz 达到开箱即用的状态;Hz 也支持基于 IDL 的更新能力,能够基于 IDL 变动智能地更新项目代码。目前 Hz 支持了 Thrift 和 Protobuf 两种 IDL 定义。命令行工具内置丰富的选项,可以根据自己的需求使用。同时它底层依赖 Protobuf 官方的编译器和自研的 Thriftgo 的编译器,两者都支持自定义的生成代码插件。如果默认模板不能够满足需求,完全能够按需定义。

基本使用:

  • 创建一个 Hertz 新项目
// GOPATH 下执行,go mod 名字默认为当前路径相对GOPATH的路径,也可自己指定
hz new

// 非GOPATH 下执行,需要指定 go mod 名
hz new -mod hertz/demo

// 整理 & 拉取依赖
go mod tidy

  • 编译项目
go build
  • 运行项目
./{{your binary}}
  • 测试
curl 127.0.0.1:8888/ping

如果返回{“message”:“pong”},说明接口调通。

总结

本文主要介绍了 Golang 微服务 HTTP 框架 Hertz,只是简单的入门练习,如果想了解更多内容还是需要仔细研究官方文档,官方文档的内容很清晰全面,后续还需要深入学习。文章来源地址https://www.toymoban.com/news/detail-478552.html

引用

  • Hertz 官方文档 Hertz | CloudWeGo
  • 项目地址

到了这里,关于开源 Golang 微服务入门一: HTTP 框架 Hertz的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于 Hertz 和 Kitex 的 Go 微服务项目 | 开源项目推荐

    FreeCar 是一个基于 Hertz 与 Kitex 的全栈微服务项目,欢迎 Star。 项目地址:CyanAsterisk/FreeCar Hertz 是一个超大规模的企业级微服务 HTTP 框架,具有高易用性、易扩展、低时延等特点。 Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景中,相较于 go net,Hertz 在 QPS、时延上

    2024年02月07日
    浏览(34)
  • Golang Gin框架HTTP上传文件

    HTTP上传的文件的原理 HTTP协议的文件上传是通过HTTP POST请求实现的,使用multipart/form-data格式将待上传的文件放入请求体中。 服务器根据请求头中的boundary参数来解析请求体,并根据Content-Disposition字段获取文件名等信息,根据Content-Type字段判断文件类型并保存到相应位置。

    2024年02月05日
    浏览(41)
  • golang 通用的 grpc http 基础开发框架

    golang 通用的 grpc http 基础开发框架 仓库地址: https://github.com/webws/go-moda 仓库一直在更新,欢迎大家吐槽和指点 transport: 集成 http(echo、gin)和 grpc。 tracing: openTelemetry 实现微务链路追踪 pprof: 分析性能 config: 通用的配置文件读取模块,支持 toml、yaml 和 json 格式。 logger: 日志系统

    2024年02月10日
    浏览(39)
  • 【开源框架】Golang DAG 任务调度框架 Goflow 全解析——源代码模型、使用示例等

    Simply way to control goroutines execution order based on dependencies.

    2024年02月06日
    浏览(56)
  • Golang中基于HTTP协议的网络服务

    HTTP协议是基于TCP/IP协议栈的,并且它也是一个面向普通文本的协议。 只要搞清楚了HTTP请求的报文(报文的头部(header)和主体(body))应该包含的内容,使用任何一个文本编译器,就饿可以编写一个完整的HTTP请求报文。 在这种情况下,直接使用 net.Dial 函数,就可以。 使

    2023年04月09日
    浏览(33)
  • golang微服务框架特性分析及选型

    (以下框架均为go框架) 包括:Istio、go-zero、go-kit、go-kratos、go-micro、rpcx、kitex、goa、jupiter、dubbo-go、tarsgo   1、特性及使用场景 start统计截止至2024.04.01 序号 名称 特性 适用场景 stars 1 Istio Istio 是一个开源的服务网格(Service Mesh)解决方案,提供了流量管理、安全策略、监控

    2024年04月17日
    浏览(32)
  • golang http服务实现多ip监听,及优雅重启

    在工作中,有时需要对http服务实现多监听,http服务重启等需求。大多数web框架只实现的是单ip监听,要实现多ip监听就需要循环监听ip; 而重启http服务,首先想到的是用endless来优雅的实现服务的重启,但是当多ip监听时,一个项目不能用一个endLess,多了会报错,且windows环境也

    2023年04月12日
    浏览(39)
  • Iris微服务框架_golang web框架_完整示例Demo

    Iris简介 Iris是一款Go语言中用来开发web应用的框架,该框架支持编写一次并在任何地方以最小的机器功率运行,如Android、ios、Linux和Windows等。该框架只需要一个可执行的服务就可以在平台上运行了。 Iris框架以简单而强大的api而被开发者所熟悉。iris除了为开发者提供非常简单

    2024年01月19日
    浏览(39)
  • 三分钟用Golang搭建一个HTTP文件上传下载服务器

    简单需要一个文件服务器来传递数据,只要两个功能,一个上传接口,一个下载接口。 选用go http模块实现,比nginx、ftp等更方便快捷。 上传接口\\\"/v1/file_upload/\\\" 上传接口增加简单BasicAuth鉴权 上传成功返回下载URL json格式返回 只想文件上传服务器测试接口,以下电梯直达即可

    2024年02月11日
    浏览(70)
  • Golang 通过开源库 go-redis 操作 NoSQL 缓存服务器

    前置条件: 1、导入库: import ( \\\"github.com/go-redis/redis/v8\\\" ) 2、搭建哨兵模式集群 具体可以百度、谷歌搜索,网上现成配置教程太多了,不行还可以搜教程视频,跟着视频博主一步一个慢动作,慢慢整。 本文只介绍通过 “主从架构 / 哨兵模式” 访问的形式,这是因为,单个

    2024年01月23日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包