2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

Kubernetes 中定时任务的实现

  • 2020-01-10
  • 本文字数:2073 字

    阅读完需:约 7 分钟

Kubernetes 中定时任务的实现

Kubernetes 中定时任务的实现

K8s 中有许多优秀的包都可以在平时的开发中借鉴与使用,比如,任务的定时轮询、高可用的实现、日志处理、缓存使用等都是独立的包,可以直接引用。


本文将介绍 K8s 中定时任务的实现,K8s 中定时任务都是通过 wait 包实现的。wait 包在 K8s 的多个组件中都有用到,以下是 wait 包在 kubelet 中的几处使用:


func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan struct{}) (err error) {



// kubelet 每 5 分钟一次从 apiserver 获取证书


closeAllConns, err := kubeletcertificate.UpdateTransport(wait.NeverStop, clientConfig, clientCertificateManager, 5*time.Minute)


if err != nil {


return err


}


closeAllConns, err := kubeletcertificate.UpdateTransport(wait.NeverStop, clientConfig, clientCertificateManager, 5*time.Minute)


if err != nil {


return err


}



}



func startKubelet(k kubelet.Bootstrap, podCfg *config.PodConfig, kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *kubelet.Dependencies, enableServer bool) {


// 持续监听 pod 的变化


go wait.Until(func() {


k.Run(podCfg.Updates())


}, 0, wait.NeverStop)



}


golang 中可以通过 time.Ticker 实现定时任务的执行,但在 K8s 中用了更原生的方式,使用 time.Timer 实现的。time.Ticker 和 time.Timer 的使用区别如下:


  • ticker 只要定义完成,从此刻开始计时,不需要任何其他的操作,每隔固定时间都会自动触发。

  • timer 定时器是到了固定时间后会执行一次,仅执行一次

  • 如果 timer 定时器要每隔间隔的时间执行,实现 ticker 的效果,使用 func (t *Timer) Reset(d Duration) bool


一个示例:


package main


import (


“fmt”


“sync”


“time”


)func main() {


var wg sync.WaitGroup timer1 := time.NewTimer(2 * time.Second)


ticker1 := time.NewTicker(2 * time.Second) wg.Add(1)


go func(t *time.Ticker) {


defer wg.Done()


for {


<-t.C


fmt.Println(“exec ticker”, time.Now().Format(“2006-01-02 15:04:05”))


}


}(ticker1) wg.Add(1)


go func(t *time.Timer) {


defer wg.Done()


for {


<-t.C


fmt.Println(“exec timer”, time.Now().Format(“2006-01-02 15:04:05”))


t.Reset(2 * time.Second)


}


}(timer1) wg.Wait()


}01


wait 包中的核心代码


核心代码


k8s.io/apimachinery/pkg/util/wait/wait.go:


func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) {


var t *time.Timer


var sawTimeout bool


for {


select {


case <-stopCh:


return


default:


} jitteredPeriod := period


if jitterFactor > 0.0 {


jitteredPeriod = Jitter(period, jitterFactor)


} if !sliding {


t = resetOrReuseTimer(t, jitteredPeriod, sawTimeout)


} func() {


defer runtime.HandleCrash()


f()


}() if sliding {


t = resetOrReuseTimer(t, jitteredPeriod, sawTimeout)


} select {


case <-stopCh:


return


case <-t.C:


sawTimeout = true


}


}


}…


func resetOrReuseTimer(t *time.Timer, d time.Duration, sawTimeout bool) *time.Timer {


if t == nil {


return time.NewTimer(d)


}


if !t.Stop() && !sawTimeout {


<-t.C


}


t.Reset(d)


return t


}几个关键点的说明:


  1. 如果 sliding 为 true,则在 f() 运行之后计算周期。如果为 false,那么 period 包含 f() 的执行时间。

  2. 在 golang 中 select 没有优先级选择,为了避免额外执行 f(),在每次循环开始后会先判断 stopCh chan。


K8s 中 wait 包其实是对 time.Timer 做了一层封装实现。


02


wait 包常用的方法


定期执行一个函数,永不停止,可以使用 Forever 方法:


func Forever(f func(), period time.Duration)


在需要的时候停止循环,那么可以使用下面的方法,增加一个用于停止的 chan 即可,方法定义如下:


func Until(f func(), period time.Duration, stopCh <-chan struct{})


上面的第三个参数 stopCh 就是用于退出无限循环的标志,停止的时候我们 close 掉这个 chan 就可以了。


有时候,我们还会需要在运行前去检查先决条件,在条件满足的时候才去运行某一任务,这时候可以使用 Poll 方法:


func Poll(interval, timeout time.Duration, condition ConditionFunc)


这个函数会以 interval 为间隔,不断去检查 condition 条件是否为真,如果为真则可以继续后续处理;如果指定了 timeout 参数,则该函数也可以只常识指定的时间。


PollUntil 方法和上面的类似,但是没有 timeout 参数,多了一个 stopCh 参数,如下所示:


PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error


此外还有 PollImmediate 、 PollInfinite 和 PollImmediateInfinite 方法。


03


总结


本文主要讲了 K8s 中定时任务的实现与对应包(wait)中方法的使用。


通过阅读 K8s 的源代码,可以发现 K8s 中许多功能的实现也都是我们需要在平时工作中用的,其大部分包的性能都是经过大规模考验的,通过使用其相关的工具包不仅能学到大量的编程技巧也能避免自己造轮子。


原文:https://dwz.cn/5zxd9ZqU


2020-01-10 13:531674

评论

发布
暂无评论
发现更多内容

CrossOver 24.0.7 for macOS & Linux - 领先的 Wine 解决方案

sysin

crossover

AI编程:cursor使用教程

卷福同学

Python Cursor-based Pagination #AI编程 #AIGC

MySQL 死锁案例一

喝水不抬头

Qt开发macOS软件系统

北京木奇移动技术有限公司

跨平台开发 软件外包公司 QT开发

QGIS软件系统的测试

北京木奇移动技术有限公司

软件外包公司 QT开发 QT软件开发

PAI Model Gallery 支持云上一键部署 DeepSeek-V3、DeepSeek-R1 系列模型

阿里云大数据AI技术

人工智能 阿里云 模型部署 PAI DeepSeek

如何通过提升简历找到自己的第一份 Web3 工作?

One Block Community

web3 English

Easysearch 集群重置 admin 用户密码

极限实验室

easysearch

AI编程:如何编写提示词

卷福同学

AIGC AI编程 cursor

基于 HyperLogLog 统计直播访问人数-Redis

储诚益

Java 面试 redis 底层原理 场景题

macOS Sonoma 14.7.3 (23H417) Boot ISO 原版可引导镜像下载

sysin

macOS Sonoma

Apple Safari 18.3 - macOS 专属浏览器 (独立安装包下载)

sysin

safari

Nexpose 7.4.0 for Linux & Windows - 漏洞扫描

sysin

Nexpose

XCM:跨链开发者的「低代码平台」

One Block Community

区块链 技术 web3

音乐 NFT 系统的性能优化

北京木奇移动技术有限公司

软件外包公司 音乐NFT 体育NFT

QGIS系统的开发难点

北京木奇移动技术有限公司

WebGIS QGIS 软件外包公司

AppSpider Pro 7.5.015 for Windows - Web 应用程序安全测试

sysin

AppSpider

Tik Tok Refugees 外流会否迎来 Web3 社交应用的春天?

One Block Community

web3 TikTok

INFINI Labs 产品更新 | Console 发布 TopN 功能,Easysearch 新增 Rollup 能力等

极限实验室

Rollup console easysearch TopN

音乐NFT系统的测试

北京木奇移动技术有限公司

软件外包公司 音乐NFT 体育NFT

爆火的Deepseek初体验

能源恒观

人工智能 AI 大模型

Easysearch 集群通过 API 进行用户密码重置

极限实验室

Easy search

Kubernetes 中定时任务的实现_语言 & 开发_华为云原生团队_InfoQ精选文章