首页 > 其他分享 >记一次go项目踩坑记录

记一次go项目踩坑记录

时间:2023-06-01 23:01:01浏览次数:30  
标签:stress github 项目 testing link1st go 记录 com

错误描述

  • 在 go 项目中创建了一个脚本,编写了一个 main 函数
  • 其中用到了一个 model github.com/link1st/go-stress-testing/stress
import (
    "fmt"
    // "github.com/dji/go-stress-testing/stress"
	"github.com/link1st/go-stress-testing/stress"
    "net/http"
    "time"
)
  • 在执行 go run xxx.go 的时候,报错
queries.go:6:2: no required module provides package github.com/link1st/go-stress-testing/stress; to add it:
        go get github.com/link1st/go-stress-testing/stress
  • 提示使用 go get github.com/link1st/go-stress-testing/stress 命令去下载缺少的模块
  • 果不其然,执行之后依旧报错
go: github.com/link1st/go-stress-testing/stress: no matching versions for query "upgrade"
  • 表示该模块没有可用的更新版本
  • 指定版本:go get github.com/link1st/go-stress-testing/stress@latest
  • 依旧报错 获取不到目标版本

在github上搜索模块版本信息

  • 搜索技巧 language:go model_name 如下
  • 查看模块版本信息

指定版本来安装

go get github.com/link1st/go-stress-testing/[email protected]
  • 事情总不会顺利,依旧报错
  • go: github.com/link1st/go-stress-testing/[email protected]: invalid version: unknown revision stress/v1.0.5

手动build

  • 经过查阅资料,可以手动build项目来安装模块,类似于maven项目中的二方库

  1. 首先搞清楚,go项目的依赖模块都安装在了什么位置
  1. $GOPATH/pkg/mod/ 目录下
  2. 类似于 maven 本地仓库的 .m2 目录。模块的存储结构也是类似的
  1. 然后下载 github.com/link1st/go-stress-testing/stress 的项目源码
  1. clone下来的代码默认是 master 分支
  2. git checkout v1.0.5
  1. 接下来进行 go build
  • -o: 指定输出文件的名称和路径。
  • -v: 打印出被编译的 Go 包的名称。
  • -a: 强制重新编译所有的包,而不使用缓存中的结果。
  • -race: 启用数据竞争检测器,以识别并报告 Go 程序中的数据竞争问题。
  • -tags: 指定要使用的构建标记。
  1. 完整命令 go build -o /Users/duzhihao/go/pkg/mod/github.com/link1st/go-stress-testing/[email protected] main.go
  1. 然而依旧还是不行

问题根源

  1. 需要的包是 github.com/link1st/go-stress-testing/stress
  2. 清楚如何解释这个包
  1. github.com:模块来源于 github
  2. link1st:作者是 link1st
  3. go-stress-testing:归属于项目 go-stress-testing
  4. stress:项目下的 stress 模块
  1. 去github的项目上找一找这个模块
  2. 好家伙,压根没有 stress 这个模块,怪不得折腾来,折腾去都搞不定

最终解决

通过别的方式找到了stress模块下的源码,一共有四个文件

task.go

package stress

import (
    "context"
    "errors"
)

// Task represents a stress testing task, which consists of a name, a RunFunc function and optional StopFunc function
type Task struct {
    Name      string
    RunFunc   func() error
    StopFunc  func() error
    Context   context.Context
    Cancel    context.CancelFunc
}

// Run runs the Task and returns a TestResult
func (t *Task) Run() *TestResult {
    var requests uint64
    var errors uint64

    for {
        select {
        case <-t.Context.Done():
            return &TestResult{
                Requests: requests,
                Errors:   errors,
            }
        default:
            if err := t.RunFunc(); err != nil {
                errors++
            }
            requests++
        }
    }
}

// NewTask returns a new Task with the given name and RunFunc function
func NewTask(name string, runFunc func() error) *Task {
    ctx, cancel := context.WithCancel(context.Background())
    return &Task{
        Name:     name,
        RunFunc:  runFunc,
        Context:  ctx,
        Cancel:   cancel,
    }
}

// NewTimedTask returns a new Task with the given name, RunFunc function and duration
func NewTimedTask(name string, runFunc func() error, duration int) *Task {
    ctx, cancel := context.WithTimeout(context.Background(), Duration(duration)*time.Second)
    return &Task{
        Name:     name,
        RunFunc:  runFunc,
        StopFunc: cancel,
        Context:  ctx,
        Cancel:   cancel,
    }
}

// Stop stops the Task
func (t *Task) Stop() error {
    if t.StopFunc == nil {
        return errors.New("Stop function is not defined")
    }

    return t.StopFunc()
}

scene.go

package stress


import (
    "sync"
    "sync/atomic"
    "time"
)


// Scene represents a stress testing scene, which consists of multiple tasks
type Scene struct {
    Name        string
    Frequency   time.Duration
    Duration    time.Duration
    SetupFunc   func() error
    CleanupFunc func() error
    tasks       []*Task
}


// AddTask adds a new Task to the Scene
func (s *Scene) AddTask(task *Task) {
    s.tasks = append(s.tasks, task)
}


// Run runs the Scene and returns a TestResult
func (s *Scene) Run() *TestResult {
    resCh := make(chan *TestResult)
    wg := sync.WaitGroup{}


    wg.Add(len(s.tasks))


    for _, task := range s.tasks {
        go func(task *Task) {
            defer wg.Done()
            resCh <- task.Run()
        }(task)
    }


    if s.SetupFunc != nil {
        if err := s.SetupFunc(); err != nil {
            panic(err)
        }
    }


    ticker := time.NewTicker(s.Frequency)
    stop := make(chan bool)


    go func() {
        time.Sleep(s.Duration)
        close(stop)
    }()


    var requests uint64
    var errors uint64


loop:
    for {
        select {
        case <-ticker.C:
            for _, task := range s.tasks {
                for i := 0; i < requestsPerTask; i++ {
                    if err := task.RunFunc(); err != nil {
                        atomic.AddUint64(&errors, 1)
                    }
                    atomic.AddUint64(&requests, 1)
                }
            }
        case res := <-resCh:
            atomic.AddUint64(&requests, res.Requests)
            atomic.AddUint64(&errors, res.Errors)
        case <-stop:
            break loop
        }
    }


    ticker.Stop()


    if s.CleanupFunc != nil {
        if err := s.CleanupFunc(); err != nil {
            panic(err)
        }
    }


    wg.Wait()


    elapsed := time.Duration(requests) * time.Second / time.Duration(rps)
    return &TestResult{
        Requests: requests,
        Errors:   errors,
        Rps:      rps,
        Elapsed:  elapsed,
    }
}


// NewScene returns a new Scene with the given name and default settings
func NewScene(name string) *Scene {
    return &Scene{
        Name:      name,
        Frequency: time.Second,
        Duration:  10 * time.Second,
        SetupFunc: func() error {
            return nil
        },
        CleanupFunc: func() error {
            return nil
        },
    }
}

test_result.go

package stress


import "time"


// TestResult represents the result of a stress test
type TestResult struct {
    Requests uint64
    Errors   uint64
    Rps      uint64
    Elapsed  time.Duration
}

utils.go

package stress


import "time"


const (
    requestsPerTask = 100
    rps             = 100
)


// Duration is an int that can be used with the time package
type Duration int


func (d Duration) String() string {
    return time.Duration(d * time.Second).String()
}

需要注意的是,经过实际操作,这几个go源码并不是很可靠,实际应用还需要根据业务需求来具体调整。

标签:stress,github,项目,testing,link1st,go,记录,com
From: https://blog.51cto.com/u_16079703/6398562

相关文章

  • 如何将spring boot项目打包成war包
    一、修改打包形式在pom.xml里设置 <packaging>war</packaging>  二、移除嵌入式tomcat插件在pom.xml里找到spring-boot-starter-web依赖节点,在其中添加如下代码,<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</ar......
  • IDEA 创建JavaWeb项目(不依赖 springboot)手动整合 SSM框架
    目录 1.创建一个Maven项目2.创建webapp和WEB-INF目录即可3.设置web.xml文件和web文件目录4.导入相关ssm框架的pom依赖文件5.创建对应的包结构:6.添加配置文件(配置mybatis、spring、springMvc等配置文件)7.web.xml配置文件8. 配置本地Tomcat运行9.打包发布1.创建一个Mav......
  • 使用session+cookie改造单表项目
    1.  session掌握之后,我们怎么解决oa项目中的登录问题,怎么能让登录起作用。  441.1 思路  44  - 登录成功之后,可以将用户的登录信息存储到session当中。也就是说session中如果有用户的信息就代表用户登录成功了。session中没有用户信息,表示用户没有登录过。则跳转到登录页......
  • ROS2-Beginner:10-记录和播放数据
    目标:记录发布到话题上的数据,可以任何时候回放和检查。背景ros2-bag是一个命令行工具,用于记录系统中主题发布的数据。它累积在任意数量的主题上传递的数据,并将其保存在数据库中。然后,您可以回放数据以重现测试和实验的结果。录制主题也是分享你的作品并允许他人重新创作的好方法......
  • 大型 3D 互动项目开发和优化实践
    开发背景得益于“元宇宙”概念在前段时间的爆火,各家公司都推出了使用3D场景的活动或频道。3D场景相比传统的2D页面优点是多一个维度,同屏展示的内容可以更多,能完整的展示物体、商品的信息。相应带来的缺点是用户使用方式改变,用户需要额外的学习成本。另外初期需要的开发......
  • C温故补缺(十七):动态链接(ELF,PIC,GOT,PLT)
    动态链接(PIC,GOT,PLT,ELF)参考:51CTO通过静态链接,可以生成一个可执行文件,这个可执行文件既可以是完全链接的也可以是部分链接的,对于部分链接的可执行文件,有些符号引用需要等到可执行文件加载时甚至是运行时才会进行符号解析和重定位。动态链接与静态链接一样包括符号解析和重......
  • 【Vue】 vue项目的目录结构
    ├──build/#Webpack配置目录├──dist/#build生成的生产环境下的项目├──config/#Vue基本配置文件,可以设置监听端口,打包输出等├──node_modules/#依赖包,通常执行npmi会生成├──src/......
  • 企业级springboot项目架构模板V3.0,开箱即用
    此次3.0更新点:1.加入文件服务(quick-storage)功能支持OSS、FTP存储(该服务支持以SDK的方式引入)2.修复sentinel因path路径问题导致流控失效问题3.修复word模板生成PDF文件工具类时首次生成时,图片生成没有成功写入FTP的问题,原因为临时文件路径问题。4.修改部分类的包路径5.auth服......
  • 企业级springboot项目架构模板V1.0,开箱即用
    项目地址:https://gitee.com/liujinxin_ark/quick-template/releases项目问题可在评论中留言,项目持续更新中…quick-template项目介绍软件架构quick-auth-serve工程quick-log-serve工程quick-common工程quick-config工程quick-base-serve工程quick-web-serve工程control目......
  • Springboot项目中如何使用线程池
    目录1.基于 ExecutorService自定义线程池(Java5中引入的)2.基于 ThreadPoolTaskExecutor线程池的使用(Spring提供,以及监听线程池)3.自定义 ThreadPoolTaskExecutor线程池用于大数据量的导出报表、远程请求处理数据量同步等等日常项目中可以定义多个线程池,如:报表导出使用的线......