一个关于goroutine
的坑,与解决它的故事…
坑的起源
这项目是公司缺人所以我来接手整一下前端,然后在测试一个地图页面的时候感觉到明显的延迟,原本以为是d3的svg地图渲染慢,正想着要不要换成canvas来加快渲染,然后我打开了开发者工具,发现这个接口整整需要4s来获取,这可是本地测试环境啊,这要是上线来整的话那不是凉凉?逐打开项目代码查看,这个接口程序非常简单,代码如下:
1 | for _, pro := range prolist { |
看了看,这不行啊,有点点拖,然后下手改造。
开始挖坑
1 |
|
使用waitgroup
与 goroutine
进行 一个小小的改造,应该就这样吧,没问题的,不测试了,跑起来,草,127ms ,指数级增长的快感,地图瞬间渲染完成,这感觉,太爽了,正当着想着和同事吹吹,不经意间把鼠标移到地图上,发现所有的附加数据都是同一个数字,所有城市都是同一个名字,我心一惊,凉了 ,赶紧回滚回滚测试环境。
埋坑
主要问题在于主进程与gorouite进程的通讯如果不通过chanel的话,只有第一个参数复制了进去,所以接下来的所有操作都是用同一个参数进行操作。埋坑方法如下。
1 | proChan := make(chan AreaList,len(prolist)) |
这样就可以实现主进程与goroutine
的通信。go run .
测试,没问题,add , commit ,push, merge 一梭子上线测试环境,没问题,终于舒服了。
在改造其他有同样情况的接口时,我发现有defer
和没有 , 速度也是有区别的,想起之前看过的一篇文章 ,defer
在使用的时候的确会有延迟,总的来说就是靠效率来换取recover
的安全…
然后又看到一篇煎鱼大大的文章 ,文章说go1.13的defer效率比以前高了大概30% ,过会升级看看。