2-20 1 views
环境
代码托管:gitlab
CI:tekton
pipline/task: 阿里云 serverless容器(spot实例且按秒计费)
任务管理:redis
镜像分发工具:crane
效果
核心实现
就近上传,改push为pull,分层同步
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func Sync(src, dest string) error { // 创建使用 docker 配置的 keychain kc, err := NewDockerConfigKeychain() if err != nil { return err } // 使用 docker 配置进行认证 err = crane.Copy(src, dest, crane.WithNoClobber(false), crane.WithAuthFromKeychain(kc)) return err } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
type TaskProcessor struct { store *store.RedisStore workerPool chan struct{} // 用于限制并发数的信号量 wg sync.WaitGroup } // NewTaskProcessor 创建一个新的任务处理器 // maxWorkers 指定最大并发任务数 func NewTaskProcessor(store *store.RedisStore, maxWorkers int) *TaskProcessor { return &TaskProcessor{ store: store, workerPool: make(chan struct{}, maxWorkers), } } // ProcessTask 处理单个任务 func (p *TaskProcessor) ProcessTask(task *types.ImageTask) { p.wg.Add(1) go func() { defer p.wg.Done() // 获取worker槽位 p.workerPool <- struct{}{} defer func() { // 释放worker槽位 <-p.workerPool }() ctx := context.Background() // 更新状态为运行中 task.Status = types.TaskStatusRunning if err := p.store.SaveTask(ctx, task); err != nil { log.Printf("Failed to update task status: %v", err) return } // 执行同步 err := imageDist.Sync(task.Src, task.Dest) // 更新最终状态 if err != nil { task.Status = types.TaskStatusFailed task.Error = err.Error() } else { task.Status = types.TaskStatusComplete } if err := p.store.SaveTask(ctx, task); err != nil { log.Printf("Failed to update final task status: %v", err) } }() } // Wait 等待所有任务完成 func (p *TaskProcessor) Wait() { p.wg.Wait() } // Shutdown 优雅关闭任务处理器 func (p *TaskProcessor) Shutdown(ctx context.Context) { done := make(chan struct{}) go func() { p.wg.Wait() close(done) }() select { case <-ctx.Done(): log.Println("Shutdown timeout, some tasks may still be running") case <-done: log.Println("All tasks completed successfully") } } |
如果想赏钱,可以用微信扫描下面的二维码,一来能刺激我写博客的欲望,二来好维护云主机的费用; 另外再次标注博客原地址 itnotebooks.com 感谢!
