Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >协程池是调用端并发请求的缓释胶囊

协程池是调用端并发请求的缓释胶囊

作者头像
有态度的马甲
发布于 2025-04-07 07:01:19
发布于 2025-04-07 07:01:19
6700
代码可运行
举报
文章被收录于专栏:精益码农精益码农
运行总次数:0
代码可运行

昨天"朝花夕拾"栏目倒腾了一款具有请求排队功能的并发受限服务器

演示了互联网高并发请求,服务端遇到的现实情况(服务器高负载、cpu打满、sql并发受限)。

文章重点在于给服务提供方削峰填谷,今天咱们把视角移到服务调用方。


如果是一个调用端程序同时发出这么多并发请求:

(在服务器处理单次请求耗时50ms的前提下)

并发客户端请求数concurrencyClients

服务器请求队列queueLength

服务器限流阈值 Maxoutstanding

总耗时ms

1000

100

10

5014

动图显示:

虽然1000个并发请求在5257ms全部处理完, 但是至少有一半的请求耗时超过3s, 那这又会有什么问题呢?

端到端的请求:为防止服务器处理过慢,长时间占用客户端到服务器的请求链路资源,调用端一般都会设置超时时间

eg:

  • 前端ajax工具库设置超时时间:axios.defaults.timeout = 12000;
  • golang httpclient 设置超时时间:client := &http.Client{   Timeout: 10 * time.Second,   }
  • etcd grpc请求超时时间:eClient.Get(ctx, "/foo")

很明显,这个例子中如果clientTimeout=3s, 就会导致大量请求超时失败。


既要让所有客户端请求都能被处理,又要保证不超过客户端自设的超时配置。

协程池[1]这个缓释胶囊就可以上场了。

Package ants implements an efficient and reliable goroutine pool for Go.  

With ants, Go applications are able to limit the number of active goroutines, recycle goroutines efficiently, and reduce the memory footprint significantly. Package ants is extremely useful in the scenarios where a massive number of goroutines are created and destroyed frequently, such as highly-concurrent batch processing systems, HTTP servers, services of asynchronous tasks, etc.

总体而言, ants是golang中用于将高并发的Goroutine削峰填谷, 起到调用端缓释胶囊的作用。

另一个角度,正因为golang启动协程毫无顾虑,协程池的存在也是为了避免协程滥用。

将原clients()函数中无脑迅速启动1000个并发协程, 替换为ants库(协程池内协程数量设置为50)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func antsClients() {
 wg1.Add(concurrencyClients)
 pool, _ := ants.NewPool(50)
 defer pool.Release()
for i := 1; i <= concurrencyClients; i++ {
  r := &Request{
   args:       []int{i},
   resultChan: make(chan int),
  }
  _ = pool.Submit(func() {
   ClientReq(r)
  })
 }
 wg1.Wait() // WaitGroup依旧可用
}

动图显示,整体耗时相比于不用协程池无差, 但是每个请求的耗时都得到了很好的控制, 整个客户端程序批量发起1000个请求显得轻快又高效。

源代码还是在https://github.com/zwbdzb/go_sample1, 欢迎关注。

That's All, 本文是自己在中厂的一个生产实践复盘: 调用方某些场景下突发批量请求,一开始也是自然启动多协程发起请求,大量请求因为服务端限制而超时失败, 启动ants这个缓释胶囊后问题得到解决。

生活就是这样,只要你愿意倒腾,总有新发现。

参考资料

[1] 

协程池: https://github.com/panjf2000/ants

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

本文分享自 精益码农 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
白话 Golang 协程池
并发指在一段时间内有多个任务(程序,线程,协程等)被同时执行。注意,不是同一时刻。
恋喵大鲤鱼
2021/05/18
2K0
白话 Golang 协程池
推荐很好用的Goroutine连接池
ants是一个高性能的协程池,实现了对大规模goroutine的调度管理、goroutine复用,允许使用者在开发并发程序的时候限制协程数量,复用资源,达到更高效执行任务的效果。
李海彬
2018/07/26
1.4K0
推荐很好用的Goroutine连接池
​Golang 并发编程指南
作者:dcguo,腾讯 CSIG 电子签开放平台中心 分享 Golang 并发基础库,扩展以及三方库的一些常见问题、使用介绍和技巧,以及对一些并发库的选择和优化探讨。 go 原生/扩展库 提倡的原则 不要通过共享内存进行通信;相反,通过通信来共享内存。 Goroutine goroutine 并发模型 调度器主要结构 主要调度器结构是 M,P,G M,内核级别线程,goroutine 基于 M 之上,代表执行者,底层线程,物理线程 P,处理器,用来执行 goroutine,因此维护了一个 gorout
腾讯技术工程官方号
2021/12/20
1.4K0
字节开源Go协程池 gopool
一般来说,用 waitGroup 结合 channel ,可以实现一个协程池的功能。一个协程池,一般要具有如下三个功能:
王小明_HIT
2024/04/17
2.1K0
字节开源Go协程池 gopool
读猿码系列——6.Golang中用幂等思路解决缓存击穿的方案:singleflight
今天我们来看一个日常工作中会遇到的问题:实际开发中常见的做法是在查数据库前先去查缓存,如果缓存Miss(未命中)就去数据库中查到数据并放到缓存里。这是正常情况,然而缓存击穿则是指在高并发系统中,大量请求同时查询一个缓存的key,假如这个key刚好过期就会导致大量的请求都打到数据库上。在绝大多数情况下,可以考虑使用singleflight来抑制重复函数调用。
才浅Coding攻略
2022/12/12
7100
莫非这就是Go最优雅协程池?
经常写Go的小伙伴都知道,Go语言的goruntine是这门编程语言的一大利器,相比线程,基于协程的goruntine更加轻量和高效,并且在语法上十分的简单。
闫同学
2024/07/25
4090
Go 常见并发模式实现(三):通过无缓冲通道创建协程池
上篇教程学院君给大家演示了如何通过缓冲通道实现共享资源池,今天,我们来看另一个并发模式的 Go 语言实现 —— 通过无缓冲通道实现协程(goroutine)池。
学院君
2020/10/19
7410
Go 常见并发模式实现(三):通过无缓冲通道创建协程池
Go语言协程池实现
对于性能测试来讲,使用编程语言实现性能测试用例的核心就是并发编程,也就是同时执行多个测试用例,以模拟真实的负载情况。并发编程可以有效地提高测试效率,可以更快地发现系统中的瓶颈和性能问题。在实现并发编程时,需要考虑线程的同步和互斥,以确保测试结果的正确性和可靠性。此外,还需要考虑如何分配和管理资源,以避免资源竞争和浪费。
FunTester
2023/08/04
2060
Go语言协程池实现
天元平台-波分DWDM资源巡检架构
我们都知道当今互联网发展特点就是快,我们作为研发所开发的任何产品,包括不限于APP、WEB端、WISE、H5等。本人经历过产品经理提出过要求研发team一个月开发一款新的APP上线,接下来就是避免重复造轮子似的“Ctrl+c&&Ctrl+v”,上线过后的代码运行阶段的稳定性结局可想而知。所以始终牢记一点,写常规代码的过程相对容易,但如何保证线上代码长期稳定的运行才是一个系统能否生存下去的关键,就好比开发一款产品是“0-1”的过程,类比于“婴儿”出生,成长的过程的稳定和恰到好处的高可用率是我们作为研发(“父母”)需要付出很多关心的地方。故而作为一名研发,当前系统在长期运行阶段,暴露许多数据资源不一致问题,这些问题有大有小,严重的影响波分快速扩容带宽需求的业务下发成功率,以及对Controller管控设备产生影响。并且对于整体波分系统的控制通道发生的设备托管问题较为频繁且严重,针对以上特点问题,天元平台项目启动。下文主要从项目概述、数据库、高并发架构、golang高级特性,以下都是我在开发过程中用到的一些经验和技术手段分享,没有最好的技术,只有合适的技术,因此也称不上是最佳实践,仅供参考。
MOSS-DZ
2023/04/20
5530
天元平台-波分DWDM资源巡检架构
使用Go协程池来优化并发任务处理
在今天的文章中,我要向大家介绍一个强大而实用的功能 - 使用Go实现的协程池。协程池是一个极为有效的工具,可以帮助我们在编写并发程序时实现更优的资源控制和调度。
运维开发王义杰
2023/08/10
1.3K0
使用Go协程池来优化并发任务处理
Go 协程池
Goroutine 是 Golang 提供的一种轻量级线程,我们通常称之为「协程」,相比较线程,创建一个协程的成本是很低的。所以你会经常看到 Golang 开发的应用出现上千个协程并发的场景。
王小明_HIT
2023/03/01
7700
Go 协程池
手把手教你Golang的协程池设计
现在很多公司都在陆续的搭建golang的语言栈,大家有没有想过为什么会出现这种情况?一是因为go比较适合做中间件,还有一个原因就是go的并发支持比较好,也就是咱们平时所谓的高并发,并发支持离不开协程,当然协程也不是乱用的,需要管理起来,管理协程的方式就是协程池,所以协程池也并没有那么神秘,今天咱们就来一步一步的揭开协程池的面纱,如果你没有接触过go的协程这块的话也没有关系,我会尽量写的详细。
程序员小饭
2021/06/22
1.2K0
手把手教你Golang的协程池设计
[警惕] 请勿滥用goroutine
在Go语言中,goroutine的创建成本很低,调度效率高,Go语言在设计时就是按以数万个goroutine为规范进行设计的,数十万个并不意外,但是goroutine在内存占用方面确实具有有限的成本,你不能创造无限数量的它们,比如这个例子:
Golang梦工厂
2022/07/11
5040
[警惕] 请勿滥用goroutine
go语言协程实现原理初探
golang作为一门现代语言,有其独特之处,比如一个go func(){}()语句即可实现协程,但也存在一些让人诟病的地方,比如错误处理等等。但是想必人无完人,无物完物。我们今天聊聊golang的协程(也叫goroutine)。首先提到协程,我们会想到进程,线程,那么协程是什么呢?协程是一种用户态的线程,他可以由用户自行创建和销毁,不需要内核调度,创建和销毁不需要占用太多系统资源的用户态线程。所以通常情况下,对于大并发的业务,我们通常能创建数以万计的协程来并发处理我们的业务,而不用担心资源占用过多。所以go的协程的作用就是为了实现并发编程,它是由go自己实现的调度器实现资源调度,从而开发者不用太多关心并发实现,从而可以安心的写一些牛逼的业务代码。
金鹏
2024/02/07
7243
go语言协程实现原理初探
Golang倒腾一款简配的具有请求排队功能的并发受限服务器
① sem 提供了限制服务端并发处理请求的信号量 ② queue 提供了一个客户端请求队列,起媒介/解耦的作用
有态度的马甲
2025/04/07
450
Golang倒腾一款简配的具有请求排队功能的并发受限服务器
Golang实现协程池
go实现协程池,协程轻量但并不是越多越好。虽然golang底层实现了对协程的复用,协程(Goroutine)的创建和调度由底层的运行时系统(runtime)负责,它会自动管理和复用协程,但是一瞬间并发过高仍然会导致内存资源消耗过大。使用协程池可用对资源进行有效控制。在内存资源够用的情况,或者其他不用限制同时任务数的情况,请用原生go 协程,不必使用协程池
地球流浪猫
2023/10/14
3980
Golang实现协程池
通过无缓冲的通道实现Worker池,无缓冲的通道好处是:1. 任务不会丢失,所有投递的任务都一定会被处理,如果协程池里的协程都在忙碌中的话,那么会阻塞在往通道投递任务的那一行代码。2. 调用者可以及时的知道协程池是否处于忙碌的状态中。 以下是Work包中的代码:package workimport "sync"// work包的目的是展示如何使用无缓冲的通道来创建一个goroutine池, 这些goroutine执行并控制一组工作// 让其并发工作。在这种情况下, 使用无缓冲的通道要比随意指定一个缓冲
dddyge
2022/12/18
7370
GoLang协程与通道---下
假设我们需要处理很多任务;一个worker处理一项任务。任务可以被定义为一个结构体(具体的细节在这里并不重要):
大忽悠爱学习
2022/08/23
6310
GoLang协程与通道---下
golang-ants协程池的使用和实现
golang中goroutine由运行时管理,使用go关键字就可以方便快捷的创建一个goroutine,受限于服务器硬件内存大小,如果不对goroutine数量进行限制,会出现Out of Memory错误。但是goroutine泄漏引发的血案,想必各位gopher都经历过,通过协程池限制goroutine数一个有效避免泄漏的手段,但是自己手动实现一个协程池,总是会兼顾不到各种场景,比如释放,处理panic,动态扩容等。那么ants是公认的优秀实现协程池。
小许code
2023/02/10
4.6K0
golang-ants协程池的使用和实现
Java开发者的Golang进修指南:从0->1带你实现协程池
在Java编程中,为了降低开销和优化程序的效率,我们常常使用线程池来管理线程的创建和销毁,并尽量复用已创建的对象。这样做不仅可以提高程序的运行效率,还能减少垃圾回收器对对象的回收次数。
努力的小雨
2024/01/11
3050
相关推荐
白话 Golang 协程池
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档