美文网首页
golang expvar的坑

golang expvar的坑

作者: chaunsin | 来源:发表于2019-10-21 18:39 被阅读0次

    概述

    golang标准库expvar包提供一个全局变量的一个包,是线程安全的,主要功能可以存储一些简单的数据比如api请求次数计数,记录当前堆栈的一些信息、 gc次数、 调用cgo次数等等..... 网上相关的教程都很详细不在赘述。

    问题描述

    在开发wechat小程序的时候想把accessToken存在expvar中, 因为这是一个全局的变量存在这里面正适合,线程安全的,方法已经写好无需重复造轮子。但是向微信服务器发送请求验证的时候总是说我的accessToken不正确40001,起初并没有怀疑accessToken有问题 因为我从expvar中Get()出同样的值,在通过微信给的校验接口工具校验 ,也成功通过了,当时特别诧异!?怀疑过编码问题 因为用的grpc ,但很快就pass掉了, 过后想起来自己还特别可笑-_- 折腾了一上午 server端 client端到处打印调试我终于发现了问题,expvar.Get().String() 获取到的值和期望的值不等。

    正题 

    expvar.Get("foo-prefix").String()    //获取到的值是"foo"   不是foo是代双引号的

    对应的结果示例

    从运行结果中已经很明显了  foo的字符串加上了 双引号" "  哎脑袋疼 事后向go提了一个issuse 结果不到俩小时给我打了回来 嗯有点尴尬 说让我用exp.Value()方法 ~嗯完了 可能作者有意设置成这样的吧。 但是这样真的会让人造成一种歧义。

    unquoted

    https://play.golang.org/p/kx87CKi_oEa

    https://github.com/golang/go/issues/35026

    结论

    一、

    当且仅当获取string类型的对象的时候不要用get以免造成歧义 如果非要使用 用strings包中的字符串处理或者切片处理把双引号去除掉 ,最好还是使用expvar.NewXxx() 的原对象的Value()方式来取值就不会有问题了。

    二、

    另一个需要注意对象的key值不能重复不然会发生键重复panic错误。

    三、

    还有一个最重要的一个点在使用expvar包会注册 http://127.0.0.1:port/debug/vars 路由地址,和pprof类型的形式一样,通过浏览器会看到 cmdline ,memstats信息 和你使用的NewXxx()方法注册的变量的内容 以json的格式进行展示,为了安全一定要考虑这个地址进行拦截等处理防止嗅探服务器信息,造成服务器存在安全隐患问题。当然如果你使用gin 等三方框架默认情况下是不会进行注册到路由表中的,除非你显示注册。

    一个用go的无名小卒

    完~

    相关文章

      网友评论

          本文标题:golang expvar的坑

          本文链接:https://www.haomeiwen.com/subject/zjtxvctx.html