- go包搜索
- go各种类型转换
- 路径解析
- 作为一个 Web 框架,安全性是很关键的一个环节,我们在实现 JSONP 方法的时候,有这一行代码:
//输出到前端页面的时候需要注意下进行字符过滤,否则有可能造成 XSS 攻击
callback := template.JSEscapeString(callbackFunc)
- 建议各位在实现的时候可以在开头写上这么几句代码
var IRequest = new(Context) var IResponse = new(Context) var _ context.Context = new(Context) 如果当前context没有实现完 IRequest 和 IResponse 会报错并且你能看到是哪些接口未实现。
- 优雅关闭
或许你并没有意识到这个问题的严重性,不妨试想下,当一个用户在购买产品的时候,由于不优雅关闭,请求进程中断,导致用户的钱包已经扣费了,但是商品还未进入用户的已购清单中。这就会给用户带来实质性的损失。所以,优雅关闭服务,其实说的就是,关闭进程的时候,不能暴力关闭进程,而是要等进程中的所有请求都逻辑处理结束后,才关闭进程。按照这个思路,需要研究两个问题“如何控制关闭进程的操作” 和 “如何等待所有逻辑都处理结束”。
- server.Shutdown 来进行优雅重启
server.Shutdown 方法是个阻塞方法,一旦执行之后,它会阻塞当前 Goroutine,并且在所有连接请求都结束之后,才继续往后执行。
- 无限循环 ```go
ticker := time.NewTicker(shutdownPollInterval) // 设置轮询时间 defer ticker.Stop() for { // 真正的操作 if srv.closeIdleConns() && srv.numListeners() == 0 { return lnerr } select { case <-ctx.Done(): // 如果ctx有设置超时,有可能触发超时结束 return ctx.Err() case <-ticker.C: // 如果没有结束,最长等待时间,进行轮询 } }
9. 优雅关闭
```go
server := &http.Server{
Handler: core,
Addr: ":8888",
}
// 这个goroutine是启动服务的goroutine
go func() {
server.ListenAndServe()
}()
// 当前的goroutine等待信号量
quit := make(chan os.Signal)
// 监控信号:SIGINT, SIGTERM, SIGQUIT
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
// 这里会阻塞当前goroutine等待信号
<-quit
// 调用Server.Shutdown graceful结束
timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := server.Shutdown(timeout); err != nil {
log.Fatal("Server Shutdown:", err)
}
- 思维导图
相信你看完 shutdown 这个函数的实现原理后,会不由得感叹 Golang 源码的优雅。很多同学会说没有好的 Golang 项目可以跟着学习,其实 Golang 源码本身就是一个非常好的学习资料。如果你能对其中的每个细节点画出思维导图,顺着导图中的分支展开分析,思考作者为什么会选择这种写法、有没有其他写法,多多练习,你一定会受益颇丰。