2. 依赖管理
2.1 依赖管理
GOPATH -> GO Vender -> Go Module
2.1.1 GOPATH
问题:无法实现package的多版本控制(同一package只能存在一个版本)
2.1.2 GO Vendor
优先从vender目录获取,然后再GOPATH
问题:无法控制依赖的版本,可能出现依赖冲突
2.1.3 Go Module
通过go.mod文件管理依赖包版本;通过go get、go mod指令管理依赖包
可以定义版本规则,管理项目依赖关系
国内Go Module环境配置
# 启用 Go Modules 功能
export GO111MODULE=on
# 配置 GOPROXY 环境变量
export GOPROXY=https://goproxy.io
2.2 依赖管理的要素
2.2.1 依赖配置
go.mod
依赖标识
[Path] [Version/Pseudo-Version]
-
//indirect没有直接依赖 -
主版本2+的模块增加
/vN的后缀(eg.lib5/v3)没有go.mod文件且主版本2+的依赖添加
+incompatible -
语义化版本
major:大版本,版本隔离minor:函数功能,兼容patch:修复 -
基于commit的伪版本
前缀-时间戳-hash码
-
编译选择最低的兼容版本:
项目C最终使用v1.4(v1.3与v1.4兼容,1.4是兼容版本,1.3不是.没有1.5,1.4最低),而不会AB分别编译版本
-
其他
-
replace k8s.io/api => k8s.io/api v0.0.0-20190918155943-95b840bb6a1f用于将一个模块版本替换成另一个模块版本,前提是当前模块为主模块时replace ecm-sdk-go => ./vendor/go-util也可以用于引入本地的其他模块到当前这个模块中 -
当前项目中禁止依赖包列表
exclude ( github.com/go-git/go-git/v5 v5.1.0 )
-
2.2.2依赖分发
-
Poxy开源代理工具 环境变量GOPROXY="Proxy1,Proxy1,...,direct":Proxy1->Proxy2->...->direct -
工具-
go get- go get packageName:安装依赖
- go get -u packageName:将依赖升级到最新的次要版本或修订版本
- go get -u=patch packageName:将依赖升级到最新的修订版本
- go get package@version:升级到指定的版本
-
工具-
go mod- go mod tidy:添加丢失的依赖,删除不用的依赖
- go mod download:下载go.mod中的依赖到本地缓存,目前所有模块版本数据均缓存在
GOPATH/pkg/mod和 GOPATH/pkg/sum下,也可以指定cache位置 - go mod graph:显示模块依赖图
- go mod vendor:复制依赖到vendor目录下
- go mod verify:根据go.sum文件校验依赖
- go mod why:解释为什么要依赖
- go list m -json all:依赖详情
- go list m -versions github.com/gin-gonic/gin:查看gin所有的历史版本
- go mod edit -require="github.com/gin-gonic/gin@v1.3.0:更换依赖版本,执行完之后要执行:go mod tidy,也可以直接改go.mod文件
- go clean -modcache:清理所有已经缓存的模块版本数据
3. 测试
回归测试:人工或自动化执行测试用例,黑盒自动化手工 集成测试:构造一个在设计中所描述的程序结构进行测试,白盒黑盒自动化静态 单元测试:单元模块接口测试,白盒自动化静态
3.1 单元测试
-
测试文件以_test.go结尾
-
func Test_nm_(t *testing.T),初始化逻辑Testmain
-
go test [flags][packages]assert.Equal(t,expectOutput,output) -
覆盖率 - 运行的代码占比
3.2 mock
测试依赖本地文件,丢失改动则无法使用 -> mock:稳定、幂等 幂等:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致。 打桩:通过“虚拟”代码替换掉依赖的方法和资源
3.3 基准测试
性能测试 func Benchmark_nm_(b *testing.B)
并发调用-并行测试 func BenchmarkParallel_nm_(b *testing.B)
4. 实战-社区话题页面
4.1 需求
4.2 ER图(实体关系图)
需要的实体:话题Topic 帖子Post
4.3 分层结构
4.4 组件工具
Gin 高性能Go Web框架
Go Mod go mod go get xx/gin
4.5 查询-index
数据索引-map
TopicDao-Data Access Objects
sync.Once高并发下保证行为只会被执行一次。func (o *Once) Do(f func())只有第一次调用生效
4.6 service
实体:PageInfo{Topic PostList}
参数校验->准备数据->组装实体
Topic与Post没有依赖关系,可以并行
4.7 router
r.GET("/community/page/get/:id", func(c *gin.Context) { //构建路由
topicId := c.Param("id")
data := handler.QueryPageInfo(topicId)
c.JSON(200, data)
})