我们刚才列出来的两个问题,全都在这一段代率攀琅绫擎了。第一个变量感化域,第二个 chan 操作。这几十行代率攀里,哪一个变量感化域存在问题?右上角的 reqBytes 的变量,我们看到前面在 for 轮回外面定义了一个 reqBytes,接下来进入到轮回中,每一次读到的器械都放到 reqBytes,我们可以看到,其实每次轮回,应用的 reqBytes 是一个变量,它的内存空间是一个。那么问题来了, goroutine 开启方法是一个必包的方法, 外面的变量对于每个子 goroutine 来说是可见的,也就是每读到一条消息,放到同样一个变量琅绫擎,有可能的结不雅是,第一个消息开了一个 goro u tine,但这个 goroutine 还没来得及调剂的时刻,又收到到第二个消息,那么第二个消息会把第一个 goroutine 琅绫擎的消息覆盖,不合请求之间会产生接洽关系影响。
第二个 chan 操作问题。我们知道在写 chan 的时刻,如不雅 chan 已经被关了,那么对它进行写入操作会 panic。我们看图9中的 writeMsgQueue 这个 chan ,在 defer 琅绫擎进行了封闭。当这个 TCP 连接弗采取的时刻, handleConnection 函数 return 之前封闭这个 chan,目标是 chan 封闭后,经由过程检查 chan 状况,可以促使 goroutine 退出,避免 goroutine 泄漏,然则这个 defer 的 close 惹人了另一个问题,如不雅办事端收到消息、开 goroutine 进行营业处理的过程中,客户端已经断开了连接,那么此时 chan 已经封闭了,当办事端营业处理完成的时刻,写入一个已封闭的 chan ,就会panic。更恐怖的是,这个 panic 是不克不及被 TcpRecoverWrap 包装的,因为在履行 defer 停止、封闭了chan 之后,handleConnection 函数就已经 return,也就是这个 panic 是产生在另一个 goroutine 的,和 handleConnection 函数没有关系,很显然刚才的包装方法是没有办法捕获如许的 panic 进行 recover 的。
图 10
今天禀享的内容大年夜概就是这些,那么怎么修这些问题呢?很简单,变量感化域拿到 for 轮回琅绫擎,panic 的问题可以加别的一个 tcp 封闭旌旗灯号,经由过程如许的方法,来修复刚才说的两个问题。当然修复方法可能有很多种,仅供大年夜家参考。
推荐阅读
MongoDB 是今朝主流的 NoSQL 数据库之一,与关系型数据库和其它的 NoSQL 不合,MongoDB 应用了面向文档的数据存储方法,将数据以类似 JSON 的方法存储在磁盘上,因为项目上的一些汗青遗留>>>详细阅读
本文标题:Go语言在扫码支付系统中的成功实践
地址:http://www.17bianji.com/lsqh/37234.html
1/2 1