1. go包搜索

    https://pkg.go.dev/search

    1. go各种类型转换

    https://github.com/spf13/cast

    1. 路径解析

    image.png

    1. 作为一个 Web 框架,安全性是很关键的一个环节,我们在实现 JSONP 方法的时候,有这一行代码:

    //输出到前端页面的时候需要注意下进行字符过滤,否则有可能造成 XSS 攻击
    callback := template.JSEscapeString(callbackFunc)

    1. 建议各位在实现的时候可以在开头写上这么几句代码

    var IRequest = new(Context) var IResponse = new(Context) var _ context.Context = new(Context) 如果当前context没有实现完 IRequest 和 IResponse 会报错并且你能看到是哪些接口未实现。

    1. 优雅关闭

    或许你并没有意识到这个问题的严重性,不妨试想下,当一个用户在购买产品的时候,由于不优雅关闭,请求进程中断,导致用户的钱包已经扣费了,但是商品还未进入用户的已购清单中。这就会给用户带来实质性的损失。所以,优雅关闭服务,其实说的就是,关闭进程的时候,不能暴力关闭进程,而是要等进程中的所有请求都逻辑处理结束后,才关闭进程。按照这个思路,需要研究两个问题“如何控制关闭进程的操作” 和 “如何等待所有逻辑都处理结束”。image.png

    1. server.Shutdown 来进行优雅重启

    server.Shutdown 方法是个阻塞方法,一旦执行之后,它会阻塞当前 Goroutine,并且在所有连接请求都结束之后,才继续往后执行。

    1. 无限循环 ```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: // 如果没有结束,最长等待时间,进行轮询 } }

    1. 9. 优雅关闭
    2. ```go
    3. server := &http.Server{
    4. Handler: core,
    5. Addr: ":8888",
    6. }
    7. // 这个goroutine是启动服务的goroutine
    8. go func() {
    9. server.ListenAndServe()
    10. }()
    11. // 当前的goroutine等待信号量
    12. quit := make(chan os.Signal)
    13. // 监控信号:SIGINT, SIGTERM, SIGQUIT
    14. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
    15. // 这里会阻塞当前goroutine等待信号
    16. <-quit
    17. // 调用Server.Shutdown graceful结束
    18. timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    19. defer cancel()
    20. if err := server.Shutdown(timeout); err != nil {
    21. log.Fatal("Server Shutdown:", err)
    22. }
    1. 思维导图

    相信你看完 shutdown 这个函数的实现原理后,会不由得感叹 Golang 源码的优雅。很多同学会说没有好的 Golang 项目可以跟着学习,其实 Golang 源码本身就是一个非常好的学习资料。如果你能对其中的每个细节点画出思维导图,顺着导图中的分支展开分析,思考作者为什么会选择这种写法、有没有其他写法,多多练习,你一定会受益颇丰。
    image.png