ATC:快速开发 Go 应用程序的开源框架

网友投稿 918 2022-10-09

ATC:快速开发 Go 应用程序的开源框架

ATC:快速开发 Go 应用程序的开源框架

ATC

ATC 是一个快速开发GO应用程序的开源框架,支持RESTful API, Grpc, Redis, Nats队列的框架.可根据自身业务逻辑选择性的卸载中间件的功能,均支持平滑退出。

要求GO版本 >= 1.8 当前版本: 1.0.4

安装ATC

go get github.com/adolphlxm/atc

用到的第三方 go package TAG

// 配置文件加载包,之前写的一个Github账户,后续会迁移过来,方便管理 github.com/lxmgo/config // 官方websocket包 code.google.com/p/go-/websocket // xorm 包 github.com/go-sql-driver/mysql github.com/go-xorm/xorm github.com/go-xorm/core

RESTful API 经典案例

一个经典的ATC例子 atc.go

package mainimport ( "github.com/adolphlxm/atc")type LoginHandler struct { atc.Handler}func (this *LoginHandler) Get(){ // 已登录 if true { loginData := map[string]interface{}{ "username" : "ATC", "regtime":"2017-04-28", } this.Ctx.SetData("data",loginData) this.Ctx.SetData("ID",this.Ctx.Query("id")) this.jsON() return } // 未登录 // 自定义错误提示内容 this.Error406(-1).Message("没有权限查看").JSON() // error.ini错误码匹配的提示内容 // this.Error406(-1).JSON() return }func main(){ // 根据配置文件注入依赖中间件 // 目前支持:HTTP/Websoeckt、Thrift、ORM(xorm、其它待开发) atc.Run()}

路由加载 router.go

// 登录过滤器// 可以通过自定义过滤器来实现登录状态、权限检查等功能func AfterLogin(ctx *context.Context){ // 错误输出 error := atc.NewError(ctx) error.Code(401,10000).JSON()}func init(){ // 分组版本控制 v1 := atc.Route.Group("V1") { // V1版本路由 v1.AddRouter("users.login",&LoginHandler{}) ... } V2 := atc.Route.Group("V2") { // V2版本过滤器, 根据路由规则加载。 // 支持三种过滤器: // 1. EFORE_ROUTE //匹配路由之前 // 2. BEFORE_HANDLER //匹配到路由后,执行Handler之前 // 3. AFTER //执行完所有逻辑后 v2.AddFilter(atc.BEFORE_ROUTE,"users.*",AfterLogin) // V2版本路由 v2.AddRouter("users.login",&LoginHandler{}) ... }}

然后在浏览器访问

http://localhost/V1/users/login将会得到一个json返回 http://localhost/V2/users/login先执行BFORE_ROUTE过滤器, 未通过则得到一个json返回。通过过滤器后 加载 Get(), 将会得到一个json返回。

路由规则

固定路由

固定路由也就是全匹配的路由,如下所示:

注:ATC路由模块之间请使用"."来区分,而不是"/"

// 匹配根目录atc.AddRouter(".", &index.MainHandler{})// 匹配 /apiatc.AddRouter("api",&api.IndexHandler{})// 匹配 /api/listatc.AddRouter("api.list", &api.ListHandler{})// 匹配 /api/groupatc.AddRouter("api.group", &api.GroupHandler{})

如上所示的固定路由就是我们最常用的路由方式,根据用户请求方法不同请求控制器中对应的方法,典型的 RESTful 方式。

正则路由

为了更加方便的路由设置,ATC 支持多种方式的路由:

{id:[\d]*}, 其中 '*' 表示匹配{}表达式零次或多次{id:[\d]?}, 其中 '?' 表示匹配{}表达式零次或一次{id:[\d]+}, 其中 '+' 表示匹配{}表达式一次或多次

// 匹配 /api/123 , 同时可匹配 /api | /api/ 这两个URL // id = 123 , 可通过this.Ctx.ParamIndex64("id") 获取参数值 // 匹配{id:[0-9]*}表达式零次或多次atc.AddRouter("api.{id:[0-9]*}",&api.IndexHandler{})// 匹配 /api/123, 不匹配 /apiatc.AddRouter("api.{id:[0-9]+}",&api.IndexHandler{})atc.AddRouter("api.{id}",&api.IndexHandler{})// 自定义正则匹配, 匹配 /api/adolph , name = adolphatc.AddRouter("api.{name:[\w]+}",&api.IndexHandler{})

Context接参方法

Param() 接收URL正则参数 context.Param() 返回stringcontext.ParamInt() 返回intcontext.ParamInt64() 返回int64context.ParamUint64() 返回uint64 Query() 接收Form表单参数 context.Query() 返回stringcontext.QueryInt() 返回intcontext.QueryInt64() 返回int64context.QueryUint64() 返回uint64context.QueryStrings() 返回[]string

顺序平滑退出

使用双向链表list实现

客户端实现TT接口 type TT interface { ModuleID() string Stop() error }ModuleID() 方法返回string, 表示退出模块名称Stop() 方法根据客户端业务自行实现退出逻辑 通过atc.Grace...() 方法插入实现的接口struct ATC默认在队头插入了http,thrift,queuePublisher,queueConsumer四个TT退出接口,也可根据客户端需要自行控制退出顺序。 当ATC收到退出信号时(参阅信号说明),从队尾开始,逆向顺序逐个退出

使用方法

// 双向链表队头插入退出接口 atc.GracePushFront(TT) // 双向链表队尾插入退出接口 atc.GracePushBack(TT) // 在"atc"模块的链表之后插入退出接口 atc.GraceInsertAfter("atc",TT) // 在"atc"模块的链表之前插入退出接口 atc.GraceInsertBefore("atc",TT) // 在链表中移除"atc"退出接口 atc.GraceRemove("atc") // 在链表中将"atc"接口移动到"http"之后。 atc.GraceMoveAfter("atc", "http") // 在链表中将"atc"接口移动到"http"之前。 atc.GraceMoveAfter("atc", "http")

Queue 队列

支持redis、nats两个队列

atc.QueuePublisher [生产实例]QueueConsumer [消费实例]实例初始化配置可在app.ini内写

配置参数

queue.publisher.support 参数:true | false注释:是否支持开启生产实例 queue.publisher.aliasnames参数: 别名,逗号隔开,如:p1,p2...注释:用来初始化多实例 queue.publisher.[aliasname].driver 参数: redis | nats注释:支持的队列驱动 queue.publisher.[aliasname].addrs 参数:redis://127.0.0.1:6379注释:redis连接地址 queue.consumer.support 参数:true | false注释:是否支持开启消费者实例

使用方法

// Publisheratc.GetPublisher("aliasname").Publish("subject", &message.Message{ Body: util.MustMessageBody(nil, /* point to your protobuffer struct */ ),})// Consumersub,_ := atc.GetPublisher("aliasname").Subscribe("subject", "cluster-group")msg, _ := sub.NextMessage(time.Second)// logic for msg

RPC 经典案例

Grpc 关于Grpc本身可查看

document: https://grpc.io/http://doc.oschina-/grpc?t=58010 examples: https://github.com/grpc/grpc-go/tree/master/examples

Grpc使用

通过.proto生成server / client 代码 protoc --go_out=plugins=grpc:. helloworld.proto 在app.ini配置文件打开grpc并配置对应的地址和端口编写server代码(举例) package mainimport ( "context" "github.com/adolphlxm/atc" pb "github.com/adolphlxm/test1/helloworld")// GRPC servertype server struct {}func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil}// 在atc.Run()之前注册GRPC服务func init() { pb.RegisterGreeterServer(atc.GetGrpcServer(), &server{})}func main() { atc.Run()} 编写client代码(举例) package main//client.goimport ( "log" "os" "golang.org/x/net/context" "google.golang.org/grpc" pb "example/rpc/helloworld")const ( address = "127.0.0.1:50005" defaultName = "world")func main() { conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatal("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) name := defaultName if len(os.Args) >1 { name = os.Args[1] } r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatal("could not greet: %v", err) } log.Printf("Greeting: %s", r.Message)}

Thrift RPC 关于Thrift RPC 具体可以 度娘、谷爹查看

之前写过一篇Thrift简单使用教程:GO/PHP使用指南

获取Thrfit-官方

官方各种DEMO

协议库IDL文件参考资料

这里就不累赘描述Thrift具体用法了。

Go的Thrift包已经整合在ATC框架内了,无需重新安装和-了!由于Go的Thrift源码有修改,支持RPC平滑退出使用.thrift IDL 生成 .go 请使用 atc-tool 工具(不然可能会报错.)

atc-tool 工具

Thrift RPC 路由 router.go

func init() { processor := micro.NewMicroThriftProcessor(&MicroHandler{}) atc.ThriftRPC.RegisterProcessor("user", processor)}

ORM

通过app.ini配置文件加载多库初始化方法返回 orm interface 接口

atc.DB("aliasname").Where("id=?",1).Get(...)

Cache

通过app.ini配置redis,memcache

atc.GetCache("aliasname").Put()atc.GetCache("aliasname").Put()atc.GetCache("aliasname").Get()atc.GetCache("aliasname").Delete()...

Mongodb

通过app.ini配置文件加载多库初始化方法Collection操作均是session Clone() ,调用方法均已进行了 Close()配置addrs=mongodb://127.0.0.1:27017/? 支持的参数

// 快速使用Collection,均已进行了Close()放心使用 atc.GetMgoDB("aliasname").Insert(name,col,data) atc.GetMgoDB("aliasname").Update(name,col,selector) ... // 快速使用Find,均已进行了Close()放心使用 atc.GetMgoDB("aliasname").Find(name,col, query).One() atc.GetMgoDB("aliasname").Find(name,col, query).All() ...

// Query q := atc.GetMgoDB("aliasname").Find().Query() q.One() // 注意,此时需要关闭session q.Close() ...

日志处理

通过app.ini配置日志输出引擎

参数说明

logdir 存放日志路径maxsize 日志分割文件尺寸, 单位:bytebuffersize 日志缓冲区大小,单位:byteflushinterval 定时刷新日志到磁盘的间隔时间,单位:s

级别说明(枚举)

LevelFatal = iota 打印文件名及行号LevelError 打印文件名及行号LevelWarn 打印文件名及行号LevelNotice 不打印文件名及行号LevelInfo 不打印文件名及行号LevelTrace 不打印文件名及行号LevelDebug 打印文件名及行号

通用使用方式

logs.Debug("") logs.Debugf("%v", "debugf") logs.Info("") logs.Infof("%v", "infof") logs.Warn("") logs.Warnf("%v", "warnf") logs.Error("") logs.Errorf("%v", "errorf") ... logs.Flush()

编译并运行

go build atc.go./atc

Flag参数说明:

-c string use -c (default "conf/app.ini") -m string Use -m (default "dev") -v Use -v

ATC信号控制:

信号量退出
TERM,INT立即终止
QUIT优雅的关闭进程,即等所有请求结束后再关闭

配置说明

atc.Aconfig 调用ATC内置参数举例:atc.Aconfig.ConfDir 获取当前项目配置目录(输出:./conf/) atc.AppConfig 调用配置文件自定义配置项

ATC项目结构

├── conf│ ├── app.ini│ └── error.ini├── front│ └── HTML...├── bin├── src│ ├── httprouter│ ├── V1│ └── router.go│ └── thriftrpc│ ├── idl│ ├── gen-go│ ├── ...(.go)│ └── router.go└── atc.go

特性

支持RESTful HTTP通信 及 平滑退出支持Websoeckt通信支持RPC通信 及 平滑退出 Thrift

更新日志

2017.5 日志支持file文件写入,通过app.ini 配置日志类型支持Flag参数(-c 配置文件, -m 配置环境, -v 当前版本号)优雅的关闭进程优化错误码配置文件加载,通过app.ini 配置错误码文件优化DEBUG模式 2017.6 utils/encrypt包增加RSA/DES/AES 加解密修复ORM BUGrpc/thrift 增加 thrift client 实现, 结合pool对连接进行管理(线程安全,thrift的本身client端是线程不安全的)pool包 通用连接池管理优化thrift RPC,支持atc-tool生成工具,使用更方便支持 API 跨域配置, 通过app.ini 配置跨域 2017.7 修复不同环境配置app.ini不生效 BUG优化日志模块 logs 包,使用更方便重构thrift client pool 封装,修复若干BUG修复日志级别BUG 2017.8 增加cache缓存模块支持memcache 2017.10 优化路由,Context struct增加RunHandler字段,便于在REST中获取和过滤运行Handler优化JSON输出,变更前仅支持 this.Ctx.SetDatas( map[string]interface{}) -> this.JSON() ,变更后兼容之前使用方式同时支持 this.JSON(interface{}) 2017.11 cache缓存模块支持redis 2017.12 优化RESTFul router 正则匹配Context提供更多的路由正则参数解析方法 及 更多的表单解析方法增加客户端顺序平滑退出接口优化logs包,日志写入缓冲区,定时刷新缓存区到磁盘(也可以退出程序时,调用logs.Flush()方法主动刷取)及配置文件增加了queue队列封装包 2018.1 ATC框架管理orm初始化实例增加cache,queue多实例管理增加mongodb封装,多实例管理优化初始化 2018.2 优化Redis、Mgo、Cache、Orm、Queue初始化及退出等日志统一输出格式增加平滑退出顺序日志输出修改配置文件,日志级别设置优化加载配置 2018.3 优化orm, 使用xorm最新版本修复配置加载BUG,异常时输出错误日志

即将支持特性(待定稿)

HTTPS / POST附件上传压缩gRPC服务注册与发现模块

LICENSE

ATC is Licensed under the Apache License, Version 2.0 (the "License") (http://apache.org/licenses/LICENSE-2.0.html).

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:104. Maximum Depth of Binary Tree
下一篇:234. Palindrome Linked List
相关文章

 发表评论

暂时没有评论,来抢沙发吧~