原文:http://tianyalong.icu/content.html?id=34
go web
Go的web框架分为两类:
- Router框架
- MVC框架
只要你的路由带有参数,并且这个项目的API数目超过了10,就尽量不要使用 net/http 中默认的路由。
梳理一下http库的Handler、HandlerFunc和ServeHTTP的关系
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
handler为自己编写的方法,他可以直接转换成HandlerFunc,因为他俩的函数签名相同。而HandlerFunc实现了ServeHTTP,所以他相当于实现了Handler。
调用的过程就是handler转换为HandlerFunc,再调用ServerHTTP来调用自己,从而将他认为是一个Handler。
那些事件适合中间件做
- 对http的响应体进行压缩处理
- 设置一个特殊的路由,例如/ping,/healthcheck,用来给负载均衡一类的前置服务进行探活
- 打印请求处理处理日志,例如请求处理时间,请求路由
- 挂载pprof需要的路由,如
/pprof
、/pprof/trace
到系统中 - 从请求头中读取X-Forwarded-For和X-Real-IP,将http.Request中的RemoteAddr修改为得到的RealIP
- 为本次请求生成单独的requestid,可一路透传,用来生成分布式调用链路,也可用于在日志中串连单次请求的所有逻辑
- 用context.Timeout设置超时时间,并将其通过http.Request一路透传下去
- 通过定长大小的channel存储token,并通过这些token对接口进行限流
限流
漏桶模式无法并发,令牌桶允许一定程度的并发, 如果令牌用光了就会退化成漏桶。
常见的Web项目分层
表驱动开发
func entry() {
var bi BusinessInstance
switch businessType {
case TravelBusiness:
bi = travelorder.New()
case MarketBusiness:
bi = marketorder.New()
default:
return errors.New("not supported business")
}
}
以上实现方式可以转换为一个map的方式来干掉Switch
var businessInstanceMap = map[int]BusinessInstance{
TravelBusiness: travelorder.New(),
MarketBusiness: marketorder.New(),
}
func entry() {
bi := businessInstanceMap[businessType]
}
金丝雀
灰度发布
也称为金丝雀发布,传说17世纪的英国矿井工人发现金丝雀对瓦斯气体非常敏感,瓦斯达到一定浓度时,金丝雀即会死亡,但金丝雀的致死量瓦斯对人并不致死,因此金丝雀被用来当成他们的瓦斯检测工具。