Go语言使用gorm对MySQL进行性能测试

Python017

Go语言使用gorm对MySQL进行性能测试,第1张

之前写过了Go语言gorm框架MySQL实践,其中对gorm框架在操作MySQL的各种基础实践,下面分享一下如何使用gorm框架对MySQL直接进行性能测试的简单实践。

这里我使用了一个原始的Go语言版本的 FunTester 测试框架,现在只有一个基本的方法,实在是因为Go语言特性太强了。框架设计的主要思路之一就是利用Go语言的闭包和方法参数特性,将一个 func() 当做性能测试的主题,通过不断运行这个 func() 来实现性能测试。当然还有另外一个思路就是运行一个多线程任务类,类似 Java 版本的 com.funtester.base.constaint.ThreadBase 抽象类,这样可以设置一些类的属性,绑定一些测试资源,适配更多的测试场景。

下面演示select的性能测试,这里我用了随机ID查询的场景。

这里我使用从35开始递增的ID进行删除。

这里使用了select的用例部分,随机ID,然后更新name字段,随机10个长度的字符串。

这里用到了 FunTester 字段都是随机生成。

到这里可以看出,性能测试框架用到的都是gorm框架的基础API使用,这里MySQL连接池的管理工作完全交给了gorm框架完成,看资料说非常牛逼,我们只需要设置几个参数。这个使用体现很像 HttpClient 设置 HTTP 连接池类似,这里我们也可以看出这些优秀的框架使用起来都是非常简单的。

PS:关于gorm的基础使用的请参考上一期的文章Go语言gorm框架MySQL实践。

Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成为现实。Go 团队实施了一个看起来比较稳定的设计草案,并且正以源到源翻译器原型的形式获得关注。本文讲述的是泛型的最新设计,以及如何自己尝试泛型。

例子

FIFO Stack

假设你要创建一个先进先出堆栈。没有泛型,你可能会这样实现:

type Stack []interface{}func (s Stack) Peek() interface{} {

 

return s[len(s)-1]

}

func (s *Stack) Pop() {

 *s = (*s)[:

len(*s)-1]

}

func (s *Stack) Push(value interface{}) {

 *s = 

append(*s, value)

}

但是,这里存在一个问题:每当你 Peek 项时,都必须使用类型断言将其从 interface{} 转换为你需要的类型。如果你的堆栈是 *MyObject 的堆栈,则意味着很多 s.Peek().(*MyObject)这样的代码。这不仅让人眼花缭乱,而且还可能引发错误。比如忘记 * 怎么办?或者如果您输入错误的类型怎么办?s.Push(MyObject{})` 可以顺利编译,而且你可能不会发现到自己的错误,直到它影响到你的整个服务为止。

通常,使用 interface{} 是相对危险的。使用更多受限制的类型总是更安全,因为可以在编译时而不是运行时发现问题。

泛型通过允许类型具有类型参数来解决此问题:

type Stack(type T) []Tfunc (s Stack(T)) Peek() T {

 

return s[len(s)-1]

}

func (s *Stack(T)) Pop() {

 *s = (*s)[:

len(*s)-1]

}

func (s *Stack(T)) Push(value T) {

 *s = 

append(*s, value)

}

这会向 Stack 添加一个类型参数,从而完全不需要 interface{}。现在,当你使用 Peek() 时,返回的值已经是原始类型,并且没有机会返回错误的值类型。这种方式更安全,更容易使用。(译注:就是看起来更丑陋,^-^)

此外,泛型代码通常更易于编译器优化,从而获得更好的性能(以二进制大小为代价)。如果我们对上面的非泛型代码和泛型代码进行基准测试,我们可以看到区别:

type MyObject struct {

    X 

int

}

var sink MyObjectfunc BenchmarkGo1(b *testing.B) {

 

for i := 0 i < b.N i++ {

  

var s Stack

  s.Push(MyObject{})

  s.Push(MyObject{})

  s.Pop()

  sink = s.Peek().(MyObject)

 }

}

func BenchmarkGo2(b *testing.B) {

 

for i := 0 i < b.N i++ {

  

var s Stack(MyObject)

  s.Push(MyObject{})

  s.Push(MyObject{})

  s.Pop()

  sink = s.Peek()

 }

}

结果:

BenchmarkGo1BenchmarkGo1-16     12837528         87.0 ns/op       48 B/op        2 allocs/opBenchmarkGo2BenchmarkGo2-16     28406479         41.9 ns/op       24 B/op        2 allocs/op

在这种情况下,我们分配更少的内存,同时泛型的速度是非泛型的两倍。

合约(Contracts)

上面的堆栈示例适用于任何类型。但是,在许多情况下,你需要编写仅适用于具有某些特征的类型的代码。例如,你可能希望堆栈要求类型实现 String() 函数

1.Docker项目

网址为 https://github.com/docker/docker 。

介绍:Docker是一种操作系统层面的虚拟化技术,可以在操作系统和应用程序之间进行隔离,也可以称之为容器。Docker可以在一台物理服务器上快速运行一个或多个实例。例如,启动一个Cent OS操作系统,并在其内部命令行执行指令后结束,整个过程就像自己在操作系统一样高效。

2.golang项目

网址为 https://github.com/golang/go 。

介绍:Go语言的早期源码使用C语言和汇编语言写成。从Go 1.5版本自举后,完全使用Go语言自身进行编写。Go语言的源码对了解Go语言的底层调度有极大的参考意义,建议希望对Go语言有深入了解的读者读一读。

3.Kubernetes项目

网址为 https://github.com/kubernetes/kubernetes 。

介绍:Google公司开发的构建于Docker之上的容器调度服务,用户可以通过Kubernetes集群进行云端容器集群管理。

4.etcd项目

网址为 https://github.com/coreos/etcd 。

介绍:一款分布式、可靠的KV存储系统,可以快速进行云配置。

5.beego项目

网址为 https://github.com/astaxie/beego 。

介绍:beego是一个类似Python的Tornado框架,采用了RESTFul的设计思路,使用Go语言编写的一个极轻量级、高可伸缩性和高性能的Web应用框架。

6.martini项目

网址为 https://github.com/go-martini/martini 。

介绍:一款快速构建模块化的Web应用的Web框架。

7.codis项目

网址为 https://github.com/Codis Labs/codis。

介绍:国产的优秀分布式Redis解决方案。

8.delve项目

网址为 https://github.com/derekparker/delve 。

介绍:Go语言强大的调试器,被很多集成环境和编辑器整合。