全部产品
云市场

Java HTTP 触发器一键部署 SpringBoot 应用

更新时间:2019-07-16 09:46:56

函数计算平台针对 Java 语言推出的 Java HTTP 触发器功能,能够无缝迁移传统的 Java Web 应用。支持基于 Servlet 协议的 Web 框架所开发应用,比如常用的 Spring、SpringBoot、Struts2等。本文介绍如何使用 Java HTTP 触发器来快速迁移 SpringBoot 应用,并使用函数计算提供的 fun 工具 做到真正一键部署。

您可以直接下载 SpringBoot 集成到函数计算示例代码 测试运行

迁移 SpingBoot 到函数计算需以下步骤:

  1. 添加 FC 入口函数
  2. 添加 SpringBootServletInitializer 入口
  3. 配置打包方式
  4. 部署服务和函数
  5. 测试运行

1. 添加 FC 入口函数

在 SpringBoot 工程中添加 FC 的函数入口和函数初始化入口,代码如下:

FcHandler.java

  1. public class FcHandler implements FunctionInitializer, HttpRequestHandler {
  2. private AppLoader fcAppLoader = new FcAppLoader();
  3. // Request url web path
  4. // 1. Without custom domain: /2016-08-15/proxy/${YourServiceName}/${YourFunctionName}
  5. // 2. With custom domain: your mapping settings path
  6. private String userContextPath = System.getenv("USER_CONTEXT_PATH");
  7. // Webapp home directory after inited
  8. // Default "/tmp"
  9. private String appBaseDir = System.getenv("APP_BASE_DIR");
  10. @Override
  11. public void initialize(Context context) throws IOException {
  12. FunctionComputeLogger fcLogger = context.getLogger();
  13. // Config FcAppLoader
  14. fcAppLoader.setFCContext(context);
  15. if (appBaseDir != null) fcAppLoader.setBaseDir(appBaseDir);
  16. // Load code from /code
  17. fcLogger.info("Begin load code");
  18. fcAppLoader.loadCodeFromLocalProject("");
  19. fcLogger.info("End load code");
  20. // Init webapp from code
  21. long timeBegin = System.currentTimeMillis();
  22. fcLogger.info("Begin load webapp");
  23. boolean initSuccess = fcAppLoader.initApp(userContextPath, FcHandler.class.getClassLoader());
  24. if(! initSuccess) {
  25. throw new IOException("Init web app failed");
  26. }
  27. fcLogger.info("End load webapp, elapsed: " + (System.currentTimeMillis() - timeBegin) + "ms");
  28. }
  29. @Override
  30. public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context)
  31. throws IOException, ServletException {
  32. try {
  33. fcAppLoader.forward(request, response);
  34. } catch (Exception e) {
  35. e.printStackTrace();
  36. }
  37. }

2. 添加 SpringBootServletInitializer 入口

要让 FC 成功加载 SpringBoot,需要为 SpringBoot 配置 ServletInitializer 接口来指向 Application 入口类:

Application.java

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. @SpringBootApplication
  4. public class Application {
  5. public static void main(String[] args) {
  6. SpringApplication.run(Application.class, args);
  7. }
  8. }

SpringBootStartApplication.java

  1. public class SpringBootStartApplication extends SpringBootServletInitializer {
  2. @Override
  3. protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
  4. return builder.sources(Application.class);
  5. }
  6. }

3. 配置打包方式

请参考 Java 代码打包 在 pom.xml 中增加如下配置:

  1. <!-- Exclude springboot embeded server-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. <exclusions>
  6. <exclusion>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-tomcat</artifactId>
  9. </exclusion>
  10. </exclusions>
  11. </dependency>
  12. <!-- Package plugin -->
  13. <build>
  14. <plugins>
  15. <plugin>
  16. <groupId>org.apache.maven.plugins</groupId>
  17. <artifactId>maven-dependency-plugin</artifactId>
  18. <executions>
  19. <execution>
  20. <id>copy-dependencies</id>
  21. <phase>prepare-package</phase>
  22. <goals>
  23. <goal>copy-dependencies</goal>
  24. </goals>
  25. <configuration>
  26. <outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
  27. <includeScope>runtime</includeScope>
  28. </configuration>
  29. </execution>
  30. </executions>
  31. </plugin>
  32. <plugin>
  33. <groupId>org.apache.maven.plugins</groupId>
  34. <artifactId>maven-compiler-plugin</artifactId>
  35. <configuration>
  36. <source>${project.java.version}</source>
  37. <target>${project.java.version}</target>
  38. </configuration>
  39. </plugin>
  40. </plugins>
  41. </build>

4. 部署服务和函数

最后,只需在 FC 平台创建服务和函数,以及 HTTP 触发器即可。可使用 fun 工具 来自动化创建过程,对应的 yml 配置如下:

  1. ROSTemplateFormatVersion: '2015-09-01'
  2. Transform: 'Aliyun::Serverless-2018-04-03'
  3. Resources:
  4. # Create Service
  5. demo-springboot-service:
  6. Type: 'Aliyun::Serverless::Service'
  7. Properties:
  8. Description: 'Hello SpringBoot On FC'
  9. Policies:
  10. - AliyunOSSFullAccess
  11. - AliyunLogFullAccess
  12. LogConfig:
  13. Project: ${YOUR_LOPROJECT} # Need to modify
  14. Logstore: ${YOUR_LOGSTORE} # Need to modify
  15. InternetAccess: true
  16. # Create function
  17. demo-springboot:
  18. Type: 'Aliyun::Serverless::Function'
  19. Properties:
  20. Initializer: hello.FcHandler::initialize
  21. Handler: hello.FcHandler::handleRequest
  22. Runtime: java8
  23. CodeUri: './target/demo-springboot-hello-1.0.0.jar'
  24. MemorySize: 256
  25. Timeout: 60
  26. InitializationTimeout: 60
  27. EnvironmentVariables:
  28. 'USER_CONTEXT_PATH': '/2016-08-15/proxy/demo-sprinboot-service/demo-springboot'
  29. 'APP_BASE_DIR': '/tmp'
  30. # Create http trigger
  31. Events:
  32. http: # trigger name
  33. Type: HTTP # http trigger
  34. Properties:
  35. AuthType: ANONYMOUS
  36. Methods: ['GET', 'POST']

执行

  • mvn clean package
  • fun deploy

即可部署成功

5. 测试函数运行

使用 curl 命令访问上述 deploy 生成的 url 地址:

  1. curl https://{account_id}.{region}.fc.aliyuncs.com/2016-08-15/proxy/demo-springboot-service/demo-springboot/

成功返回 SpringBoot 页面springboot