ants:强大的高性能与低成本 Go 协程池

news/2024/10/4 9:29:43

ants:强大的高性能与低成本 Go 协程池

源自开发者
专注于提供关于Go语言的实用教程、案例分析、最新趋势,以及云原生技术的深度解析和实践经验分享。
256篇原创内容

在开发高并发程序时,管理并发的能力至关重要。在 Golang 中,虽然可以使用 Go 内置的 goroutines 来处理并发任务,但没有调度和控制的 goroutine 很容易导致系统资源耗尽。为了解决这个问题,ants 是一个高性能且低成本的 Go 协程池库,可以更高效地管理和使用 goroutine。

本文将详细介绍如何使用 ants 作为 goroutine 池来优化 Go 应用程序,包括如何安装 ants、创建池、提交任务、调整参数等,并通过几个示例演示其实际应用。

安装 ants

首先,我们需要在项目中安装 ants。这可以通过以下命令完成:

go get -u github.com/panjf2000/ants/v2

安装完成后,就可以在代码中引用 ants 了。

基本使用方法

基本的使用 ants 非常简单。我们可以创建一个 goroutine 池,在池中提交任务,然后关闭池。以下是一个简单的示例:

package main

import (
    "fmt"
    "time"
    "github.com/panjf2000/ants/v2"
)

func main() {
    runTask := func(i interface{}) {
        fmt.Printf("Running task: %d\n", i.(int))
        time.Sleep(1 * time.Second) // 模拟任务处理
    }

    // 创建一个具有 10 个 goroutines 的池
    p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
        runTask(i)
    })
    defer p.Release()

    // 提交任务
    for i := 0; i < 30; i++ {
        _ = p.Invoke(i)
    }

    // 等待所有任务完成
    p.Wait()
    fmt.Println("All tasks completed")
}

在这个示例中,我们创建了一个包含 10 个 goroutines 的池,并提交了 30 个任务。ants 会自动调度这些任务,确保并发数不会超过池的大小。

调整参数

ants 提供了多种参数来优化池的行为。例如,可以调整池的大小、设置非阻塞模式、以及设置空闲的超时时间等。

设置池大小

我们可以创建一个不同大小的池,通过 NewPoolWithFunc 来指定池大小:

p, _ := ants.NewPoolWithFunc(20, func(i interface{}) {
    runTask(i)
})

设置非阻塞模式

默认情况下,如果池已满,新任务会阻塞直到有空闲 goroutine 可用。我们可以通过设置非阻塞模式来改变这一行为:

p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
    runTask(i)
}, ants.WithNonblocking(true))

在非阻塞模式下,如果池已满,新任务会立即返回错误,而不是等待。

设置任务超时

我们还可以设置池中任务的超时时间,以避免某些任务耗时过长:

p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
    runTask(i)
}, ants.WithExpireDuration(5 * time.Second))

在这个示例中,每个任务最多只能运行 5 秒钟,超过这个时间,任务将被自动终止。

示例:网络爬虫

假设我们正在编写一个网络爬虫,需要并发访问多个网页。可以使用 ants 来管理并发连接:

package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
    "github.com/panjf2000/ants/v2"
)

func main() {
    urls := []string{
        "http://example.com",
        "http://example.org",
        "http://example.net",
    }

    fetchURL := func(url string) {
        resp, err := http.Get(url)
        if err != nil {
            fmt.Printf("Failed to fetch %s: %s\n", url, err)
            return
        }
        defer resp.Body.Close()
        body, _ := ioutil.ReadAll(resp.Body)
        fmt.Printf("Fetched from %s: %d bytes\n", url, len(body))
    }

    p, _ := ants.NewPoolWithFunc(5, func(i interface{}) {
        fetchURL(i.(string))
    })
    defer p.Release()

    for _, url := range urls {
        _ = p.Invoke(url)
    }

    p.Wait()
    fmt.Println("All URLs fetched")
}

在这个示例中,我们创建了一个网络爬虫,使用 ants 来并发地访问多个网页。爬虫只使用 5 个 goroutines,并发访问多个 URL。

扩展思路

除了基本的任务提交和参数调整,还有许多高级用法。下面列举几个:

动态调整池大小

有时候,我们需要根据运行时环境动态调整池的大小。ants 支持在运行时调整池大小:

pool.Tune(20)

性能监控

ants 内置了一些性能监控功能,可以用来观察池的运行状态:

fmt.Printf("Running goroutines: %d\n", pool.Running())
fmt.Printf("Free goroutines: %d\n", pool.Free())

异常处理

可以为每个任务设置异常处理机制,确保 goroutine 不会因为 panic 而崩溃:

p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic", r)
        }
    }()
    runTask(i)
})

总结

使用 ants 可以显著提高 Go 应用程序的并发能力,使得 goroutines 的管理更加高效和可靠。通过调整参数,我们可以更灵活地控制池的行为,以满足不同的应用场景需求。无论是简单的并发任务,还是复杂的并发控制,ants 都提供了强大的支持。

希望通过本文,你能够对 ants 有一个全面的理解,并能在实际项目中灵活运用。🔧🚀

 

 

文章精选

使用 Go 语言连接并操作 SQLite 数据库

Go语言官方团队推荐的依赖注入工具

替代zap,Go语言官方实现的结构化日志包

Go语言常见错误 | 不使用function option模式

必看| Go语言项目结构最佳实践

 

点击关注并扫码添加进交流群领取「Go 语言」学习资料

图片

K8sCat

 来杯冰美式提提神~ 

赞赏二维码钟意作者

Golang · 目录
上一篇使用 Gin 快速开发高性能的 Web 应用
阅读 196
写留言
 
 
 
 
 
 
 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/44312.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

app专项测试

过滤: 过滤表达式: domain. 展示 domain 中的资源, *.comhas-response-header. 包含指定 HTTP 响应 headeris. 表达式larger-than. 展示大于某个尺寸的资源,1000 等于 1kmethod. 指定http请求方法,比如 get 或者 postmime-type. 资源 mime 类型,比如 application/jsonsch…

goland的启动配置

参考:https://www.cnblogs.com/laijinquan/p/11968410.html 纯记录,如图

POS机SQL server数据库修复

今天这个案例,是烟酒店的老板,一台超市收银系统损坏了,资讯云的管理系统描述的就是开机进不了系统,找不到硬盘,导致数据呢无法访问,索性能进去,可能也运行不了几分钟就直接关机或者是死机,一定要保证数据万无一失,它里面有一些销售的一些记录报表,包括一些会员卡的情…

BitLocker加密分区丢失了如何恢复?

关于BitLocker加密分区丢失与恢复BitLocker是Windows操作系统提供的磁盘加密技术,可以更好的保护电脑中的数据。被BitLocker加密后的分区,在文件管理器中可以看到分区上会有个黄色的锁(如下图所示),双击该分区,会弹出窗口要求输入密码或是秘钥。输入正确的密码/秘钥后,即…

23年前的东芝硬盘能恢复出来数据吗

23年前的照片怎么导出来?是一块20g的东芝硬盘,型号是MK2023GAS。这款20g的硬盘来说简直是太熟悉了,上大学的时候购买的人生第一台笔记本电脑京东方的,里面的硬盘就是这个型号,他启蒙我认识了苍老师,在他坏了之后,又带领我走上了硬盘维修和数据恢复的道路,直到今天。先来…

结组作业,第二次冲刺(2)

今天是第二次冲刺的第二天,经过昨天的总结,我们今天准备增加一个信箱功能,用户能够通过信箱给我们提出建议,或者告诉我们有什么问题,我觉得这个功能挺重要的,可以通过这个功能来得到用户的反馈,以便于之后对项目进行修改,以下为今日部分代码:<%@ page language=&qu…

最流行的部署模式概述

蓝/绿部署:使用两种环境,保证零宕机;一个托管实时版本,而另一个测试新的更新。如果需要,此设置允许轻松回滚。金丝雀部署:首先向一小部分用户推出更改,从而实现性能监控和收集反馈。如果成功,更新可以逐步扩展到更多用户。滚动部署:分阶段更新软件,确保大部分系统保持…