从 rsc 力排众议设计并将 go mod 集成在 Go 语言中,已经两年过去了,时至今日,广大 Gopher 还是经常被 go mod 相关的问题折磨。
本文会列举一些我和我的同事使用 go mod 时碰到的问题,有些问题是 go mod 本身的问题,有些可能是第三方 goproxy 实现的问题。
如果你做过比较大型的 go 项目开发,相信总会有那么几个让你会心一笑。
Go 命令的副作用
Go 社区之父早期提到过 less is more [https://en.wikipedia.org/wiki/Less_is_more]
的哲学,可惜社区里有不少人被带偏了。
每次 Go 增加语法上的新特性、新功能,就会有原教旨主义者跳出来扔出一句 less is more(或者也可能是大道至简),扬长而去,留下风中凌乱的你。
即使到了官方已经确定要增加泛型功能的 2020 年,依然有人煞有介事地写文章说为什么 go doesn't need
当前互联网公司的后端架构都是微服务化的,服务彼此使用 RPC 通信,与业务无关的功能部分会从业务代码中抽离为框架。
框架提供了基础的 RPC 功能,同时需要对稳定性负责,一个微服务框架包含但不限于以下功能:
* 路由
* 限流
* 熔断
* 负载均衡
* 服务注册与发现
* tracing
* 链路加密
这些功能看起来也是通用且稳定,所以我们对一个框架的印象往往是成型了之后便很少再升级了。但是云原生时代将我们的假设击得粉碎。底层基础设施也开始迅速发生变化,例如:
* 物理机集群 -> k8s 集群,破坏了我们的服务实例 ip 不会变的假设
* 基础设施给服务的资源分配方式发生变化,超卖使以往未经审慎设计的代码在恶劣环境下更易崩溃
* 服务数量的爆炸式增长使每个内部的微服务都要面对 C10k
先来看一个 demo:
1 package main
2
3 import (
4 "fmt"
5 "net"
6 "os"
7 "runtime"
8 )
9
10 var rawFileList []*os.File
11
12 func main() {
13 l, err := net.Listen("tcp"
1.14 defer
正常处理流程
在 Go 1.14 中,增加了一种新的 defer 实现:open coded defer。当函数内 defer 不超过 8 个时,则会使用这种实现。
形如下面这样的代码:
defer f1(a)
if cond {
defer f2(b)
}
body...
会被翻译为:
deferBits