前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言中常见100问题-#100 Not understanding the impacts of running Go ..

Go语言中常见100问题-#100 Not understanding the impacts of running Go ..

作者头像
数据小冰
发布2024-02-23 17:05:53
1250
发布2024-02-23 17:05:53
举报
文章被收录于专栏:数据小冰数据小冰
不了解在Docker和Kubernetes中运行Go程序影响

2021年Go开发者调查(https://go.dev/blog/survey2021-results)表明,用Go编写服务是最常见的用法,见下图。与此同时,Kubernetes是部署这些服务最广泛使用的平台。

理解Go程序是如何在Docker和Kubernetes中运行的至关重要,这样可以防止常见问题产生。比如CPU受限。

Go语言中常见100问题-#56 Concurrency isn’t always faster中提到,设定GOMAXPROCS可以调整运行时中P(GMP中的P)数量,由于每个系统线程必须要绑定P才能真正地执行,所以P的数量影响程序的并发性。

默认情况下,GOMAXPROCS被设置为操作系统可见的逻辑CPU内核数,这在Docker和Kubernetes环境中有啥影响呢?下面举例说明:

假设我们的Kubernetes集群由八核节点组成,当在Kubernetes中部署一个容器时,可以定义CPU限制来确保应用不会消耗掉所有的主机资源。如下,配置CPU的使用限制为4000m,这里单位后缀m表示千分之一核,也就是说 1 Core = 1000m,所以4000m对应4个CPU核。

现假定我们的应用在部署时,基于上述配置限制GOMAXPROCS值被设置为4。但实际是这样的吗?答案是否定的,GOMAXPROCS实际被设置为主机上逻辑核心的数量8,这会导致什么问题呢?

Kubernetes使用完全公平调度器(CFS)作为进程调度器,此外CFS还会强制按Pod限制的CPU资源执行。在管理Kubernetes集群时,管理员可以配置如下两个参数:

  • cpu.cfs_period_us(全局配置)
  • cpu.cfs_quota_us(Pod配置)

第一个参数设置时长,第二个参数是额度配置。默认情况下,时长设置为100毫秒。额度配置表示应用在100毫秒内可以消耗的CPU时间,默认是-1表示不设置硬限。限制为4个内核意味着总时长为400毫秒(4*100毫秒)。因此CFS保证应用在100毫秒内不会消耗超过400毫秒的CPU时间。

现在有这样一个场景,多个goroutines正在四个不同线程上运行,每个线程被调度到不同的内核(1、3、4和8),如下图所示。

在第一个100毫秒时间内,有四个线程处于忙碌状态,总共消耗了400毫秒时间,即达到限额的100%。在第二个100毫秒时间内,总共消耗了360毫秒,第三个100毫秒时间消耗了275毫秒,它们都没有超过400毫秒限制,一切工作良好。

但是,实际GOMAXPROCS值为8,因此在最坏情况下,可以有八个线程都在运行,每个线程被安排在不同内核上,如下图。

因为配额为400毫秒,如果有8个线程忙于执行goroutines,则50毫秒后就达到400毫秒(8*50毫秒=400毫秒)。接下来CFS将限制CPU资源,因此在下一个周期开始前,没有CPU资源可用。意味着我们的应用将被搁置50毫秒。

这种情况下,平均延迟为50毫秒的服务可能需要150毫秒才能完成,这可能对延迟造成300%的损失。

有什么解决方法吗?关注Go语言第33803 issue问题进展(github.com/golang/go/issues/33803),也许在将来的Go版本中,GOMAXPROCS会支持CFS。

当前解决方法是使用uber公司提供的automaxprocs库(github.com/uber-go/automaxprocs)。使用很简单,在main.go文件中添加一个go.uber.org/automaxprocs空导入即可,它会根据容器中的CPU配额自动设置GOMAXPROCS,前面的例子中,GOMAXPROCS被设置为4而不是宿主机CPU数8,从而避免CPU throttling。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据小冰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 不了解在Docker和Kubernetes中运行Go程序影响
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档