Open
Description
测试方式: ab -c 10 -n 100 localhost:8000/debug/vars
测试结果:
fatal error: concurrent map read and map write
goroutine 139 [running]:
runtime.throw(0x4a46303, 0x21)
/usr/local/go/src/runtime/panic.go:1116 +0x72 fp=0xc001b0c208 sp=0xc001b0c1d8 pc=0x4034962
runtime.mapaccess2(0x491bee0, 0xc0005cb080, 0xc001b0c288, 0x0, 0xc001a39601)
/usr/local/go/src/runtime/map.go:469 +0x258 fp=0xc001b0c248 sp=0xc001b0c208 pc=0x400fbd8
github.com/go-playground/validator/v10.(*Validate).RegisterTranslation(0xc00008e4e0, 0x4a31dce, 0xc, 0x4bbb0e0, 0xc001a3bb60, 0xc001acc690, 0x4a6d278, 0x0, 0x0)
/Users/hxj/godevspace/pkg/mod/github.com/go-playground/validator/[email protected]/validator_instance.go:261 +0xb0 fp=0xc001b0c2a8 sp=0xc001b0c248 pc=0x43ea6c0
github.com/go-playground/validator/v10/translations/zh.RegisterDefaultTranslations(0xc00008e4e0, 0x4bbb0e0, 0xc001a3bb60, 0x0, 0x62fdf00)
/Users/hxj/godevspace/pkg/mod/github.com/go-playground/validator/[email protected]/translations/zh/zh.go:1321 +0x4f9 fp=0xc001b0d3b0 sp=0xc001b0c2a8 pc=0x480bfd9
github.com/go-programming-tour-book/blog-service/internal/middleware.Translations.func1(0xc000398000)
/Users/hxj/Work/work_go/go-programming-tour-book/blog-service/internal/middleware/translations.go:30 +0x1ea fp=0xc001b0d458 sp=0xc001b0d3b0 pc=0x4816a8a
github.com/gin-gonic/gin.(*Context).Next(0xc000398000)
/Users/hxj/godevspace/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 +0x3b fp=0xc001b0d478 sp=0xc001b0d458 pc=0x45e9f8b
github.com/go-programming-tour-book/blog-service/internal/middleware.ContextTimeout.func1(0xc000398000)
/Users/hxj/Work/work_go/go-programming-tour-book/blog-service/internal/middleware/context_timeout.go:16 +0x14f fp=0xc001b0d4f8 sp=0xc001b0d478 pc=0x48161df
github.com/gin-gonic/gin.(*Context).Next(0xc000398000)
/Users/hxj/godevspace/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 +0x3b fp=0xc001b0d518 sp=0xc001b0d4f8 pc=0x45e9f8b
github.com/go-programming-tour-book/blog-service/internal/middleware.RateLimiter.func1(0xc000398000)
/Users/hxj/Work/work_go/go-programming-tour-book/blog-service/internal/middleware/limiter.go:23 +0x89 fp=0xc001b0d568 sp=0xc001b0d518 pc=0x4816449
修复方式: 去掉 translations.go中间件,将中间件中的函数内容放到main.go文件中,函数体:
// 在global包中定义全局变量
var Trans ut.Translator
// InitTrans 初始化翻译器
func InitTrans(locale string) (err error) {
// 修改gin框架中的Validator引擎属性,实现自定制
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
zhT := zh.New() // 中文翻译器
enT := en.New() // 英文翻译器
// 第一个参数是备用(fallback)的语言环境
// 后面的参数是应该支持的语言环境(支持多个)
// uni := ut.New(zhT, zhT) 也是可以的
uni := ut.New(enT, zhT, enT)
// locale 通常取决于 http 请求头的 'Accept-Language'
var ok bool
// 也可以使用 uni.FindTranslator(...) 传入多个locale进行查找
global.Trans, ok = uni.GetTranslator(locale)
if !ok {
return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
}
// 注册翻译器
switch locale {
case "en":
err = enTranslations.RegisterDefaultTranslations(v, global.Trans)
case "zh":
err = zhTranslations.RegisterDefaultTranslations(v, global.Trans)
default:
err = enTranslations.RegisterDefaultTranslations(v, global.Trans)
}
return
}
return
}
在main()函数中调用:
func main() {
if err := InitTrans("zh"); err != nil {
fmt.Printf("init trans failed, err:%v\n", err)
return
}
......
}
修改pkg/app/form.go文件中的
BindAndValid(){
// 直接用全局变量
for key, value := range verrs.Translate(global.Trans) {
....
}
}
Metadata
Metadata
Assignees
Labels
No labels