AWS lambda和Java并发

And*_*niy 42 java concurrency multithreading amazon-web-services aws-lambda

众所周知,AWS lambda 可能会重用早期创建的处理程序对象,而且确实如此(请参阅常见问题解答):

问:AWS Lambda会重用函数实例吗?

为了提高性能,AWS Lambda可以选择保留您的函数实例并重复使用它来提供后续请求,而不是创建新副本.您的代码不应该假设这总是会发生.


问题是关于Java并发性.如果我有一个处理程序的类,请说:

public class MyHandler {
    private Foo foo;
    public void handler(Map<String,String> request, Context context) {
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,foo在这里访问和使用对象变量是否可以线程安全?

换句话说:AWS lambda可以同时为不同的调用使用相同的对象吗?

编辑我的函数在基于事件的源上处理,特别是它由API网关方法调用.

EDIT-2当你想要将某种连接池实现到外部资源时,这类问题就会出现,所以我想保持与外部资源的连接作为对象变量.它实际上按预期工作,但我害怕并发问题.

EDIT-3更具体地说,我想知道:AWS lambda处理程序的实例是否可以共享公共堆(内存)?我必须指定这个额外的细节,以防止回答列出有关java线程安全对象的明显和常见的事情.

Leo*_*eon 62

AWS lambda可以同时为不同的调用使用相同的对象吗?

AWS lambda的处理程序实例是否可以共享公共堆(内存)?

一个强大,明确的NO.AWS Lambda的处理程序实例甚至无法共享文件(in /tmp).

AWS Lambda容器可能无法重用于Lambda函数的两个或多个并发存在的调用,因为这会破坏隔离要求:

问:AWS Lambda如何隔离我的代码?

每个AWS Lambda函数都在其自己的隔离环境中运行,具有自己的资源和文件系统视图.

部分"如何做AWS LAMBDA我的代码运行的容器模型?"在官方说明lambda函数是如何工作的状态:

执行Lambda函数后,AWS Lambda会在预期另一个Lambda函数调用的情况下维护容器一段时间.实际上,如果AWS Lambda选择在再次调用Lambda函数时重用容器,则服务在Lambda函数完成后冻结容器并解冻容器以供重用.此容器重用方法具有以下含义:

  • Lambda函数代码中的任何声明都会保持初始化状态,从而在再次调用函数时提供额外的优化. 例如,如果Lambda函数建立数据库连接,而不是重新建立连接,则在后续调用中使用原始连接.您可以在代码中添加逻辑,以在创建连接之前检查连接是否已存在.

  • 每个容器在/ tmp目录中提供一些磁盘空间.当容器被冻结时,目录内容仍然存在,提供可用于多次调用的瞬态缓存.您可以添加额外的代码来检查缓存是否包含您存储的数据.

  • 如果AWS Lambda选择重用容器,则Lambda函数启动的后台进程或回调在函数结束时未完成.在代码退出之前,您应该确保代码中的任何后台进程或回调(如果是Node.js)都已完成.

正如您所看到的,在尝试利用容器重用时,Lambda函数的多个并发调用之间绝对没有关于竞争条件的警告.唯一的注意是"不要依赖它!".