玩转阿里云函数计算(三)——一键配置 SpringBoot 应用-阿里云开发者社区

开发者社区> 阿里云Serverless Compute> 正文

玩转阿里云函数计算(三)——一键配置 SpringBoot 应用

简介: 前言 阿里云函数计算 Function Compute(FC),旨在帮助用户采用弹性伸缩、动态分配资源的方式,来执行业务函数。让用户无需购买部署服务器,无需考虑业务负载,就能快速搭建可处理高并发的后台服务。

前言

阿里云函数计算 Function Compute(FC),旨在帮助用户采用弹性伸缩、动态分配资源的方式,来执行业务函数。让用户无需购买部署服务器,无需考虑业务负载,就能快速搭建可处理高并发的后台服务。
函数计算平台针对 Java 语言推出的 Java HTTP 触发器功能,能够无缝迁移传统的 Java Web 应用。支持基于 Servlet 协议的 Web 框架所开发的应用,比如常用的 Spring、SpringBoot、Struts2等。

本文介绍如何使用 Java HTTP 触发器来快速迁移 SpringBoot 应用 demo-springboot-hello,并使用函数计算提供的 fun 工具 来快速部署。

继续本文之前,建议先阅读

  1. 玩转阿里云函数计算(一)——Java Http 触发器极速迁移传统 Spring 应用
  2. 玩转阿里云函数计算(二)——Java Http 触发器极速迁移传统 SpringBoot 应用

相关链接

开始部署

SpringBoot 集成到函数计算平台 (FC) 有两种方式可选择:

  1. 将 FC 函数入口集成到 SpringBoot 工程
  2. 独立开 FC 函数入口和 SpringBoot 工程

方式 一 较为简单真正做到一键部署,但函数计算上传的 代码包大小 有限制 50 M,可提工单调整。
方式 二 独立的将 SpringBoot 工程打包成 war 包,并将函数入口工程打包成 jar 用来创建函数和加载 web 工程的 war 包。这种方式较为灵活,不受代码包限制,但需要额外的创建一个函数入口工程。

方式一、集成函数入口到 SpringBoot 工程

您可以直接下载 SpringBoot 集成到函数计算示例代码 测试运行
发布 SpringBoot 工程到函数计算需要以下步骤:

1. 增加 FC 入口函数

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

FcHandler.java

public class FcHandler implements FunctionInitializer, HttpRequestHandler {
  private AppLoader fcAppLoader = new FcAppLoader();
  
  // Request url web path
  // 1. Without custom domain: /2016-08-15/proxy/${YourServiceName}/${YourFunctionName}
  // 2. With custom domain: your mapping settings path
  private String userContextPath = System.getenv("USER_CONTEXT_PATH");
  
  // Webapp home directory after inited
  private String appBaseDir = System.getenv("APP_BASE_DIR");
  
  @Override
  public void initialize(Context context) throws IOException {
      FunctionComputeLogger fcLogger = context.getLogger();
      
      // Config FcAppLoader
      fcAppLoader.setFCContext(context);
      if (appBaseDir != null) fcAppLoader.setBaseDir(appBaseDir);
      
      // Load code from /code
      fcLogger.info("Begin load code");
      fcAppLoader.loadCodeFromLocalProject("");
      fcLogger.info("End load code");
      
      // Init webapp from code
      long timeBegin = System.currentTimeMillis();
      fcLogger.info("Begin load webapp");
      boolean initSuccess = fcAppLoader.initApp(userContextPath, FcHandler.class.getClassLoader());
      if(! initSuccess) {
          throw new IOException("Init web app failed");
      }
      fcLogger.info("End load webapp, elapsed: " + (System.currentTimeMillis() - timeBegin) + "ms");
  }
  
  @Override
  public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context)
          throws IOException, ServletException {
      try {
          fcAppLoader.forward(request, response);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

2. 增加 SpringBootServletInitializer 入口

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

public class SpringBootStartApplication extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
      return builder.sources(Application.class);
  }
}

3. 配置打包方式

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

<!-- Specify tomcat version to 8.5.20 -->
<properties>
<project.java.version>1.8</project.java.version>
<tomcat.version>8.5.20</tomcat.version>
</properties>

<!-- Exclude springboot embeded server-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
    <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
</exclusions>
</dependency>

<!-- Package plugin -->
<build>
  <plugins>
       <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-dependency-plugin</artifactId>
          <executions>
              <execution>
                  <id>copy-dependencies</id>
                  <phase>prepare-package</phase>
                  <goals>
                      <goal>copy-dependencies</goal>
                  </goals>
                  <configuration>
                      <outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
                      <includeScope>runtime</includeScope>
                  </configuration>
              </execution>
          </executions>
      </plugin>
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
              <source>${project.java.version}</source>
              <target>${project.java.version}</target>
          </configuration>
      </plugin>
  </plugins>
</build>

4. 创建服务和函数

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

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
# Create Service
demo-springboot-service:
  Type: 'Aliyun::Serverless::Service'
  Properties:
    Description: 'Hello SpringBoot On FC'
    Policies:
      - AliyunOSSFullAccess
      - AliyunLogFullAccess

    LogConfig:
      Project: hyt-proj
      Logstore: hyt-store

    InternetAccess: true

  # Create function
  demo-springboot:
    Type: 'Aliyun::Serverless::Function'
    Properties:
      Initializer: hello.FcHandler::initialize
      Handler: hello.FcHandler::handleRequest
      Runtime: java8
      CodeUri: './target/demo-springboot-hello-1.0.0.jar'
      MemorySize: 256
      Timeout: 60
      InitializationTimeout: 60
      EnvironmentVariables:
        'USER_CONTEXT_PATH': '/2016-08-15/proxy/demo-sprinboot-service/demo-springboot'
        'APP_BASE_DIR': '/tmp'
    
    # Create http trigger
    Events:
      http: # trigger name
        Type: HTTP # http trigger
        Properties:
            AuthType: ANONYMOUS
            Methods: ['GET', 'POST']

执行

  • mvn clean package
  • fun deploy

即可部署成功

方式二、分离函数入口工程和 SpringBoot 工程

1. 打包需要迁移的 SpringBoot 工程为 war 包

demo-springboot-hello 示例代码

在源码根目录执行 maven 打包命令 maven clean package。打包成功后,在 target 目录下生成 demo-springboot-hello-1.0.0.war 这个文件。

2. 上传 war 包到 OSS 服务

具体怎么上传 OSS 请参考:上传文件到 OSS

3. 下载示例代码并部署

  • 下载 fc-demo-springboot 示例代码
  • 配置 OSS
    假设上传 OSS 的 war 包对应信息为:

    endpoint: oss-cn-hangzhou.aliyuncs.com
    bucket:   fc-test-hyt
    key:      demo-springboot-hello-1.0.0.war

    修改示例代码中 template.yml 中环境变量配置:
    image

  • 部署
    在示例代码根目录执行 fun deploy 即可

测试函数运行

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

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

成功返回 SpringBoot 页面
image

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
阿里云Serverless Compute
使用钉钉扫一扫加入圈子
+ 订阅

Serverless微服务应用实践分享

函数计算官网