(图片来源网络,侵删)
私信我回复“Go”免费领取资料精心整理了《手撕GO语言》219页免费资料,私信我回复”Go”免费获取网盘链接和提取码Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,它用批判吸收的眼光,融合C语言、Java等众家之长,将简洁、高效演绎得淋漓尽致很多技术爱好者喜欢 Go 语言有以下几个原因:1. 语言本身极其简洁(只有 25 个关键字);2.能轻而易举地实现交叉编译;3.天然支持创建可靠的 HTTP 服务器;从根本上来讲,Go 是一种 boring 的语言,可能这就是为什么可以用它来开发一些诸如 Docker 和 Kubernetes 等很棒的项目,像 Cloudflare 等具有高性能和弹性要求的公司也正在使用它尽管上手很容易,但是有很多细节还是值得关注如果你在不清楚的情况下编写代码,很可能会导致各种稀奇古怪的问题,并且很难发现和纠正错误下面会给大家列举一些常见错误,是在 review 生产代码时发现的希望你再遇到相同问题时能轻松地解决1.HTTP 超时时间HTTP 超时时间,其实在点击已经跟大家讨论过这个问题但仍然值得再提一提,因为好的解决方案总是需要更多的时间思考的使用默认的 HTTP 客户端可以发出 HTTP 请求,为了说明问题,下面是一个使用 GET 请求访问 google.com 的例子:私信我回复“Go”免费获取资料正如文章指出的,默认的 HTTP 客户端没有设置超时时间,这意味着请求有可能会被长时间挂起(ps:具体原因可以查看原文)所以,解决这个问题最好的办法是什么呢?&http.Client{Timeout: time.Minute},给 HTTP 客户端定义一个合理的超时时间你也可以考虑给 HTTP 请求加上 context,这样做有几个好处:有能力取消正在进行的 HTTP 请求;为一些特殊请求指定超时时间;第 2 个好处显得尤为重要,比如你知道有几个请求需要耗时很长时间,超过 1 个小时但是你又不想每个请求都设置这么长的超时时间,你就可以只针对特殊请求设置比较长的超时时间上面的例子中,如果加上 context 代码会像下面这样:私信我回复“Go”免费获取资料请求时间如果超过了超时时间,c.Do() 调用就会返回 DeadlineExceeded 错误,可以很容易地处理错误或者重试2.数据库连接我参与的每一个 Go 项目几乎都会出现数据库连接问题我认为对刚入门 Go 语言的新手来说,有个难以绕过去的点,sql.DB 对象是并发安全的连接池,而不是单个数据库连接这意味着连接使用完之后如果没有返还给进程池,会轻易导致连接数耗尽,甚至最后导致应用程序宕掉例如,数据库连接池包含打开和空闲连接,分别是通过下面这些选项设置的:SetConnMaxLifetime,连接可以重用的最长时间;SetMaxIdleConns,最大的空闲连接数量;SetMaxOpenConns,最大的打开连接数量;需要注意的是,即使你的最大打开连接数设置成 200,如果连接使用完不返还连接池,应用程序也有可能会耗尽数据库能接受的最大连接数,最后导致宕机、重启服务你需要检查数据库设置,以确保正确设置了这些参数如果数据库没有设置这些参数,应用程序将轻而易举地耗尽数据库能接受的连接数让我们回到进程池的问题上,查询数据库之后,很多开发人员会忘记关闭 sql.Rows 对象,这就会导致超出最大连接数限制,并导致死锁或者高延迟下面给大家展示下类似的代码片段:私信我回复“Go”免费获取资料相信你也注意到,正如能在 HTTP 请求上添加 context 一样,我们也可以在数据库查询时添加超时时间的 context这没什么问题正如上面讨论的,我们需要关闭 rows 对象将连接返还给进程池,防止连接数超出私信我回复“Go”免费获取资料如果在函数或者包之间传递数据库连接,尤其难以发现这一点3.goroutine 或者内存泄漏最后一个要讨论的常见问题是 goroutine 泄漏,一般这个问题难以发现,但通常是由开发人员的错误引起的使用 channel 时通常会发生这种问题,比如:私信我回复“Go”免费获取资料如果我们不关闭通道 c 或者 someFunc() 不返回错误,我们初始化的 goroutine 将会挂起直到程序终止我们不可能找出每一个导致 goroutine 泄漏的 地方,我通常采用两种方法来检测和消除它们第一种方法是在单元测试方法里使用探测器,比如使用 Uber 开源的 goleak 库,就像下面这个例子一样:私信我回复“Go”免费获取资料这段代码就会验证,在代码优美关闭 30s 之后是否还有多余的 goroutine 在运行另一种方法是在应用程序的运行实例上使用 Go profiler,并查看存活的 goroutine 数量其中一种方法就是使用 net/http/pprof 库,并查看生成的火焰图就像下面这样使用它:私信我回复“Go”免费获取资料上面这段代码,pprof 占用 6060 端口,对于特别严重的泄漏,如果你刷新将会看到协程数量在增多;对于更多的一些微小泄漏问题,则需要查看 profile 发现具体的问题,profile 页面就像下面这样:私信我回复“Go”免费获取资料如果你的应用程序是空闲的,但是你又看见大数据量的 goroutine,这说明程序已经有问题了确认泄漏位置之后,我仍然建议在单元测试中使用探测器,以确保解决问题总结希望上面讨论的这些常见错误,如果以后你也遇到,可以帮助你更快地识别并完美地解决问题
0 评论