go语言中微服务框架介绍

go-kit

go-micro

go-zero文档

如何做好微服务

• 基本功能层面

a. 并发控制&限流,避免服务被突发流量击垮

b. 服务注册与服务发现,确保能够动态侦测增减的节点

c. 负载均衡,需要根据节点承受能力分发流量

d. 超时控制,避免对已超时请求做无用功

e. 熔断设计,快速失败,保障故障节点的恢复能力

• 高阶功能层面

a. 请求认证,确保每个用户只能访问自己的数据

b. 链路追踪,用于理解整个系统和快速定位特定请求的问题

c. 日志,用于数据收集和问题定位

d. 可观测性,没有度量就没有优化

实例应用架构

绿色背景的功能模块是自动生成的,按需激活

红色模块是需要自己写的,也就是增加下依赖,编写业务特有逻辑

• 微服务架构图

goctl各层代码生成

API gateway

rpc

model

goctl工具介绍

·goctl

goctlgo-zero配套的代码生成器

定义api请求

根据定义的api自动生成golang(后端), java(iOS & Android), typescript(web & 小程序),dart(flutter)

生成MySQL CURD

生成MySQL CURD

· 1) 生成 api

    goctl api -o xxx.api

# 描述了api基本信息比如Authapi是哪个用途
info(
    title: doc title
    desc: >
    doc description first part,
    doc description second part<
    version: 1.0
)

# type类型声明和golang语法兼容

type int userType

type user struct {
	name string `json:"user"` // 用户姓名
}

type student struct {
	name string `json:"name"` // 学生姓名
}

type teacher struct {
}

type (
	address struct {
		city string `json:"city"` // 城市
	}

	innerType struct {
		image string `json:"image"`
	}

	createRequest struct {
		innerType
		name    string    `form:"name"`         // niha
		age     int       `form:"age,optional"` // nihaod
		address []address `json:"address,optional"`
	}

	getRequest struct {
		name string `path:"name"`
		age  int    `form:"age,optional"`
	}

	getResponse struct {
		code    int     `json:"code"`
		desc    string  `json:"desc,omitempty"`
		address address `json:"address"`
		service int     `json:"service"`
	}
)


# 一个文件里面只能有一个service

# service代表一组服务
# 一个服务可以由多组名称相同的service组成
# 可以针对每一组service配置group属性来指定service生成所在子目录

service user-api {
    # doc用来描述此路由的用途
    @doc(
        summary: user title
        desc: >
        user description first part,
        user description second part,
        user description second line
    )
    @server(
        handler: GetUserHandler
        # GetProfileHandler表示处理这个路由的handler
        
        group: user
        # group属性来指定service生成所在子目录
    )
    get /api/user/:name(getRequest) returns(getResponse)
    #请求方式   路由path     返回的结构体
    
    
    @server(
        handler: CreateUserHandler
        group: user
    )
    post /api/users/create(createRequest)
}

service user-api {
    @doc(summary: user title)
    @server(
        handler: GetProfileHandler
    )
    get /api/profile/:name(getRequest) returns(getResponse)

    @server(
        handler: CreateProfileHandler
    )
    post /api/profile/create(createRequest)
}

service user-api {
    @doc(summary: desc in one line)
    @server(
        handler: PingHandler
    )
    head /api/ping()
}

·2) 根据定义好的api文件生成golang代码

    goctl api [go/java/ts] [-api user/user.api] [-dir ./src]

    
    .
      ├── internal
      │   ├── config
      │   │   └── config.go
      │   ├── handler
      │   │   ├── pinghandler.go
      │   │   ├── profile
      │   │   │   ├── createprofilehandler.go
      │   │   │   └── getprofilehandler.go
      │   │   ├── routes.go
      │   │   └── user
      │   │       ├── createuserhandler.go
      │   │       └── getuserhandler.go
      │   ├── logic
      │   │   ├── pinglogic.go
      │   │   ├── profile
      │   │   │   ├── createprofilelogic.go
      │   │   │   └── getprofilelogic.go
      │   │   └── user
      │   │       ├── createuserlogic.go
      │   │       └── getuserlogic.go
      │   ├── svc
      │   │   └── servicecontext.go
      │   └── types
      │       └── types.go
      └── user.go

生成的代码可以直接跑,有几个地方需要改

servicecontext.go里面增加需要传递给logic的一些资源,比如mysql, redis,rpc等

在定义的get/post/put/delete等请求handlerlogic增加处理业务逻辑的代码

实例应用

1)mkdir hello
  cd hello

2) go mod init  hello

3) goctl api -o hello.api

4) 编辑hello
    
    syntax = "v1"
    
    info(
        title: "用戶注冊"// TODO: add title
        desc: "用戶注冊"// TODO: add description
        author: "jiamin"
        email: "jiamin@xx.cn"
    )
    
    type (
        UserOptReq {
            Mobile string `json:"mobile"`
            Passwd string `json:"passwd"`
            Code   string `json:"code"`
        }
    
        UserOpResp {
            Id    int    `json:"id"`
            Token string `json:"token"`
        }
    
        //图片验证码支持
        VerifyReq {
            Ticket string `json:"ticket"`
        }
    
        //图片验证码支持
        VerifyResp {
            Data string `json:"data"`
        }
    )
    
    service hello-api {
        @doc(
            summary: 公开的api函数
            desc: >
            register: 用户注册,
            authorization: 用户登录,
            verify: 图片验证码接口
        )
        @server(
            handler: registerHandler
            group: register
        )
        post /open/register(UserOptReq) returns(UserOpResp)
    }
    
    service hello-api {
        @doc(
            summary: 公开的api函数
            desc: >
            register: 用户注册,
            authorization: 用户登录,
            verify: 图片验证码接口
        )
        
        @server(
            handler: authorizationHandler
            group: authorization
        )
        post /open/authorization(UserOptReq) returns(UserOpResp)
        
        @server(
            handler: verifyHandler
            group: verify
        )
        post /open/verify(VerifyReq) returns(VerifyResp)
        
    }


5)生成代码
    
    goctl api  go   -api   hello.api   -dir  .

6) 运行测试 
    
    go run hello.go
    
    curl http://127.0.0.1:8888/open/register -X POST -H "Content-Type: application/json" -d {\"mobile\":\"15367151352\",\"passwd\":\"testpwd\",\"code\":\"asdf\"}
    # {"id":0,"token":""}
Buy me a 肥仔水!