基本架构
- 微服务采用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网关实践