如何关闭Boto S3连接?

39

我在Python程序中使用Boto连接到Amazon S3。我能够打开连接并上传文件到存储桶。我认为我应该关闭连接以释放资源,并避免因保留打开的连接而产生任何安全风险。我假设应该调用close()方法。但我进行了以下测试:

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

我认为第三步会失败,但上传成功了!那么close()方法是做什么的呢?如果它并没有真正关闭连接,我应该使用什么代替close()方法?或者不关闭连接也可以吗?

我已经在Boto教程Boto API参考这个StackOverflow帖子中寻找答案,但迄今为止没有找到。

感谢您的帮助。

3个回答

25

您的第三步能够成功是因为boto库中有自动重新打开关闭连接并在出现错误时重试请求的代码。手动关闭boto连接没有太大意义,因为它们只是HTTP连接,在闲置一段时间后会自动关闭。不必担心尝试手动关闭它们。


9
在底层,boto使用httplib。该客户端库支持HTTP 1.1 Keep-Alive,因此它可以并且应该保持套接字打开,以便可以在同一连接上执行多个请求。
`connection.close()`实际上并不关闭底层套接字。相反,它删除对httplib连接池的引用,这使得垃圾收集器可以运行它们,并且这才是实际的套接字关闭发生的时候。
显然,您也可以通过不保留对boto连接本身的引用来让垃圾收集器运行。但是重用boto连接也有性能的好处(例如见上面的Keep-Alive说明)。
幸运的是,在大多数情况下,您不必显式调用`connection.close()`。有关必须调用close的情况的更多详细信息,请参见我在StackOverflow文章中链接到的问题的答案。

0

至少有一种情况下,保持此连接处于打开状态可能会导致失败。上面的答案引导我找到了解决方案。在下面,addUnverifiedEmail执行AWS RDS DB插入操作。因此,在尝试执行插入时,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()实际上并没有关闭连接并保持关闭状态,那么可能会存在相当大的缺陷。


我猜这是一个 boto3.client('cognito-idp')?你看到的错误是与 RDS 实例上锁定记录有关的 MySQL 错误吗?我对它们如何相关感到困惑。cognito-idp 是否也在写入 MySQL?您是否已将 cognito 链接以创建 DB 用户?也许您的 addUnverifiedEmail 插入被 cognito 阻止了,因为它也在进行插入操作?为什么它既要注册又要添加未验证的相同用户电子邮件? - Davos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接