golang性能测试框架k6源码分析

Python011

golang性能测试框架k6源码分析,第1张

k6是新兴的性能测试框架,比肩jmeter,另外测试脚本使用js,更加适合自动化的架构。

k6启动的框架是使用golang的cli标准框架cobra,入口函数

进入cobra框架后,我们直接查看getRunCmd,这个是命令run的入口,主要工作都是从这里开始。

重点关注初始化Runner,这个是通过js脚本,使用goja库解析后,生成的实际执行单元。

进入js目录,查看Runner的结构,runner.go

Runner有一些配置属性,另外还有方法,方法用lib.Runner的接口进行规范。

Runner有一个NewVU方法,里面定义了连接参数,实现api测试

返回主函数,在初始化完成Runner后,启动调度器,以及做结果收集

最终封装成一个engine

启动测试

当客户端在 发出POST请求时/albums,您希望将请求正文中描述的专辑添加到现有专辑数据中。

为此,您将编写以下内容:

1、编写代码

a.添加代码以将专辑数据添加到专辑列表。

在此代码中:

1)用于Context.BindJSON 将请求正文绑定到newAlbum。

2) album将从 JSON 初始化的结构附加到albums 切片。

3)向响应添加201状态代码,以及表示您添加的专辑的 JSON。

b.更改您的main函数,使其包含该router.POST函数,如下所示。

在此代码中:

1)将路径中的POST方法与 /albumspostAlbums函数相关联。

使用 Gin,您可以将处理程序与 HTTP 方法和路径组合相关联。这样,您可以根据客户端使用的方法将发送到单个路径的请求单独路由。

a.如果服务器从上一节开始仍在运行,请停止它。

b.从包含 main.go 的目录中的命令行,运行代码。

c.从不同的命令行窗口,用于curl向正在运行的 Web 服务发出请求。

该命令应显示添加专辑的标题和 JSON。

d.与上一节一样,使用curl检索完整的专辑列表,您可以使用它来确认添加了新专辑。

该命令应显示专辑列表。

当客户端向 发出请求时GET /albums/[id],您希望返回 ID 与id路径参数匹配的专辑。

为此,您将:

a.在您在上一节中添加的函数下方postAlbums,粘贴以下代码以检索特定专辑。

此getAlbumByID函数将提取请求路径中的 ID,然后找到匹配的专辑。

在此代码中:

(1)Context.Param用于从 URL 中检索id路径参数。当您将此处理程序映射到路径时,您将在路径中包含参数的占位符。

(2)循环album切片中的结构,寻找其ID 字段值与id参数值匹配的结构。如果找到,则将该album结构序列化为 JSON,并将其作为带有200 OK HTTP 代码的响应返回。

如上所述,实际使用中的服务可能会使用数据库查询来执行此查找。

(3)如果找不到专辑,则返回 HTTP 404错误。

b.最后,更改您的main,使其包含对router.GET的新调用,路径现在为/albums/:id ,如以下示例所示。

在此代码中:

(1)将/albums/:id路径与getAlbumByID功能相关联。在 Gin 中,路径中项目前面的冒号表示该项目是路径参数。

a.如果服务器从上一节开始仍在运行,请停止它。

b.在包含 main.go 的目录中的命令行中,运行代码以启动服务器。

c.从不同的命令行窗口,用于curl向正在运行的 Web 服务发出请求。

该命令应显示您使用其 ID 的专辑的 JSON。如果找不到专辑,您将收到带有错误消息的 JSON。

恭喜!您刚刚使用 Go 和 Gin 编写了一个简单的 RESTful Web 服务。

本节包含您使用本教程构建的应用程序的代码。

client-go是一个调用kubernetes集群资源对象API的客户端,即通过client-go实现对kubernetes集群中资源对象(包括deployment、service、ingress、replicaSet、pod、namespace、node等)的增删改查等操作。大部分对kubernetes进行前置API封装的二次开发都通过client-go这个第三方包来实现。

​client-go官方文档: https://github.com/kubernetes/client-go

client-go库版本

获取kubernetes配置文件kubeconfig的绝对路径。一般路径为$HOME/.kube/config。该文件主要用来配置本地连接的kubernetes集群。config配置文件支持集群内和集群外访问方式。(只要在网络策略访问范围内)

config文件形式如下所示:

通过参数(master的url或者kubeconfig路径)用BuildConfigFromFlags方法来获取rest.Config对象,一般是通过参数kubeconfig的路径。

通过config对象为入参,调用NewForConfig函数获取clients对象,clients是多个client的集合。里面包含着各个版本的client。源码地址:k8s.io/client-go/kubernetes/clientset.go

NewForConfig函数根据传入的rest.config对象创建一个Clientset对象,此对象可以操作CoreV1()方法。

其结构体具体参数如下所示:

Clientset结构体实现了以上结构定义的所有方法。源码地址:k8s.io/client-go/kubernetes/clientset.go

因为Clientset可使用其中任意函数调用,如获取Pod列表。

在创建Clientset对象时,Clientset 中的变量coreV1也被一起初始化创建。即创建了CoreV1Client对象。

如下所示:

CoreV1Interface中包含了各种kubernetes对象的调用接口,例如PodsGetter是对kubernetes中pod对象增删改查操作的接口。ServicesGetter是对service对象的操作的接口。

CoreV1Client结构体实现了CoreV1Interface所有的定义函数。

PodsGetter接口中定义了Pods方法此方法返回PodInterface,这样就可以用Clients.Corev1().Pods()方法对Pod进行增删改查操作了。

调用Pods方法,再通过newPods函数创建一个Pods的对象。pods对象继承了rest.Interface接口,即最终的实现本质是RESTClient的HTTP调用。

PodInterface接口定义了Pod对象操作的所有方法。

Pod对象中继承了rest.Interface,上面提到过此client便是进行http请求调用。

以上分析了clientset.CoreV1().Pods("").List(metav1.ListOptions{})对pod资源获取的过程,最终是调用RESTClient的方法实现。

在CoreV1Client对象创建的时候也根据config对象调用est.RESTClientFor(&config)函数创建了rest client对象。在创建Pod时将CoreV1Client对象的restClient赋值给Pod的client。

此接口定义了http请求的方法。

通过以上实现可以看出对着的接口调用都转到了Verb方法的调用。Verb方法通过传参调用NewRequest函数最终执行了一次http请求操作。

可以看到NewRequest最终将参数组成http请求参数进行了http请求调用。至此clientset.CoreV1().Pods("").List(metav1.ListOptions{})调用完成,最终将结果返回。

client-go对kubernetes资源对象的调用操作,需要先获取kubernetes的配置信息,即$HOME/.kube/config。(master节点)

具体流程如下图所示: