登录
首页 >  Golang >  Go问答

使用 Golang 从 Amazon SQS 队列读取数据 - 处理文件描述符

来源:stackoverflow

时间:2024-03-20 19:36:37 300浏览 收藏

在使用 Golang 从 Amazon SQS 队列读取数据时,可能会遇到大量打开的文件描述符。这通常是由于 AWS 服务客户端未正确关闭连接导致的。要解决此问题,可以在 AWS 配置中设置 `MaxIdleConnsPerHost` 选项,以控制每个主机的最大连接数。此外,还可以调整系统限制,例如使用 `limitnofile` 选项,以增加文件描述符的软限制和硬限制。

问题内容

第一篇文章,请耐心等待 - 我正在使用 receivemessage 从 amazon-sqs 队列中读取内容 - 下面是代码片段。这一切都运行良好(到目前为止每分钟运行大约 3000 条消息)。然而 lsof -p 显示大量(有时数百个)打开的文件描述符 - 这是预期的吗?或者是否需要执行某些操作来关闭未使用的连接(如果这是正确的术语)。任何建议将不胜感激。

for {
     select {
     default:                
            recvResult, rErr := c.AwsService.ReceiveMessage(&sqs.ReceiveMessageInput{
                    QueueUrl:            c.AwsQueueURL.QueueUrl,
                    MaxNumberOfMessages: aws.Int64(c.AwsMaxMessages),
                    WaitTimeSeconds:     aws.Int64(c.AwsLongPollTimeout),
                    VisibilityTimeout:   aws.Int64(c.AwsVisibilityTimeout),
            })
            // error check

            var wg sync.WaitGroup
            msgCount := len(recvResult.Messages)
            if msgCount > 0 {
                for _, awsMsg := range recvResult.Messages {
                    wg.Add(1)
                    go func(m *sqs.Message) {
                            defer wg.Done()
                            // process message body, send results to another endpoint, not AWS
                            okToDelete := processAwsMessage(
                                          workerId, c.NodeId, c.QueueId, c.SaveMessageOnError, 
                                          time.Now().UnixNano(), m.Body,
                                          )

                            if okToDelete {
                                  _, dErr := c.AwsService.DeleteMessage(
                                             &sqs.DeleteMessageInput{
                                                   QueueUrl:      c.AwsQueueURL.QueueUrl,
                                                   ReceiptHandle: m.ReceiptHandle,
                                             })
                            // error check
                            }
                    }(awsMsg)  // End go func
               } end for messages
          wg.Wait()
     } // end msgCount > 0
//// Code to complete select (ctx.Done) and for, etc

解决方案


您可以通过在 http 客户端中设置 maxconnsperhost 来控制 aws.config 连接数

config := &aws.Config{
    Endpoint: aws.String("sqs.us-east-1.amazonaws.com"), // VPC endpoint here
    Region: aws.String("us-east-1"),
    HTTPClient: &http.Client{
        Transport: &http.Transport{
            Proxy: http.ProxyFromEnvironment,
            DialContext: (&net.Dialer{
                Timeout:   30 * time.Second,
                KeepAlive: 30 * time.Second,
            }).DialContext,
            MaxIdleConns:          380,
            MaxIdleConnsPerHost:   160,
            IdleConnTimeout:       90 * time.Second,
            TLSHandshakeTimeout:   10 * time.Second,
            ExpectContinueTimeout: 1 * time.Second,
        },
    },
}

所以 - 这里有两个组件需要解决:

1 - 从 ganapathydselva 提供的适当应用上述内容。

2 - 确保文件描述符得到适当调整。由于我的应用程序从 systemd 运行,因此我在 .service 文件中的 [service] 部分下应用了以下内容 limitnofile=8192:10240

这会将软限制提高到 8192,将硬限制提高到 10240

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>