常用的框架 | 青训营笔记

180 阅读4分钟

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

前言

今天的课程主要讲了在后端开发时常用的三大框架--gorm、hertz、kitex

Gorm

Gorm是一种在开发Go语言应用时常用的数据库框架,它支持sqlite、mysql等多种数据库并提供了驱动支持,也支持用户自行开发连接驱动。此外,他还有以下特点:

  • 支持全功能
  • 多种关系(一对一、一对多、多对多等)
  • 钩子方法与链式表达式
  • 事务、索引、锁
  • 自动迁移、自定日志记录
  • 可扩展

安装

go get -u gorm.io/gorm  
go get -u gorm.io/driver/sqlite # 安装sqlite驱动

简易使用

请参考GORM 指南

hertz

Hertz是一个 Golang 微服务 HTTP 框架,它具有以下特点

  • 高易用性
  • 高性能
  • 高扩展性
  • 多协议支持
  • 网络层切换

目前,这个框架已经在字节内部广泛的使用。

安装

安装可以参考快速开始

使用

在使用时,与目前常用的gin框架类似,可以无缝切换。下面是一个简单的例子。

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"
)

func main() {
    h := server.Default()

    h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
            ctx.JSON(consts.StatusOK, utils.H{"message": "pong"})
    })

    h.Spin()
}

除了上述功能,它也提供了路由管理、参数绑定与校验、中间件、客户端和代码生成工具等功能,方便用户的使用。此外,由于Hertz原生支持微服务,因此在开发微服务方面的应用时能够简化开发环节。下面是一个使用consul作为注册中心,使用hertz框架的微服务项目。可以看到,从使用上相较gin + go-micro上来说比较方便,性能上也更好。

package main

import (
	"context"
	"log"
	"sync"

	"github.com/cloudwego/hertz/pkg/app/server/registry"
	consulapi "github.com/hashicorp/consul/api"

	"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"
	"github.com/hertz-contrib/registry/consul"
)

var wg sync.WaitGroup

func main() {
	config := consulapi.DefaultConfig()
	config.Address = "127.0.0.1:8500"
	consulClient, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal(err)
		return
	}

	wg.Add(2)
	go func() {
		defer wg.Done()
		addr := "127.0.0.1:8888"
		r := consul.NewConsulRegister(consulClient)
		h := server.Default(
			server.WithHostPorts(addr),
			server.WithRegistry(r, &registry.Info{
				ServiceName: "hertz.test.demo",
				Addr:        utils.NewNetAddr("tcp", addr),
				Weight:      10,
				Tags:        nil,
			}),
		)

		h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
			ctx.JSON(consts.StatusOK, utils.H{"ping": "pong1"})
		})
		h.Spin()
	}()
	go func() {
		defer wg.Done()
		addr := "127.0.0.1:8889"
		r := consul.NewConsulRegister(consulClient)
		h := server.Default(
			server.WithHostPorts(addr),
			server.WithRegistry(r, &registry.Info{
				ServiceName: "hertz.test.demo",
				Addr:        utils.NewNetAddr("tcp", addr),
				Weight:      10,
				Tags:        nil,
			}),
		)

		h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
			ctx.JSON(consts.StatusOK, utils.H{"ping": "pong2"})
		})
		h.Spin()
	}()

	wg.Wait()
}

kietx

Kitex[kaɪt’eks] 字节跳动内部的 Golang 微服务 RPC 框架,具有高性能强可扩展的特点,在字节内部已广泛使用。如果对微服务性能有要求,又希望定制扩展融入自己的治理体系,Kitex 会是一个不错的选择。

RPC简介

RPC(Remote Procedure Call)远程过程调用协议,一种通过网络从远程计算机上请求服务,而不需要了解底层网络技术的协议。RPC它假定某些协议的存在,例如TPC/UDP等,为通信程序之间携带信息数据。在OSI网络七层模型中,RPC跨越了传输层和应用层,RPC使得开发,包括网络分布式多程序在内的应用程序更加容易。

快速开始

注意:Kitex 目前对 Windows 的支持并不完善,建议使用虚拟机或 WSL2 进行测试。

编写服务端

安装所需工具

- ``go install github.com/cloudwego/kitex/tool/cmd/kitex@latest``
- ``go install github.com/cloudwego/thriftgo@latest``

编写IDL

接口描述语言(Interface definition language,IDL) 是一种语言的通用术语,它允许用一种语言编写的程序或对象与用未知语言编写的另一个程序进行通信。 我们可以使用 IDL 来支持 RPC 的信息传输定义。Kitex 默认支持 thriftproto3 两种 IDL,而在底层传输上,Kitex 使用扩展的 thrift 作为底层的传输协议。下面是一个proto示例

package api.server

service Echo {
    rpc Echo(Req) returns (Res) {}
}

message Req {
    string message = 1;
}
message Res {
    string message = 1;
}

生成服务端代码

kitex -module exmaple -service example echo.proto

上述命令中,-module 表示生成的该项目的 go module 名,-service 表明我们要生成一个服务端项目,后面紧跟的 example 为该服务的名字。最后一个参数则为该服务的 IDL 文件。生成后的项目结构如下:

.
|-- build.sh
|-- echo.thrift
|-- handler.go
|-- kitex_gen
|   `-- api
|       |-- echo
|       |   |-- client.go
|       |   |-- echo.go
|       |   |-- invoker.go
|       |   `-- server.go
|       |-- echo.go
|       `-- k-echo.go
|-- main.go
`-- script
    |-- bootstrap.sh
    `-- settings.py

实现服务逻辑

在handler.go文件中,我们需要实现Echo的具体逻辑。

func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
  return &api.Response{Message: req.Message}, nil
}

编译并运行

运行 sh build.sh 以进行编译,编译结果会被生成至 output 目录。运行 sh output/bootstrap.sh 以启动服务。

实战

本节课的实战内容是使用上课介绍的三个框架实现一个笔记项目。

服务名称服务介绍
gateway网关层
accont账户逻辑层
note笔记逻辑层
database数据库管理

模块

  • gateway -- 实现对应的接口,并对数据进行校验
    • 登录
    • 注册
    • 笔记的增删改查
  • account -- 实现用户账户的具体处理逻辑
    • 创建用户
    • 校验用户
    • 修改用户
    • 查询用户
  • note -- 实现笔记的具体处理逻辑
    • 笔记的增删改查
  • database -- 统一数据管理与封装
    • 数据库的集中管理

参考