如何关闭Boto S3连接?

39 投票
3 回答
48663 浏览
提问于 2025-04-18 04:36

我在我的Python程序中使用Boto来连接Amazon S3。我可以顺利打开连接并将文件上传到一个存储桶里。我想,应该在完成后关闭连接,以释放资源,更重要的是,避免因为连接一直开着而带来的安全风险。我以为应该调用close()方法来关闭连接。但我做了以下测试:

  1. 打开连接。
  2. 关闭连接。
  3. 上传文件到存储桶。

我以为第三步会失败,但上传居然成功了!那close()到底是干嘛的呢?如果它并没有真正关闭连接,那我应该用什么来替代close()呢?或者说,关闭连接根本就没必要?

我在Boto教程Boto API参考这个StackOverflow帖子中找过答案,但到现在还没有找到。

谢谢你的帮助。

3 个回答

0

有一种情况是,如果一直保持这个连接打开,可能会导致失败。上面的回答让我找到了解决办法。下面的 addUnverifiedEmail 函数是用来往 AWS RDS 数据库插入数据的。所以,当我尝试插入数据时,boto3 的连接仍然是有效的,这段代码来自我的 Lambda(用 Python 写的)。

boto3.client.sign_up(
                ClientId='xxxxxxxxxxxxxxxxxxxxxxxxxx',
                Username=self._user['email'],
                Password=self._user['password'],
                UserAttributes=attributes
)
dbUserInstance.addUnverifiedEmail(self._user['email'])

这导致了一个错误(错误代码 1205,锁等待超时)。接下来,addUserToCognito 函数创建了 boto3 的连接,并且在插入之前这个连接就不再有效了。

self.addUserToCognito()
dbUserInstance.addUnverifiedEmail(self._user['email'])

在做了这个修改后,插入操作成功了。幸运的是,addUnverifiedEmail 是 addUserToCognito 函数里的最后一个调用,所以我很容易就把它移到了外面。其他更复杂的代码可能就不那么容易处理了。因此,如果 client.close() 没有真正关闭连接,或者没有保持连接关闭,这可能是一个很大的问题。

10

在背后,boto这个库使用的是httplib。这个客户端库支持HTTP 1.1的保持连接功能,也就是说,它可以并且应该保持连接的打开状态,这样就可以通过同一个连接发送多个请求。

connection.close()其实并不会真正关闭底层的连接。它只是移除了对httplib连接池的引用,这样垃圾回收器就可以对这些连接进行处理,真正的连接关闭是在这个时候发生的。

当然,你也可以通过不保留对boto连接的引用来让垃圾回收器运行。但重复使用boto连接会有性能上的好处(比如上面提到的保持连接的好处)。

幸运的是,在大多数情况下,你不需要手动调用connection.close()。关于一个必须调用close的情况,更多细节可以查看我在这个StackOverflow帖子中的回答。

25

你的第三步之所以有效,是因为boto这个库有一段代码,可以自动重新打开已经关闭的连接,并在出错时重试请求。手动关闭boto的连接其实没什么好处,因为这些连接只是普通的HTTP连接,闲置几分钟后会自动关闭。所以我建议你不用担心去手动关闭它们。

撰写回答