go语言微服务api网关实践

golang Chase 2276℃ 0评论

基本架构

  • 微服务采用go-micro(v2)框架
  • http服务采用beego(v1)框架
  • 拓扑也很典型

具体实施

第一个版本

  • 由go-micro提供service层
  • http网关作为微服务的客户端接入
  • 项目结构
.
├── conf
│   └── app.conf
├── controllers
│   └── init.go
├── go.mod
├── go.sum
├── main.go
├── models
│   ├── init.go
├── pb
│   ├── xxx.pb.go
│   ├── xxx.pb.micro.go
│   ├── xxxx.pb.go
│   └── xxxx.pb.micro.go
├── routers
│   └── router.go
├── services
│   ├── init.go
│   └── rpc.go
└── bee_go_micro
  • 代码
//service/rpc.go
var RpcClient BeeGoMicroService
func RunRpcServer() {
    rpc := micro.NewService(
        micro.Name("go.rpc.bee_go_micro"),
    )
    rpc.Init(
        micro.AfterStart(func() error {
            //此处的问题是,当程序启动时可能client还没创建好,导致使用rpc.RpcClient调用方法时无法获得预期数据
            RpcClient = pb.NewBeeGoMicroService("go.rpc.bee_go_micro", rpc.Client())
            return nil
        }),
    )
    if e := pb.RegisterBeeGoMicroHandler(rpc.Server(), new(BeeGoMicro)); e != nil {
        panic(e.Error())
    }
    if e := rpc.Run(); e != nil {
        panic(e.Error())
    }
}

//controllers/init.go
type Api struct {
    beego.Controller
}

func (a *Api) Get() {
    var data interface{}
    var err error
    defer func() {
        a.Data["json"] = data
        a.ServeJSON()
    }()
    data, err = rpc.RpcClient.Get(...)      //伪代码
}

第二个版本

思考

  • api那层经过抽象以后都有大量重复代码,是否可以自动生成api-gateway?
  • 为何不以protobuf文件为设计指导,专注于开发service?

自问自答

  • 两个问题其实可以通过写protobuf插件的形式来生成代码,然后专注service开发
    • 插件需要实现protoc-gen-go中的四个方法
    • 生成基于beego的http gateway
  • 采用新方案项目结构
.
├── bmicro      //生成的文件
│   ├── test.pb.bmicro.go       //生成的gateway
│   ├── test.pb.go
│   └── test.pb.micro.go
├── models
├── routers
│   └── filter.go       //可在此处编写特殊业务的拦截器
├── go.mod
├── go.sum
├── main.go
├── conf        //beego配置
│   └── app.conf
└── test.proto

附上在下编写的protoc-gen-bmicro插件

  • protoc-gen-bmicro
  • TODOs:
    • gen-code
    • beego.validation
    • rate-limiting
    • caching
    • loging
    • authorization

转载请注明:攻壳tech » go语言微服务api网关实践

喜欢 (95)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址