本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载自夜明的孤行灯
本文链接地址: https://www.huangyunkun.com/2016/10/30/run-spring-boot-in-aws-lambda/
AWS Lambda 是一种计算服务。首先将代码上传到 AWS Lambda ,它按使用时间收费,有自动伸缩等功能,也就是说你上传了代码,其他事情你就不用管了。
从字面上看你上传的代码是一个函数,那么就需要一个触发器来调用你的函数。AWS提供了若干触发器,其中就有API Gateway。这意味着你可以暴露一个HTTP或者HTTPS的调用地址,然后执行对应的函数。
因为AWS Lambda有自己的一些要求,所以很明显是无法直接运行Spring Boot应用的,需要修改一下入口才能实现对应的功能。
首先在依赖中加入aws的依赖
compile group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.48'
这个依赖中包含了我们必须实现的接口RequestHandler
package com.amazonaws.services.lambda.runtime; import com.amazonaws.services.lambda.runtime.Context; /** * * Lambda request handlers implement AWS Lambda Function application logic using plain old java objects * as input and output. * * @param <I> The input parameter type * @param <O> The output parameter type */ public interface RequestHandler<I, O> { /** * Handles a Lambda Function request * @param input The Lambda Function input * @param context The Lambda execution environment context object. * @return The Lambda Function output */ public O handleRequest(I input, Context context); }
所以新建一个Runner类
@Configuration @EnableAutoConfiguration @ComponentScan("你自己的包名") public class Runner implements RequestHandler<Void, PersonsVO> { private Logger logger = LoggerFactory.getLogger(this.getClass()); private static ConfigurableApplicationContext applicationContext; @Override public PersonsVO handleRequest(Void input, Context context) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); logger.info("Start !"); ApplicationContext applicationContext = getApp(); logger.info("Spring boot load finished."); stopWatch.stop(); logger.info("Time is {}", stopWatch.toString()); T t = applicationContext.getBean(你需要的类.class); return t.function(); } private ConfigurableApplicationContext getApp() { if (applicationContext == null) { applicationContext = new SpringApplicationBuilder() .main(getClass()) .bannerMode(Banner.Mode.OFF) .web(false) .sources(getClass()) .addCommandLineProperties(false) .build() .run(); } return applicationContext; } }
其实原理很简单,因为入口变了,所以只有自己启动Spring上下文,然后调用。
AWS Lambda标榜的是自己调用了就会回收,但是从观察来看,似乎会保持当前的环境和状态一段时间,所以我们可以再调用的时候先判断一下有没有Spring上下文,如果有就直接使用,没有才加载。
首次请求真的很慢,因为Spring需要生成上下文,如果你还用了hibernate这些,那启动速度轻轻松松达到10s,但是这之后的时间就很快了,因为环境中已经有Spring上下文了。如果很久之后你的函数再被触发,那么又需要重新加载了。
总的来说一个普通的Spring Boot应用是很难直接迁移到AWS Lambda的,虽然能够工作,但是响应时间和包大小很难接受。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载自夜明的孤行灯
本文链接地址: https://www.huangyunkun.com/2016/10/30/run-spring-boot-in-aws-lambda/