获得徽章 0
为什么要引用单元测试类
传统方法的缺点分析
不方便,我们需要在main函数中去调用,这样就需要去修改main函数,如果现在项目正在运行,就可能去停止项目
不利于管理,因为当我们测试多个函数或者多个模块时,都需要写在main函数,不利于我们管理和清晰我们的思路
单元测试基本介绍
Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试,testing框架和其他语言中的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例
优点
确保每个函数是可运行,并且运行结果是正确的
确保写出来的代码性能是好的
单元测试能及时的发现程序设计或实现的逻辑错误,使问题及早暴露,便于问题的定位解决,而性能测试的重点在于发现程序设计的一些问题,让程序能够在高并发的情况下还能保持稳定
Testing规范
测试用例文件名必须以 _test.go结尾
测试用例函数必须以Test开头,一般来说就是Test+被测试的函数名
测试用例函数的形参类型必须是*testing.T
一个测试用例文件中,可以由多个测试用例函数
当出现错误使,可以使用t.Fatalf来格式化输出错误信息,并退出程序
t.Logf方法可以输出相应的日志
测试用例函数,并没有放在main函数中,但是却执行了main函数 在这里插入图片描述
pass表示测试用例运行成功,Fail表示测试用例运行失败
测试单个文件,一个要带上被测试的源文件
go test -v cal_test.go cal.go
传统方法的缺点分析
不方便,我们需要在main函数中去调用,这样就需要去修改main函数,如果现在项目正在运行,就可能去停止项目
不利于管理,因为当我们测试多个函数或者多个模块时,都需要写在main函数,不利于我们管理和清晰我们的思路
单元测试基本介绍
Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试,testing框架和其他语言中的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例
优点
确保每个函数是可运行,并且运行结果是正确的
确保写出来的代码性能是好的
单元测试能及时的发现程序设计或实现的逻辑错误,使问题及早暴露,便于问题的定位解决,而性能测试的重点在于发现程序设计的一些问题,让程序能够在高并发的情况下还能保持稳定
Testing规范
测试用例文件名必须以 _test.go结尾
测试用例函数必须以Test开头,一般来说就是Test+被测试的函数名
测试用例函数的形参类型必须是*testing.T
一个测试用例文件中,可以由多个测试用例函数
当出现错误使,可以使用t.Fatalf来格式化输出错误信息,并退出程序
t.Logf方法可以输出相应的日志
测试用例函数,并没有放在main函数中,但是却执行了main函数 在这里插入图片描述
pass表示测试用例运行成功,Fail表示测试用例运行失败
测试单个文件,一个要带上被测试的源文件
go test -v cal_test.go cal.go
展开
评论
点赞
Mutex 特性
Mutex 就是一把互斥锁,可以想象成一个令牌,有且只有这一个令牌,只有持有令牌的 goroutine 才能进入房间(临界区),在房间内执行完任务后,走出房间并把令牌交出来,如果还有其余的 goroutine 等着获取这个令牌,让他们再去抢这个令牌,抢到的重复上述过程,没抢到的继续等。
上述是从宏观角度来看待互斥锁的,但是在 Mutex 内部,有着非常复杂的抢锁逻辑,Mutex 的发展也经历了几个版本,我们可以用拿令牌进餐厅吃饭来形象比喻下几个主要版本的变化。
前提:餐厅一次只能进入一个人,餐厅有一个令牌,只有持有这个令牌的人才能进去;从餐厅出来后,需要把这个令牌归还
版本一
餐厅在门外设置了一个队伍,如果令牌空闲,拿着令牌去餐厅用餐;如果令牌不是空闲的,新来的人就要去队伍后面排队等待叫号。(不是空闲包含两种情况:持有令牌的人在餐厅里面,队伍是空的;队伍有人排队。)
此版本的问题就是:只要令牌不是空闲的,新来的人必须直接去排队,没有商量的余地。这样看起来很公平,遵循先来后到的原则,但是对于餐厅来说,营业效率就会有所降低,即单位时间内接待顾客的数量(IO)会减少。为什么这样说呢,举个例子,有个顾客从餐厅出来归还令牌后,需要去等待队列去叫号,被叫到号的这个人需要花费时间走到餐厅(获取到CPU),这中间就浪费了不少时间。
版本二
为了提高营业效率,允许刚到门口的顾客和被叫到号的顾客一起去抢令牌,而不是直接去排队,这样就给了新人机会。举个例子:当持有令牌的人从餐厅出来归还令牌后,去等待队列叫个号,如果此时有顾客刚到门口,被叫到号的和新到的顾客一起抢令牌,抢到的就可以直接进入餐厅,抢不到的接着去排队,由于刚到的顾客离门口近(正在占据CPU),被叫到号的顾客离得远(需要等CPU),而且刚到的顾客可能不只一个,所以被叫到号的顾客很大概率抢不到令牌,可能还没走到门口(还没获取到CPU)就被新来的顾客抢走了。不管怎么样,这样提高了餐厅的效率,可以在单位时间内接待更多的客户。
版本三
餐厅发现有些人用餐很快,如果让抢不到令牌的先别直接去排队,而是在门口转悠会(当然不能一直转悠,有条件限制,到了限制还是要去排队),这种方式类似乐观锁,那么有顾客从餐厅出来后,就不用去叫号了,直接让门口的这些顾客继续抢就行了,这样就进一步提高了餐厅的运行
Mutex 就是一把互斥锁,可以想象成一个令牌,有且只有这一个令牌,只有持有令牌的 goroutine 才能进入房间(临界区),在房间内执行完任务后,走出房间并把令牌交出来,如果还有其余的 goroutine 等着获取这个令牌,让他们再去抢这个令牌,抢到的重复上述过程,没抢到的继续等。
上述是从宏观角度来看待互斥锁的,但是在 Mutex 内部,有着非常复杂的抢锁逻辑,Mutex 的发展也经历了几个版本,我们可以用拿令牌进餐厅吃饭来形象比喻下几个主要版本的变化。
前提:餐厅一次只能进入一个人,餐厅有一个令牌,只有持有这个令牌的人才能进去;从餐厅出来后,需要把这个令牌归还
版本一
餐厅在门外设置了一个队伍,如果令牌空闲,拿着令牌去餐厅用餐;如果令牌不是空闲的,新来的人就要去队伍后面排队等待叫号。(不是空闲包含两种情况:持有令牌的人在餐厅里面,队伍是空的;队伍有人排队。)
此版本的问题就是:只要令牌不是空闲的,新来的人必须直接去排队,没有商量的余地。这样看起来很公平,遵循先来后到的原则,但是对于餐厅来说,营业效率就会有所降低,即单位时间内接待顾客的数量(IO)会减少。为什么这样说呢,举个例子,有个顾客从餐厅出来归还令牌后,需要去等待队列去叫号,被叫到号的这个人需要花费时间走到餐厅(获取到CPU),这中间就浪费了不少时间。
版本二
为了提高营业效率,允许刚到门口的顾客和被叫到号的顾客一起去抢令牌,而不是直接去排队,这样就给了新人机会。举个例子:当持有令牌的人从餐厅出来归还令牌后,去等待队列叫个号,如果此时有顾客刚到门口,被叫到号的和新到的顾客一起抢令牌,抢到的就可以直接进入餐厅,抢不到的接着去排队,由于刚到的顾客离门口近(正在占据CPU),被叫到号的顾客离得远(需要等CPU),而且刚到的顾客可能不只一个,所以被叫到号的顾客很大概率抢不到令牌,可能还没走到门口(还没获取到CPU)就被新来的顾客抢走了。不管怎么样,这样提高了餐厅的效率,可以在单位时间内接待更多的客户。
版本三
餐厅发现有些人用餐很快,如果让抢不到令牌的先别直接去排队,而是在门口转悠会(当然不能一直转悠,有条件限制,到了限制还是要去排队),这种方式类似乐观锁,那么有顾客从餐厅出来后,就不用去叫号了,直接让门口的这些顾客继续抢就行了,这样就进一步提高了餐厅的运行
展开
评论
点赞
单元测试基本介绍
Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试,testing框架和其他语言中的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例
优点
确保每个函数是可运行,并且运行结果是正确的
确保写出来的代码性能是好的
单元测试能及时的发现程序设计或实现的逻辑错误,使问题及早暴露,便于问题的定位解决,而性能测试的重点在于发现程序设计的一些问题,让程序能够在高并发的情况下还能保持稳定
Testing规范
测试用例文件名必须以 _test.go结尾
测试用例函数必须以Test开头,一般来说就是Test+被测试的函数名
测试用例函数的形参类型必须是*testing.T
一个测试用例文件中,可以由多个测试用例函数
当出现错误使,可以使用t.Fatalf来格式化输出错误信息,并退出程序
t.Logf方法可以输出相应的日志
测试用例函数,并没有放在main函数中,但是却执行了main函数 在这里插入图片描述
pass表示测试用例运行成功,Fail表示测试用例运行失败
测试单个文件,一个要带上被测试的源文件
go test -v cal_test.go cal.go
Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试,testing框架和其他语言中的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例
优点
确保每个函数是可运行,并且运行结果是正确的
确保写出来的代码性能是好的
单元测试能及时的发现程序设计或实现的逻辑错误,使问题及早暴露,便于问题的定位解决,而性能测试的重点在于发现程序设计的一些问题,让程序能够在高并发的情况下还能保持稳定
Testing规范
测试用例文件名必须以 _test.go结尾
测试用例函数必须以Test开头,一般来说就是Test+被测试的函数名
测试用例函数的形参类型必须是*testing.T
一个测试用例文件中,可以由多个测试用例函数
当出现错误使,可以使用t.Fatalf来格式化输出错误信息,并退出程序
t.Logf方法可以输出相应的日志
测试用例函数,并没有放在main函数中,但是却执行了main函数 在这里插入图片描述
pass表示测试用例运行成功,Fail表示测试用例运行失败
测试单个文件,一个要带上被测试的源文件
go test -v cal_test.go cal.go
展开
评论
点赞
安装Go库db2struct时,使用go get命令执行
go get ``github.com/Shelnutt2/db2struct/cmd/db2struct,
执行db2struct -h报错:
zsh: command not found: db2struct
改为go install命令执行
go install ``github.com/Shelnutt2/db2struct/cmd/db2struct
后成功执行db2struct -h,同时ls $GOPATH/bin也看到了可执行文件db2struct。
二、原因探究
(一)命令定义和区别
go install 和 go get 都是 Go 语言的工具命令,但它们之间有一些区别。
go get:用于从远程代码存储库(如 GitHub)中下载或更新 Go 代码包。它会下载代码包并将其存储在 $GOPATH/src 目录下对应的位置,并编译代码包中的程序和库。如果目标包之前已经被下载过了,那么 go get 会尝试更新到最新版本,并重新编译程序和库文件。在更新完代码包后,go get 还会自动把下载的代码包的可执行文件复制到 $GOPATH/bin 目录下,以方便直接使用该可执行文件。
go install:用于编译并安装 Go 代码包,并将其生成的可执行程序或库文件存储到 $GOPATH/bin 或者 $GOPATH/pkg 目录下。如果你在项目目录下执行 go install,它将会编译并安装当前项目的代码,生成可执行文件并将其保存到 $GOPATH/bin 目录下(如果项目是一个库,则生成的是 .a 文件,并将其存储到 $GOPATH/pkg 目录下)。
因此,go get 用于下载和更新代码包,并产生对应的可执行程序,而 go install 用于将一个 Go 代码包转化为可执行程序或库文件,并安装到系统路径以供直接使用。
go get ``github.com/Shelnutt2/db2struct/cmd/db2struct,
执行db2struct -h报错:
zsh: command not found: db2struct
改为go install命令执行
go install ``github.com/Shelnutt2/db2struct/cmd/db2struct
后成功执行db2struct -h,同时ls $GOPATH/bin也看到了可执行文件db2struct。
二、原因探究
(一)命令定义和区别
go install 和 go get 都是 Go 语言的工具命令,但它们之间有一些区别。
go get:用于从远程代码存储库(如 GitHub)中下载或更新 Go 代码包。它会下载代码包并将其存储在 $GOPATH/src 目录下对应的位置,并编译代码包中的程序和库。如果目标包之前已经被下载过了,那么 go get 会尝试更新到最新版本,并重新编译程序和库文件。在更新完代码包后,go get 还会自动把下载的代码包的可执行文件复制到 $GOPATH/bin 目录下,以方便直接使用该可执行文件。
go install:用于编译并安装 Go 代码包,并将其生成的可执行程序或库文件存储到 $GOPATH/bin 或者 $GOPATH/pkg 目录下。如果你在项目目录下执行 go install,它将会编译并安装当前项目的代码,生成可执行文件并将其保存到 $GOPATH/bin 目录下(如果项目是一个库,则生成的是 .a 文件,并将其存储到 $GOPATH/pkg 目录下)。
因此,go get 用于下载和更新代码包,并产生对应的可执行程序,而 go install 用于将一个 Go 代码包转化为可执行程序或库文件,并安装到系统路径以供直接使用。
展开
评论
点赞
Go Vendor简介
govendor 是一个基于 vendor 目录机制的包管理工具。
最开始的时候,Go 并没有提供较为妥当的包管理工具。从 1.5 版本开始提供了 vendor 特性,但需要手动设置环境变量 GO15VENDOREXPERIMENT=1。在执行 go build 或 go run 命令时,会按照以下顺序去查找包:
在当前vendor目录(如果当前目录存在vendor目录的话)查找依赖包;
如果当前目录不存在vendor目录,则到上一级目录继续查找;
重复步骤2,直到到达$GOPATH/src目录,查找vendor目录中是否存在依赖包;
如何没有查找到依赖包,则继续在$GOROOT目录查找;
如果没有查找到,则继续在$GOPATH/src目录查找。
在发布 1.6 版本时,该环境变量的值已经默认设置为 1 了,该值可以使用 go env 命令查看。在发布 1.7 版本时,已去掉该环境变量,默认开启 vendor 特性。
govendor 功能
支持从项目源码中分析出依赖的包,并从 $GOPATH 复制到项目的 vendor 目录下;
支持包的指定版本,并用 vendor/vendor.json 进行包和版本管理;
支持用 govendor add/update 命令从 $GOPATH 中复制依赖包;
如果忽略了 vendor/*/ 文件,可用 govendor sync 恢复依赖包;
可直接用 govendor fetch 添加或更新依赖包;
可用 govendor migrate 从其他 vendor 包管理工具中一键迁移到 govendor;
支持 Linux,macOS,Windows,甚至现有所有操作系统;
支持 Git、Hg、SVN,BZR(必须指定一个路径);
govendor 是一个基于 vendor 目录机制的包管理工具。
最开始的时候,Go 并没有提供较为妥当的包管理工具。从 1.5 版本开始提供了 vendor 特性,但需要手动设置环境变量 GO15VENDOREXPERIMENT=1。在执行 go build 或 go run 命令时,会按照以下顺序去查找包:
在当前vendor目录(如果当前目录存在vendor目录的话)查找依赖包;
如果当前目录不存在vendor目录,则到上一级目录继续查找;
重复步骤2,直到到达$GOPATH/src目录,查找vendor目录中是否存在依赖包;
如何没有查找到依赖包,则继续在$GOROOT目录查找;
如果没有查找到,则继续在$GOPATH/src目录查找。
在发布 1.6 版本时,该环境变量的值已经默认设置为 1 了,该值可以使用 go env 命令查看。在发布 1.7 版本时,已去掉该环境变量,默认开启 vendor 特性。
govendor 功能
支持从项目源码中分析出依赖的包,并从 $GOPATH 复制到项目的 vendor 目录下;
支持包的指定版本,并用 vendor/vendor.json 进行包和版本管理;
支持用 govendor add/update 命令从 $GOPATH 中复制依赖包;
如果忽略了 vendor/*/ 文件,可用 govendor sync 恢复依赖包;
可直接用 govendor fetch 添加或更新依赖包;
可用 govendor migrate 从其他 vendor 包管理工具中一键迁移到 govendor;
支持 Linux,macOS,Windows,甚至现有所有操作系统;
支持 Git、Hg、SVN,BZR(必须指定一个路径);
展开
评论
点赞
Go Modules是Go 语言从 1.11 版本之后官方推出的版本管理工具。Modules官方定义为:
模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。
使用modules依赖管理的好处是非常明显的:
自动下载依赖包
不需要将代码再放入$GOPATH/src
所有来自第三方的包都会指定版本(使用dep是无法指定第三方包的版本的)
对于已经转移的包,可以用replace在go.mod文件中替换,不需要修改代码
如何使用Modules
把 golang 升级到 1.11+ (现在已经到1.19了)
设置 GO111MODULE
GO111MODULE
GO111MODULE 有三个值:off, on和auto(默认值)。
GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
当前目录在$GOPATH/src之外且该目录包含go.mod文件
当前文件在包含go.mod文件的目录下面。
当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。
注:使用go modules最好搭配go proxy一起使用,否则在go get一些包时会出现get不到的问题
模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。
使用modules依赖管理的好处是非常明显的:
自动下载依赖包
不需要将代码再放入$GOPATH/src
所有来自第三方的包都会指定版本(使用dep是无法指定第三方包的版本的)
对于已经转移的包,可以用replace在go.mod文件中替换,不需要修改代码
如何使用Modules
把 golang 升级到 1.11+ (现在已经到1.19了)
设置 GO111MODULE
GO111MODULE
GO111MODULE 有三个值:off, on和auto(默认值)。
GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
当前目录在$GOPATH/src之外且该目录包含go.mod文件
当前文件在包含go.mod文件的目录下面。
当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。
注:使用go modules最好搭配go proxy一起使用,否则在go get一些包时会出现get不到的问题
展开
评论
点赞
Goroutines 是 Go 语言主要的并发原语。它看起来非常像线程,但是相比于线程它的创建和管理成本很低。Go 在运行时将 goroutine 有效地调度到真实的线程上,以避免浪费资源,因此您可以轻松地创建大量的 goroutine(例如每个请求一个 goroutine),并且您可以编写简单的,命令式的阻塞代码。因此,Go 的网络代码往往比其它语言中的等效代码更直接,更容易理解(这点从下文中的示例代码可以看出)。
对我来说,goroutine 是将 Go 这门语言与其它语言区分开来的一个主要特征。这就是为什么大家更喜欢用 Go 来编写需要并发的代码。在下面讨论更多关于 goroutine 之前,我们先了解一些历史,这样你就能理解为什么你想要它们了。
基于 fork 和线程
fork_thread.jpeg
高性能服务器需要同时处理来自多个客户端的请求。有很多方法可以设计一个服务端架构来处理这个问题。最容易想到的就是让一个主进程在循环中调用 accept,然后调用 fork 来创建一个处理请求的子进程。这篇 Beej's Guide to Network Programming 指南中提到了这种方式。
在网络编程中,fork 是一个很好的模式,因为你可以专注于网络而不是服务器架构。但是它很难按照这种模式编写出一个高效的服务器,现在应该没有人在实践中使用这种方式了。
fork 同时也存在很多问题,首先第一个是成本: Linux 上的 fork 调用看起来很快,但它会将你所有的内存标记为 copy-on-write。每次写入 copy-on-write 页面都会导致一个小的页面错误,这是一个很难测量的小延迟,进程之间的上下文切换也很昂贵。
另一个问题是规模: 很难在大量子进程中协调共享资源(如 CPU、内存、数据库连接等)的使用。如果流量激增,并且创建了太多进程,那么它们将相互争夺 CPU。但是如果限制创建的进程数量,那么在 CPU 空闲时,大量缓慢的客户端可能会阻塞每个人的正常使用,这时使用超时机制会有所帮助(无论服务器架构如何,超时设置都是很必要的)。
对我来说,goroutine 是将 Go 这门语言与其它语言区分开来的一个主要特征。这就是为什么大家更喜欢用 Go 来编写需要并发的代码。在下面讨论更多关于 goroutine 之前,我们先了解一些历史,这样你就能理解为什么你想要它们了。
基于 fork 和线程
fork_thread.jpeg
高性能服务器需要同时处理来自多个客户端的请求。有很多方法可以设计一个服务端架构来处理这个问题。最容易想到的就是让一个主进程在循环中调用 accept,然后调用 fork 来创建一个处理请求的子进程。这篇 Beej's Guide to Network Programming 指南中提到了这种方式。
在网络编程中,fork 是一个很好的模式,因为你可以专注于网络而不是服务器架构。但是它很难按照这种模式编写出一个高效的服务器,现在应该没有人在实践中使用这种方式了。
fork 同时也存在很多问题,首先第一个是成本: Linux 上的 fork 调用看起来很快,但它会将你所有的内存标记为 copy-on-write。每次写入 copy-on-write 页面都会导致一个小的页面错误,这是一个很难测量的小延迟,进程之间的上下文切换也很昂贵。
另一个问题是规模: 很难在大量子进程中协调共享资源(如 CPU、内存、数据库连接等)的使用。如果流量激增,并且创建了太多进程,那么它们将相互争夺 CPU。但是如果限制创建的进程数量,那么在 CPU 空闲时,大量缓慢的客户端可能会阻塞每个人的正常使用,这时使用超时机制会有所帮助(无论服务器架构如何,超时设置都是很必要的)。
展开
评论
点赞
Go 为了实现更高的并发,自己实现了用户态的调度器,称之为 GMP 模型,在上一篇文章中,我们已经简单分析了它的实现。由于自己实现了 goroutine 的调度器,这也会让代码的执行过程更加复杂。而代码在执行的过程中,有可能会出现性能问题,单纯的通过日志很难排查,这就需要其他的方式来辅助。
Go 提供了一些工具,可以在代码运行的过程中采集一些信息,并且可以根据这些信息去生成可视化的图表,然后更方便排查问题。这些工具 Go 原生就提供了,不需要再引入其他的库。
在对程序进行分析,特别是对线上问题分析的时候,需要先采集数据,只有采集到数据后才能进行后续的分析,所以这篇文章我们也从两个部分出发,一部分是采集数据,另一部分是如何对采集到的数据进行分析。
1. 采集信息
1.1 pprof
这个工具是 Go 提供监控工具,可以实时采集程序运行过程中的性能数据。在 Go 中,有两个 pprof 的包:
runtime/pprof
net/http/pprof
其中 net/http/pprof 是对 runtime/pprof 进行了封装,提供了 Web 环境的下的访问接口,通常我们使用这个就可以。
Go 提供了一些工具,可以在代码运行的过程中采集一些信息,并且可以根据这些信息去生成可视化的图表,然后更方便排查问题。这些工具 Go 原生就提供了,不需要再引入其他的库。
在对程序进行分析,特别是对线上问题分析的时候,需要先采集数据,只有采集到数据后才能进行后续的分析,所以这篇文章我们也从两个部分出发,一部分是采集数据,另一部分是如何对采集到的数据进行分析。
1. 采集信息
1.1 pprof
这个工具是 Go 提供监控工具,可以实时采集程序运行过程中的性能数据。在 Go 中,有两个 pprof 的包:
runtime/pprof
net/http/pprof
其中 net/http/pprof 是对 runtime/pprof 进行了封装,提供了 Web 环境的下的访问接口,通常我们使用这个就可以。
展开
评论
点赞
snake
一款适合于快速开发业务的Go框架,主要是提供API服务。
技术栈
框架路由使用 gin 路由
中间件使用 gin 框架的中间件
数据库组件 gorm
文档使用 swagger 生成
配置文件解析库 viper
使用 JWT 进行身份鉴权认证
校验器 validator 也是 gin 框架默认的校验器,当前最新是v9版本
任务调度 cron
包管理工具 go module
测试框架 goConvey
CI/CD Github Actions
特性
遵循 RESTful API 设计规范
基于 GIN WEB 框架,提供了丰富的中间件支持(用户认证、跨域、访问日志、请求频率限制、追踪 ID 等)
基于 GORM 的数据库存储
JWT 认证
支持 Swagger 文档(基于swaggo)
使用 make 来管理Go工程
使用 shell(admin.sh) 脚本来管理进程
支持多环境配置
一款适合于快速开发业务的Go框架,主要是提供API服务。
技术栈
框架路由使用 gin 路由
中间件使用 gin 框架的中间件
数据库组件 gorm
文档使用 swagger 生成
配置文件解析库 viper
使用 JWT 进行身份鉴权认证
校验器 validator 也是 gin 框架默认的校验器,当前最新是v9版本
任务调度 cron
包管理工具 go module
测试框架 goConvey
CI/CD Github Actions
特性
遵循 RESTful API 设计规范
基于 GIN WEB 框架,提供了丰富的中间件支持(用户认证、跨域、访问日志、请求频率限制、追踪 ID 等)
基于 GORM 的数据库存储
JWT 认证
支持 Swagger 文档(基于swaggo)
使用 make 来管理Go工程
使用 shell(admin.sh) 脚本来管理进程
支持多环境配置
展开
评论
点赞
GoFrame是一款模块化、高性能、企业级的Go基础开发框架。GoFrame不是一款WEB/RPC框架,而是一款通用性的基础开发框架,是Golang标准库的一个增强扩展级,包含通用核心的基础开发组件,优点是实战化、模块化、文档全面、模块丰富、易用性高、通用性强、面向团队。
我的使用体验
官方文档详细介绍了框架特点,我就不赘述了。
下面我以一个使用者和学习者的角度分享一下我的学习体会。
设计思想
设计思想是GoFrame框架的灵魂,同时对于使用者来讲,是不可或缺的内功心法。GoFrame有其独特的设计思想,理解了GoFrame的设计思想,您就理解了GoFrame的全部。
和PHP的Laravel一样,goframe的设计思想非常值得我们学习和借鉴。
我的使用体验
官方文档详细介绍了框架特点,我就不赘述了。
下面我以一个使用者和学习者的角度分享一下我的学习体会。
设计思想
设计思想是GoFrame框架的灵魂,同时对于使用者来讲,是不可或缺的内功心法。GoFrame有其独特的设计思想,理解了GoFrame的设计思想,您就理解了GoFrame的全部。
和PHP的Laravel一样,goframe的设计思想非常值得我们学习和借鉴。
展开
评论
点赞
优化服务器负载对于确保运行在 Kubernetes 上的 Golang 应用程序的高性能和可扩展性至关重要。随着企业越来越多地采用容器化的方式和 Kubernetes 来部署和管理应用程序,采取减少服务器负载的最佳实践势在必行,进而达到最佳的资源利用效率、成本效益并改善用户体验。
运行 Golang 应用程序的多个容器可以放在一个 Kubernetes 集群内,并部署在多个节点上。每个容器可以使用 CPU、内存以及存储等系统资源。如果这些资源没有被高效地管理起来,可能会导致服务器负载不断增加,从而降低性能并增加支出。
因此,针对 Kubernetes 的 Golang 应用优化对于完成有效的资源利用、降低服务器负载以及保证应用在生产环境中顺利运行至关重要。
运行 Golang 应用程序的多个容器可以放在一个 Kubernetes 集群内,并部署在多个节点上。每个容器可以使用 CPU、内存以及存储等系统资源。如果这些资源没有被高效地管理起来,可能会导致服务器负载不断增加,从而降低性能并增加支出。
因此,针对 Kubernetes 的 Golang 应用优化对于完成有效的资源利用、降低服务器负载以及保证应用在生产环境中顺利运行至关重要。
展开
评论
点赞
系统对定位权限的设置会随着时间发生变化,而我们只能拥抱变化!本文是对定位权限设置做个记录,方便以后做系统适配。本篇也会持续更新~。
在iOS 7及以前: 系统设置里面有永不、始终选项。
iOS 8-10:永不、始终选项,如果配置NSLocationWhenInUseUsageDescription 会出现使用应用期间选项.
由于项目中不适配这么低版本系统,所以接下来主要对iOS 11及以上截图记录并且会持续跟踪。
一、iOS 11~12
请求权限的方式:
requestWhenInUseAuthorization(),使用应用期间权限,要求info.plist中配置NSLocationWhenInUseUsageDescription这个key和对应的文案,配置之后,权限弹窗的描述就是这个文案。在‘系统设置’中显示的文案是首先看NSLocationAlwaysAndWhenInUseUsageDescription的文案,没有时才显示NSLocationWhenInUseUsageDescription的文案。
requestAlwaysAuthorization(),总是允许权限,要求info.plist中配置NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription两个key和对应的文案。配置之后,权限弹窗和设置中的文案是NSLocationAlwaysAndWhenInUseUsageDescription的文案。
在iOS 7及以前: 系统设置里面有永不、始终选项。
iOS 8-10:永不、始终选项,如果配置NSLocationWhenInUseUsageDescription 会出现使用应用期间选项.
由于项目中不适配这么低版本系统,所以接下来主要对iOS 11及以上截图记录并且会持续跟踪。
一、iOS 11~12
请求权限的方式:
requestWhenInUseAuthorization(),使用应用期间权限,要求info.plist中配置NSLocationWhenInUseUsageDescription这个key和对应的文案,配置之后,权限弹窗的描述就是这个文案。在‘系统设置’中显示的文案是首先看NSLocationAlwaysAndWhenInUseUsageDescription的文案,没有时才显示NSLocationWhenInUseUsageDescription的文案。
requestAlwaysAuthorization(),总是允许权限,要求info.plist中配置NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription两个key和对应的文案。配置之后,权限弹窗和设置中的文案是NSLocationAlwaysAndWhenInUseUsageDescription的文案。
展开
评论
点赞