点击订阅《云荐大咖》专栏,获取官方推荐优质内容,学技术不迷路!5G远程控制场景对实时音视频传输时延、卡顿率、弱网阻等要求非常高。本文将介绍如何结合5G网络的特点,对音视频通信链路进行联合优化,满足行业场景的远程控制需求,减少画面延迟。在上一篇文章中,我们介绍了模块路径、版本号和兼容原则、伪版本号这三个概念。在下一篇文章中,我们将继续介绍GoModules的核心概念。四:主版本号后缀从主版本号2开始,必须在模块路径中添加一个与主版本号相匹配的后缀,如/v2。例如,如果模块在v1.0.0版本中具有路径example.com/test,则在v2.0.0中它将具有路径example.com/test/v2。主版本号后缀遵循导入兼容规则:如果新包与旧包的导入路径相同,则新包必须向后兼容旧包。根据定义,模块新主要版本中的包不向后兼容先前主要版本中的相应包。因此,从v2开始,包需要一个新的导入路径。这是通过向模块路径添加主要版本后缀来实现的。由于模块路径是模块内每个包的导入路径的前缀,因此将主版本后缀添加到模块路径可为每个不兼容的版本提供不同的导入路径。主要版本v0或v1不允许使用主要版本后缀。v0和v1之间的模块路径不用改,因为v0版本不稳定,没有兼容性保证。此外,对于大多数模块,v1向后兼容最新的v0版本,这只是作为对兼容性的承诺而开始的。这里有一个特殊情况,以gopkg.in/开头的模块路径必须始终具有主要版本后缀,即使对于v0和v1版本也是如此。后缀必须以点而不是斜杠开头(例如,gopkg.in/yaml.v2)。因为在GoModules发布之前,gopkg.in遵循了这个规则。为了让导入到gopkg.in包中的代码能够继续导入编译,Go做了一些兼容性工作。主版本后缀允许模块的多个主版本共存于同一个构建中。这可以很好地解决钻石依赖冲突https://jlbp.dev/what-is-a-di…。通常,如果传递依赖项需要两个不同版本的模块,则将使用较高版本。但是,如果这两个版本不兼容,那么任何一个版本都无法满足所有调用者的需求。由于不兼容的版本肯定有不同的大版本号,大版本后缀有不同的模块路径,所以不存在冲突:不同后缀的模块被认为是独立的模块,它们的包的导入路径也不同。因为很多Go项目在迁移到Go模块之前发布了v2或更高版本,所以没有使用主版本后缀。对于这些版本,Go使用+incompatible构建标志进行注释(例如,v2.0.0+incompatible)。五:将包路径解析为模块路径的过程通常是在使用“goget”时指定包路径而不是模块路径。Go如何找到模块路径?go命令将在主模块(当前模块)的构建列表中搜索哪些模块路径与此包路径的前缀匹配。比如导入的包路径是example.com/a/b,发现example.com/a是一个模块路径,那么就会检查example.com/a在b目录下是否包含这个包,在这个A目录中必须至少有一个go源文件在里面才能被认为是一个有效的包。在此过程中不会应用编译约束(BuildConstraints)。如果在构建列表中确实找到了包含该包的模块,那么将使用该模块。如果没有找到模块提供这个包或者找到两个或多个模块提供这个包,那么go命令会提示错误。但是你可以指定-mod=mod让go命令尝试下载本地找不到的包,并更新go.mod和go.sum。goget和gomodtidy这两个命令会自动执行此操作。当go命令尝试下载新包时,它会返回并检查GOPROXY环境变量,这是一个逗号分隔的URL列表,当然支持direct和off等关键字。proxyURL表示go会使用GOPROXY协议拉取模块,direct表示go需要直接与版本控制系统交互,off表示go不需要与外界交互。另外,GOPRIVATE和GONOPROXY环境变量也可以精细控制go下载代码包的策略。对于GOPROXY列表中的每个项目,go命令返回请求模块路径的每个前缀。对于成功请求的模块,go命令返回并下载最新的模块并检查该块是否包含请求的包。如果多个模块包含请求的包,将选择路径最长的那个。如果找到的模块中不包含该包,则会报错。如果没有找到模块,go命令会尝试GOPROXY列表中的下一个配置项,如果尝试都没有找到模块,就会报错。例如,假设用户要获取包golang.org/x/net/html,而之前配置的GOPROXY为https://corp.example.com,https://goproxy.io。go命令将遵循以下请求序列:Requesttohttps://corp.example.com/(parallel):Requestforlatestversionofgolang.org/x/net/htmlRequestforlatestversionofgolang.org/x/netRequestforlatestversionofgolang.org/xRequestforlatestversionofgolang.org如果上面的https://corp.example.com/失败,返回410或404状态码并发送到https://proxy.golang.org/发起请求:Requestforlatestversionofgolang.org/x/net/htmlRequestforlatestversionofgolang.org/x/netRequestforlatestversionofgolang.org/xRequestforlatestversionofgolang.org当需要的模块是发现后,go命令会将这个依赖模块的路径和对应的版本添加到主模块的go.mod文件中。这样可以保证以后编译模块时使用相同的模块版本,保证编译的可重复性。如果解析后的代码包没有被主模块直接引用,go.mod文件中新增的依赖后会有//间接注释。六:go.mod文件如前所述,模块定义是由一个名为go.mod的UTF-8编码的文本文件定义的。该文件以“行”(面向行)的形式组织。每行都有一个独立的指令,由一个保留关键字和一些参数组成。例如:模块example.com/my/thinggo1.17requireexample.com/other/thingv1.0.2requireexample.com/new/thing/v2v2.3.4excludeexample.com/old/thingv1.2.3replaceexample。/bad/thingv1.4.5=>example.com/good/thingv1.4.5retract[v1.9.0,v1.9.5]开头的关键字可以按行的形式分块,就像dailyimports一样,所以可以改为:require(example.com/new/thing/v2v2.3.4example.com/old/thingv1.2.3)go.mod文件的设计考虑到了开发人员的可读性和机器的易写性。go命令还提供了几个子命令来帮助开发者修改go.mod文件。例如,goget命令可以在需要时更新go.mod文件。gomodedit命令可以对文件做一些低级的修改操作。如果我们有类似的需求,我们可以使用golang.org/x/mod/modfile包以编程方式进行相同的更改。通过这个包,还可以一窥go.mod底层的struct结构://go.mod文件的组成typeFilestruct{Module*Module//ModulepathGo*Go//GoversionRequire[]*Require//依赖模块Exclude[]*Exclude//排除模块Replace[]*Replace//替换模块Retract[]*Retract//撤回模块}//AModule是模块statement.typeModulestruct{Modmodule.VersionDeprecatedstring}//Go是go语句。typeGostruct{Versionstring//"1.23"}//AnExclude是单个排除语句。typeExcludestruct{Modmodule.Version}//AReplace是单个替换语句。typeReplacestruct{Oldmodule.VersionNewmodule.Version}//一个Retract是一个单一的retract语句Modules早期就是这样设计的,那么这个字段的作用是什么?估计很多人不知道,如果我们维护的某个模块的主版本从v1演化到v2,我们不再维护v1版本,希望用户尽量使用v2。通过上面的介绍,我们知道v1和v2是不同的导入路径。“Retract”什么也做不了,这次“Deprecated”就起作用了,看下面的例子://Deprecated:inexample.com/a/b@v1.9.0,最新支持版本为example.com/a/b/v2.moduleexample.com/a/bgo1.17当用户去获取example.com/a/b的版本时,go命令可以感知到这个版本不再维护.将报告给用户:goget-dexample.com/a/b@v1.9.0go:warning:moduleexample.com/deprecated/aisdeprecated:inexample.com/a/b@v1.9.0,the最新支持的版本是example.com/a/b/v2用户可以按照提示拉取v2代码。path,还介绍了版本号和伪版本号,最后简单介绍一下go。Go模块有很大帮助。以上概念在使用Go语言时经常会遇到。了解版本号和伪版本号的区别和设计原则,可以帮助我们理解按照semver标准定义自己的标签有多么重要。同时,遵循GoModules定义的兼容原则,让上下游开发者在社区协作时变得更加友好和高效。下一系列文章将开始了解GoModules中的设计细节,例如go.mod文件的详细解释和配套的gomod子命令等,敬请期待。另外,腾讯云goproxy企业版已经商用,需要了解的同学可以点这里。李宝琨历年推荐精彩文章:Gomodules基础精炼,六大核心概念全解析(上)Gomodules基础精炼,六大核心概念全解析(下)《云荐大咖》是腾讯云+的优质内容专栏社区。云推荐官特邀行业领袖,聚焦前沿技术落地与理论实践,持续为您解读云时代热点技术,探索行业发展新机遇。点击一键订阅,我们会定期为您推送优质内容。
