使用Golang时遇到的一些坑
1、 【致命】不是所有Panic都能捕获
我们知道Golang给开发人员提供recover()机制,对堆栈异常(panic)进行捕获并自定义其处理逻辑。下面举个例子:
构造一个除0的异常场景:

输出结果:

我们看到程序正常退出,没有异常,说明recover()按照预期捕获到panic异常;但不是所有panic都能通过recover()捕捉到的,比如:并发操作map实例。
构造并发操作map的场景:

输出结果:

以上结果可知,我们不能单纯依靠recover()解决函数内部所有panic异常,应该做到以下几点:
a) 通过编写代码校验,防止能预期到的panic,比如:空指针引用的指针判断。
b) 对于无法预期的panic,使用recover()捕获并加以处理。
c) 使用map时,必须要考虑是否存在并发读写场景,存在时,应使用ConcurrentMap组件或自己加sync.RWMutex进行加锁保护。
相关参考:
关于并发读写map导致的panic无法使用recover()捕获,是Go1.6增加的一个特性,https://golang.org/doc/go1.6#runtime;
当然这个并非是唯一一个无法通过recover()捕获的场景,还有可能Go本身的bug,https://github.com/golang/go/issues/21717;这个Bug在Go1.9.2才修复
2、 【严重】小心Map的内存泄露
大部分Golang程序做业务缓存实现时,都使用了map,看以下代码片段,简单模拟了这种使用场景:

增加环境变量GODEBUG=gctrace=1,运行可见,即使代码逻辑清空了map,但进程内存使用并没有像预期那样“实报实销”:

应如何解决:定期替换成新的map,释放旧的map对象。
3、 【提示】不是每次Map遍历都能得到相同排序的集合
经常遇到一些业务场景,需要将map的所有元素打印输出,在Golang里面实现是非常简单的,一个for range就可以实现,但结果却有点出人意料:

输出结果:

两次遍历的结果均不相同,这是为什么呢?这是Golang故意增加的一个随机数导致的,https://blog.golang.org/go-maps-in-action;所以如果对结果一致性有要求的业务逻辑,就不能简单的遍历map了,可以这样实现:

4、 【严重】客户端执行Response.Body.Close()后HTTP连接真的关闭了吗?
按照官方文档对标准库中的http client包的说明,在使用时需要主动调用Response.Body.Close()将连接关闭,但并不说明只要写了这句话就能关闭连接的。看看以下场景:

执行后,统计了下连接数,发现大量TIME_WAIT连接没有按预期回收,看来Response.Body.Close()没生效。

我们把代码调整如下:

再看看连接数统计:

为什么?以上是个较为特殊的场景,业务只关心请求的响应码,并不关心响应体,所以没有加入读取resp.Body的代码。可以看到此时关闭Body读取数据通道,会导致Golang底层没有真正关闭连接。要解决这个这种场景出现的连接泄露问题,需要在Close前额外加入io.Copy(ioutil.Discard, resp.Body),来完成TCP响应体读取流程。
Go语言未来的前景很不错,而在国内的大厂中,华为云对此的支持还是可以的,在其微服务应用平台、微服务引擎中开放了Go语言的服务框架。
目前,华为云有一个关于微服务的活动,有想应用服务微服务化需求的朋友可以考虑试用一下!
https://activity.huaweicloud.com/cse/index.html?dfk
使用Golang时遇到的一些坑的更多相关文章
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(四)——对 run.py 的调整
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能
使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...
- 记一次在node.js中使用crypto的createCipheriv方法进行加密时所遇到的坑
Node.js的crypto模块提供了一组包括对OpenSSL的哈希.HMAC.加密.解密.签名,以及验证等一整套功能的封装.具体的使用方法可以参考这篇文章中的描述:node.js_crypto模块. ...
- 学习Spring5源码时所遇到的坑
学习Spring5源码时所遇到的坑 0)本人下载的源码版本是 spring-framework-5.0.2.RELEASE 配置好gradle环境变量之后,cmd进入到spring项目,执行gradl ...
- 在PyQt5中使用Pandas时的几个坑
最近在看Python GUI编程,在用到PyQt5+Pandas时遇到一些问题.这里把问题和解决方法整理一下.备查. (好像不能上传附件,内容只好写在下面了.) 在PyQt5中使用Pandas时的几个 ...
- golang 学习过程中踩的坑
目录 [他人总结] 首字母大写才是对外可见的 包的初始化函数顺序问题 DB 连接泄漏问题 err 常用写法 goroutine 内的变量 指针可能是 nil 多层 map 未初始化 [他人总结] ht ...
随机推荐
- vue 使用 echart ,自定义样式案例
1.vue 安装 echart 库 npm install echarts --save 2.vue代码 引入 let echarts = require("echarts/lib/echa ...
- CF1195B
CF1195B 题意: 有一个盒子,每次可以做两个操作: 1.每次吃掉一块蛋糕 2.每次放入比上一次放入数多1的蛋糕 当盒子为空时,只能执行第 $ 2 $ 个操作.第 $ 1 $ 次操作永远是放入一个 ...
- SQL-W3School-高级:SQL JOIN
ylbtech-SQL-W3School-高级:SQL JOIN 1.返回顶部 1. SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据. Join 和 Key 有时为了得到完 ...
- OSG Qt Widget加载三维模型
graphicswindowqt.h #ifndef GRAPHICSWINDOWQT_H #define GRAPHICSWINDOWQT_H #include <QGLWidget> ...
- C++ STL partial_sort_copy greater
#include <iostream>#include <deque>#include <algorithm>#include <vector>#inc ...
- linux 测试磁盘iops 方法详解
一.FIO安装 wget http://brick.kernel.dk/snaps/fio-2.0.7.tar.gz yum -y install libaio-devel tar -zxvf ...
- NLP之ROUGE[笔记]
0 前言 [定义]ROUGE:recall-oriented understanding for gisting evaluation,面向召回的要点评估理解 召回率,recall rate;要点,g ...
- iOS-iOS 支付 [支付宝、银联、微信](转)
支付宝iOSsdk官方下载sdk地址:https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId ...
- Python操作qml对象
1. 如何在python里获得qml里的对象? 1.1 获取根对象 QML: import QtQuick 2.12 import QtQuick.Controls 2.12 ApplicationW ...
- Java工程师学习指南第7部分:重新学习MySQL与Redis
本文整理了微信公众号[Java技术江湖]发表和转载过的Mysql和Redis相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧吧. 大白话说说mysql 面试官:给我说说你平时是如何优化M ...