RX is a dynamic configurable and assemble web framework based on Go.
- Dynamic middleware
- Customized Group
- Customized Strategy
- Customized Response
- Asynchronous Router
- Customized Abort
- TCP Server
- Context Transfer
- Epoll Kqueue
- URL Parse
- Body Parse
- File Upload
- Benchmark
动态中间件(ctx 栈调用) 使用 Next 函数可以定义本 handler 执行完毕后下一个运行的 handler,动态化中间件, 避免了中间件的静态硬编码带来的逻辑麻烦.
func handler(ctx ctx.ReqCxtI) {
log.Println("execute handler")
ctx.Next(handler4)
}
- 自定义路由组, 可以定义递归组, 每个组可添加多个handler, 以递归栈形式调用。极大简化了手动注册路由的麻烦。
- 例如: 定义一个 /v1 组, 其子组 /v2, 孙组 /v3, 如下可以注册路由为:
group := ctx.Group("/v1", handler1)
group.Register("get", "ddd", handler2)
// 递归组
sub := group.Group("/v2", handler2, handler3)
sub.Register("get", "/aaa", handler3)
sub2 := sub.Group("/v3", handler4, handler5)
sub2.Register("get", "/eee", last)
ctx.Register("post", "/ccc", handler1, handler2, handler4)
ctx.Register("get", "/ccc", handler1, handler2, handler4)
---------------------------------------------------
|EGISTER ROUTER:| post | /ccc |3|
|EGISTER ROUTER:| get | /ccc |3|
|EGISTER ROUTER:| get | /v1/ddd |2|
|EGISTER ROUTER:| get | /v1/v2/aaa |4|
|EGISTER ROUTER:| get | /v1/v2/v3/eee |6|
--------------------------------------------------
- 自定义策略
- 超时策略: 在某个handler内部设置超时, 可极大简化reqContext 的超时管理, 无论栈内有多少待执行handler,一旦 超时直接按照约定的超时策略中断流程, 并返回相关数据
- TTL策略: 可设置最大栈内调用深度, 可以极大简化维护栈内调用,方便debug,一旦handler执行次数超过 ttl 设定的阈值, 将中断reqContext 并按照约定返回相关数据
- 异步策略: 设置handler为异步执行, 会往协程池丢送一次任务,并快速返回,任务静默运行。
- 安全策略: 设置安全检查
- 熔断策略: 设置熔断检查
todo:
- panic策略:
- error 策略:
- 兜底策略:
- 降级策略:
- 其它:
- 样例1: 如下 group 组注册了 handler1 处理, 其下所有注册的路由都将采取该策略来初始化自己的请求上下文。
- 样例2: 使用 注册接口注册一个自定义的处理策略 c.RegisterStrategy(&ctx.StrategyContext{Ttl: 4})
func handler1(c ctx.ReqCxtI) {
c.SetTimeOut(1 * time.Second)
c.SetTTL(4)
log.Println("execute handler1")
c.RegisterStrategy(&ctx.StrategyContext{Ttl: 4})
}
group := ctx.Group("/v1", handler1)
// /v1/api 路由若1秒内完成,则退出并返回, 若执行了四次handler,则退出返回
group.Register("get", "api", handler2)
- 完美支持异步路由! 再不用担心写异步逻辑了! 全部交给RX, 配合自定义策略进行功能化拓展!
- 样例:
func handler1(c ctx.ReqCxtI) {
c.RegisterStrategy(&ctx.StrategyContext{Ttl: 4, Timeout: 2 * time.Second, Async: true})
}
func handler2(c ctx.ReqCxtI) {
// 使用异步来标识异步处理逻辑
// 阻塞5秒钟
time.Sleep(5 * time.Second)
log.Println("execute handler2")
}
// 执行如下
group := ctx.Group("/v1", handler1, handler2)
group.Register("get", "ddd", myhandler)
当使用 RegisterStrategy 注册自定义策略绑定到某个Group上, 若在某个handler有延迟逻辑,使用异步可以轻便的让
超时逻辑得以执行!
- 自定义 response
- 目前支持JSON
func handler(ctx ctx.ReqCxtI) {
log.Println("execute handler")
ctx.JSON(200, map[string]interface{}{"time": time.Now(), "engine": ctx.Get("user")})
}
- 自定义 abort
- 当在handler context中调用此函数, 将直接以指定的 message 退出当前请求, 后续的栈中中间件将不再执行。如下所示,Next将handler压栈,但是不会再执行
- 富化中 增加模板
ctx.SetDefaultHandler(404, func(ctx ctx.ReqCxtI) {
ctx.Next(handler) // not execute
ctx.Abort(200, "Not Allowed")
})
- 支持TCP长连接 web
server := engine.NewServer("std", "127.0.0.1:9999")
server.Type("tcp")
defer server.Run()
- context 信息传递
- 原生并发处理
ctx.Set("user", []string{"a", "b", "c"})
ctx.Get("user")
- epoll kqueue 内核态长连接支持
type PollIF interface {
ChangeRW(fd int)
ChangeDetach(fd int)
ChangeRead(fd int)
AddRW(fd int)
AddRead(fd int)
Looping(execute func(fd int) error)
Close() error
Trigger(note interface{}) error
}
- 获取url参数
name := ctx.GetQuery("name", "XR")
log.Println(name)
- post Body动态解析
type PostBody struct {
Name string `json:"name"`
}
func handler5(ctx ctx.ReqCxtI) {
var post PostBody
err := ctx.ParseBody(&post)
ctx.JSON(200, map[string]interface{}{"time": time.Now(), "engine": post.Name})
}
- 支持文件上传, 异步上传
- todo: 支持 bytes 流上传
func upload(c ctx.ReqCxtI) {
c.SaveLocalFile("dst path")
c.JSON(200, "xxx")
}
提升负载策略,真实并发量突破3200 ab -n 1000 -c 10 http://localhost:9999/ping
Server Software: RX
Server Hostname: 127.0.0.1
Server Port: 9999
Document Path: /ping
Document Length: 18 bytes
Concurrency Level: 10
Time taken for tests: 0.161 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 98000 bytes
HTML transferred: 18000 bytes
Requests per second: 6217.90 [#/sec] (mean)
Time per request: 1.608 [ms] (mean)
Time per request: 0.161 [ms] (mean, across all concurrent requests)
Transfer rate: 595.07 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.2 1 1
Processing: 0 1 0.2 1 2
Waiting: 0 1 0.2 1 2
Total: 0 1 0.4 2 2
ERROR: The median and mean for the total time are more than twice the standard
deviation apart. These results are NOT reliable.
Percentage of the requests served within a certain time (ms)
50% 2
66% 2
75% 2
80% 2
90% 2
95% 2
98% 2
99% 2
100% 2 (longest request)