AWS Java Lambda 与环境变量

一句话概要:对 Lambda 环境变量的任何改动都会引起一次 Lambda 的冷启动,大可放心在 handleRequest(...) 方法外使用环境变量。

AWS 上 Java Lambda 应用记要 中,我学到了 Lambda 的实例是跨请求共享的,所以为使用 Lambda 配置的环境变量时曾写出了下面复杂而多余的  AWS  Lambda 代码:

public class Handler implements RequestHandler<SNSEvent, String> {

    private int threadPoolSize = getThreadPoolSizeFromEnv();
    private ExecutorService threadPool = Executors.newFixedThreadPool(threadPoolSize);

    @Override
    public String handleRequest(SNSEvent snsEvent, Context context) {

        int configuredThreadPoolSize = getThreadPoolSizeFromEnv();
        if(configuredThreadPoolSize != threadPoolSize) {
            threadPoolSize = configuredThreadPoolSize;
            threadPool = Executors.newFixedThreadPool(threadPoolSize);
        }

        return "Hello Lambda";
    }

    private int getThreadPoolSizeFromEnv() {
        return Integer.parseInt(System.getenv().getOrDefault("threadpool_size", "50"));
    }
}

这段代码看起来很在理,既然 Lambda 实例是共享的,那么在必变环境变量之后就可能不会重新初始始化实例,所以在每次的请求方法中对比如果环境变量值改动了就重新用最新的配置值来初始化线程池。然而上面的代码结结实实是多余的,真是把 Lambda 想得太简单了,如果是很多环境变量岂不是逐一判断。 阅读全文 >>

AWS Java Lambda 使用 Logback 记录日志

直接一句话:去掉 Log4J 的依赖,把  Slf4J, Logback, 和 log4j-over-slf4j 依赖加进来就行了,配置文件换成 logback.xml,这就完了,不要往下看了,都是些废话。

当我们用 Serverless 命令 sls create -t aws-java-maven -p hello-lambda 创建的示例项目中直接用的是 Log4J 日志组件,而且也没用像  Slf4j, 或 Apache Common Logging 更上一层的通用日志框架。查看了几个 AWS 本身的组件 S3, SNS, 和 Kinesis 的 SDK, 它们内部是用的 Apache Common Logging 声明的日志变量

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Logger;

private static final Log log = LogFactory.getLog(AmazonKinesis.class)

而我们自己的组件中通用日志组件是 Slf4j, 底层实现为 Logback, 所以我们希望在 Lambda 中使用 Logback 来写日志。

选用一个通用日志框架总是明智之举,因为一个项目经常杂糅了多种日志实现,使用 Slf4J 或 Apache Common Logging 可以把它们(Log4J, Logback, 或更多)输出到共同的目的地,并且有统一的日志输出接口。而我们认为通用日志框架还是 Slf4J 要先进些,所以我们在 Java Lambda 中的日志方案是 Slf4J + Logback,还需要把 Log4J 的日志桥接到 Slf4J 上来,再经由 Logback 输出。

回到前面创建的 hello-lambda 项目,看其中怎么用的 Log4J,先瞧瞧 pom.xml 文件怎么引入的 Log4J, 它是间接通过一个 AWS 定义的 Log4J Appender 引入的 阅读全文 >>

AWS 上 Java Lambda 应用记要

AWS 的 Lambda 给了那些不想自己管理 EC2 服务器和配置负载人员很大的便利,所以 Lambda 被描述为 Serverless。真正的只关注业务就行,怎么调度,同时有多少个实例运行交给亚马逊去处理就是了。运行 Lambda 的环境也是亚马逊内部的 EC2 服务器,镜像是 Amazon Linux, 所以如果想运行系统命令,那是 Linux 的。Lambda 支持多种语言 Node.js, Python, C#(.net core), 还有 Java 8,我们就选择了 Java 8, 一开始还担心它与别的语言比起来会多大劣势,其实不然。而且所谓的 Java 8, 并非单指 Java 语言,而是指 JVM 平台,所以也可以用 Scala, Clojure, Groovy, Kotlin 来写。

Java 与脚本语言如 Node.js, Python 相比给人一个明显的感觉是启动慢,还有人用统计数据来比划 AWS Lambda cold start(pseudeo-)benchmark. 不过真不用担心,人家说的是冷启动,也就发生在部署后第一次执行启动会比较慢。要是我们的 Lambda 经常被调用,或每天触发比较集中,Lambda 在任务到来之前处理待续状态,就不会有冷启动的耗时过程。或者是每次任务要执行 3 分钟左右,又何必在乎毫秒级的冷启动时间。

说到底就是别理会下面的数据

  • 20ms startup time for Python ~ $0.041675
  • 40ms startup time for Node.js ~ $0.08335
  • 80ms startup time for Java ~ $0.1667

Lambda 实例重用

Java 的 Lambda 就是一个微服务,在首次触发时微服务冷启动有些慢,但一旦启动之后就可以用这个微服务实例接受后续的请求,只有在比较长的一段时间内未被触发 AWS 才会把这个微服务杀掉。 阅读全文 >>

代码整洁之道(Clean Code) 笔记(一)

第一章:整洁代码

  1. 代码即设计
  2. 童子军军规:把露营地清理得比来时还干净,签入代码前是否已做重构
  3. 你湎自行实践,且体验自己失败。你须观察他人的实践与失败
  4. 勒布朗(LeBlanc) 法则:稍后等于永不 (Later equals never)
  5. 赶上期限的唯一方法--做得快的唯一方法--就是始终尽可能保持代码整洁
  6. 缺乏“代码感”的程序员,看混乱是混乱,无处着手。有“代码感”的程序员能从混乱中看出其他的可能与变化
  7. 不好的代码引诱别人做没规矩的优化,搞出一堆混乱来
  8. 整洁的代码只做好一件事,糟糕的代码想做太多事,它意图混乱,目的含混
  9. 整洁的代码从不隐藏设计者的意图
  10. 整洁的代码只提供一种而非多种做一件事的途径
  11. 整洁的代码总是看起来像是某位特别在意它的人写的
  12. 回放我们编码过程显示,多多数时间都是在滚动屏幕,浏览其他模块
  13. 读与写花费时间的比例超过 10:1, 写新代码时,我们一直在读旧代码
  14. 编写代码的难度,取决于读周边代码的难度 阅读全文 >>