2024-09-14 15:58:09 +08:00
2024-09-14 15:58:09 +08:00

fastApi

fastApi: 基于Gin框架构建的web服务开发手脚架统一规范开发快速开发Api接口

https://github.com/kwinH/fastApi

目的

本项目采用了一系列Golang中比较流行的组件可以以本项目为基础快速搭建Restful Web API

特色

本项目已经整合了许多开发API所必要的组件

  1. cobra: cobra既是一个用于创建强大现代CLI应用程序的库也是一个生成应用程序和命令文件的程序
  2. Gin: 轻量级Web框架Go世界里最流行的Web框架
  3. Gin-Cors: Gin框架提供的跨域中间件
  4. GORM: ORM工具。本项目需要配合Mysql使用
  5. Go-Redis: Golang Redis客户端
  6. viper: Viper是适用于Go应用程序的完整配置解决方案
  7. JWT: 使用jwt-go这个库来实现我们生成JWT和解析JWT的功能
  8. Zap: Zap日志库,配置traceId,可进行链路追踪
  9. swag: 使用swag快速生成RESTFul API文档
  10. cron: cron是golang中广泛使用的一个定时任务库
  11. go-nsq: nsq 是一款基于 go 语言开发实现的分布式消息队列组件
  12. endless 用于创建和管理 HTTP 服务器的 Go 包,特别是提供了优雅的停机、热重启支持功能
  13. OpenTelemetry 实现分布式追踪和指标收集的功能
  14. asynq 基于 Redis 实现异步任务队列

本项目已经预先实现了一些常用的代码方便参考和复用:

  1. 创建了用户模型
  2. 实现了/api/v1/user/register用户注册接口
  3. 实现了/api/v1/user/login用户登录接口
  4. 实现了/api/v1/user/me用户资料接口(需要登录后获取token)

本项目已经预先创建了一系列文件夹划分出下列模块:

.
├── Dockerfile
├── LICENSE.md
├── Makefile
├── README.md
├── app
│   ├── http
│   │   ├── controller  MVC框架的controller负责协调各部件完成任务
│   │   ├── middleware  中间件
│   │   ├── request     请求参数结构体
│   │   ├── response    响应结构体
│   │   └── service     业务逻辑处理
│   └── model                 数据库模型
│       └── user.go
├── bin
├── cmd                             命令行
│   ├── main.go
│   ├── migrate.go
│   ├── server
│   │   ├── cron.go
│   │   ├── gin.go
│   │   └── mq.go
│   └── version.go
├── common                          公共的
│   └── services              公共的服务
├── config.yaml                     配置文件
├── core                            一些核心组件初始化
│   ├── global
│   │   └── core.go
│   ├── gorm.go
│   ├── init.go
│   ├── logger
│   │   ├── gorm_logger.go
│   │   └── zap.go
│   ├── middleware
│   │   └── zap.go
│   ├── nsq_producer.go
│   ├── redis.go
│   ├── trans.go
│   └── viper.go
├── crontab                         定时任务
│   ├── cron_init.go
│   ├── schedule.go
│   └── testJob.go
├── docker                          docker相关
│   └── nsq
│       └── docker-compose.yaml
├── docs                            swagger生成的文档
│   ├── docs.go
│   ├── swagger.json
│   └── swagger.yaml
├── go.mod
├── go.sum
├── log.log
├── main.go
├── mq                              消息队列
│   ├── mq_base.go
│   └── send_registered_email.go
├── router
│   ├── api.go
│   ├── router.go
│   ├── swagger.go
│   └── warp.go
├── start.sh
└── util                            工具类
    ├── common.go
    ├── gin.go
    └── ip.go

config.yaml

项目在启动的时候依赖config.yaml配置文件

Go Mod

本项目使用Go Mod管理依赖。

go mod init go-crud
export GOPROXY=http://mirrors.aliyun.com/goproxy/
bin/fast-api-linux // 自动安装

编译

#编译成linux系统可执行文件, bin/fast-api-mac
make linux

#编译成mac系统可执行文件, bin/fast-api-linux
make mac

#编译成windows系统可执行文件, bin/fast-api-win
make win

#会自动编译成当前系统可执行文件
make

运行HTTP

启动

项目运行后启动在3000端口可以修改参考gin文档)

bin/fast-api-linux server -c config.yaml

优雅关闭

bin/fast-api-linux server stop

平滑重启

bin/fast-api-linux server restart

定时任务

bin/fast-api-linux cron -c config.yaml

nsq消息队列

先启动nsq服务

cd docker/nsq
docker-compose up -d

开启config.yaml配置中的nsq选项

...
nsq:
  producer: 127.0.0.1:4150
  consumer: 127.0.0.1:4161

生产者

所有的生产者代码都放在mq目录下,并且都继承BaseMQBaseMQ中封装了Producer方法,只需要实现HandleMessage方法即可

package mq

import (
	"context"
	"fastApi/app/model"
	"fastApi/core/logger"
	"github.com/nsqio/go-nsq"
)

type SendRegisteredEmail struct {
	BaseMQ
}

func (c *SendRegisteredEmail) HandleMessage(msg *nsq.Message) error {
	return c.Handle(msg, func(ctx context.Context, data string) error {
		logger.Log(ctx).Info("ok")
		return nil
	})
}

func init() {
	MQList = append(MQList, NewSendRegisteredEmail())
}

func NewSendRegisteredEmail() *SendRegisteredEmail {
	return &SendRegisteredEmail{
		BaseMQ: BaseMQ{
			Topic: "sendRegisteredEmail",
		}}
}

触发生产者

err := mq.NewSendRegisteredEmail().Producer(ctx, []byte("test"), 1*time.Second)
fmt.Printf("err%v", err)

运行消费者

bin/fast-api-linux nq -c config.yaml

asysq消息队列基于redis实现

开启config.yaml配置中的asysq选项

...
asynq:
  addr: 127.0.0.1:6379
  password: "Q#W*9hETg*fp0)@jWmXl"
  db: 0

生产者

所有的生产者代码都放在asynq目录下,并且都继承BaseMQBaseMQ中封装了Producer方法,只需要实现Consumer方法即可

package asynq

import (
	"context"
	"fastApi/core/logger"
	"github.com/hibiken/asynq"
)

func init() {
	MQList = append(MQList, NewTest())
}

type Test struct {
	BaseMQ
}

func NewTest() *Test {
	return &Test{
		BaseMQ: BaseMQ{
			Typename: "test",
		}}
}

func (c *Test) Consumer(ctx context.Context, t *asynq.Task) error {
	logger.SLog(ctx).Infof("type: %v, payload: %s", t.Type(), string(t.Payload()))

	return nil
}


触发生产者

rawData := `{"name":"kwinwong"}`
err := asynq.NewTest().Producer(c, []byte(rawData))
fmt.Printf("err%v", err)

运行消费者

bin/fast-api-linux asynq -c config.yaml

链路追踪

fast-api 中基于OpenTelemetry集成了链路追踪config.yaml配置如下:

#链路追踪
telemetry:
  name: fast-api
  endpoint: http://127.0.0.1:14268/api/traces # trace信息上报的url
  sampler: 1.0  # 采样率

问题

windows 下的信号没有 SIGUSR1、SIGUSR2 等,做兼容处理:

在 go 的安装目录修改 Go\src\syscall\types_windows.go增加如下代码

var signals = [...]string{
    // 这里省略N行。。。。
 
    /** 兼容windows start */
    16: "SIGUSR1",
    17: "SIGUSR2",
    18: "SIGTSTP",
    /** 兼容windows end */
}
 
/** 兼容windows start */
func Kill(...interface{}) {
    return;
}
const (
    SIGUSR1 = Signal(0x10)
    SIGUSR2 = Signal(0x11)
    SIGTSTP = Signal(0x12)
)
/** 兼容windows end */
Description
fastApi: 基于Gin框架构建的web服务开发手脚架,统一规范开发,快速开发Api接口
Readme 170 KiB
Languages
Go 93.6%
Makefile 4.7%
Dockerfile 1.3%
Shell 0.4%