踩坑经验1——golang的template库的坑

93 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

今天发生了一次线上事故,虽然我对项目上线已经非常谨慎,但仍然免不了马失前蹄。

这次的事故,不是代码逻辑,而是在用到某个golang的库的时候踩坑了,具体是html/template库。

可以参看下面的demo

package main

import (
   "bytes"
   "encoding/json"
   "fmt"
   "html/template"
)

type BizData struct {
   ID int64 `json:"id"`
   //ID string `json:"id"`
}

type BizData2 struct {
   ID string `json:"id"`
}

func main() {
   bizData, _ := json.Marshal(&BizData{
      ID: 1000000,
      //ID: 1,
      //ID: "1000000",
   })

   var extraData interface{}
   _ = json.Unmarshal(bizData, &extraData)
   temp, _ := template.New("test").Parse("{{.id}}")
   content, _ := parseTemplate(temp, extraData)
   fmt.Println(content) // 1e+06
}

// 渲染模版配置
func parseTemplate(t *template.Template, v interface{}) (data string, err error) {
   buf := new(bytes.Buffer)
   err = t.Execute(buf, v)
   if err != nil {
      fmt.Println(err)
      return
   }
   data = buf.String()
   return
}

上面这段demo,如果id传int64类型,当大于1000000时,会被template库转成科学计数法的形式,如1e+06

目前我的解决思路是,不传int64,而是传string类型,得以解决问题。

在发现和解决问题时,我主要做了以下几件事:

  1. 快速定位问题。通过日志大概定位出问题原因,并在uat环境进行了模拟验证。
  2. 恢复线上。迅速停掉了有问题的在线任务,让线上得以恢复,不过期间任务没有运行,会丢掉部分数据。
  3. 统计影响量。根据日志,统计了受影响的用户,联系产品做决策。
  4. 代码修复。把bug迅速修复好,保证线上能恢复运行。
  5. 错误数据处理。对影响的用户进行私信撤回,不过这部分花了不少时间,因为撤回私信的流程较为麻烦。
  6. 重新执行。对已经撤回的私信,重新进行发送。

本次事件值得我思考的地方:

  1. 测试时,如果使用一些模式的库,要多做一些测试
  2. 线上告警还不是很健全,很多服务存在日志告警配置不合理的情况
  3. 微服务拆分要提上日程,可以更精准的了解特定服务的运行情况,并对症下药
  4. 由于之前在做方案设计的时候,支持了重试,所以能支持快速恢复,以后这些好的设计思路应继续保持