技术栈使用指南

在代码开发阶段,开发人员在开发环境中,通过特定的开发框架及特定的配置,完成了对预期功能的实现。在生产环境中,为了实现高效、低成本、更安全的部署,一般可以选择将应用部署到云端。云端通过技术栈为应用提供框架和 runtime 等运行环境支持,包括提供运行所需的脚本并且安装 JDK、Tengine 环境依赖等。

什么是应用

按照官网文档 创建工程 创建的 SOFABoot 工程,通过 编译运行,在本地被打包为 {XXX}-executable.jar 文件,并存放于工程根目录的 target 目录中。这个 fat JAR 文件,在 SOFAStack 平台上,就是一个应用。在云端,应用需要和其运行的环境进行关联,才能实现预期功能。应用和技术栈的关联方式,请参见 关联技术栈与应用服务

什么是技术栈

在 SOFAStack 平台上,技术栈 指一个应用程序所依赖的全部框架及附属资源的集合,它定义了应用发布部署和运维时的依赖信息,主要包括下述内容:

  • 操作系统和版本

  • 开发框架类型和版本

  • 应用启动和部署脚本

  • 环境参数

官方技术栈下载

请单击获取 官方技术栈

技术栈命名规则

发布应用时,一旦选定技术栈架构,则不可再更改,但可更新该架构下的技术栈版本号以获取最新功能。每个技术栈架构都有对应的技术栈,随着功能迭代和需求变更,该技术栈产生了各种不同的版本。

以技术栈 SOFA_Boot_1.0.7-j180t2114 为例,对 SOFABoot 技术栈的命名规则说明如下:

  • 1.0.7:指技术栈的版本。

    更多版本信息,请参见 版本说明

  • j180:指 JDK 版本 1.8.0(技术栈中更具体的是 1.8.0_131,不是 ajdk,也不支持协程)。

  • t2114: 指 tengine 版本 2.1.14。

开发框架与技术栈

对于开发框架 SOFABoot 3.x,其所支持的技术栈及推荐的技术栈信息如下:

  • JDK 版本:≥ JDK 8

  • 技术栈版本:≥ 1.0.6-j180t2114

开发框架与所支持的技术栈配置关系图:

关系图
说明

开发框架 SOFABoot 3.x 下,推荐的技术栈版本为 1.0.7。

技术栈目录结构

技术栈目录包含以下子文件夹:

  • conf/:存放技术栈配置文件。为可选文件,内容可以为空。

  • lifecycle/:存放生命周期代码。理论上您可以使用任何语言来编写这些生命周期脚本。lifecycle 目录下所有文件名必须以专属前缀 ac_ 开头,且没有后缀。目前,下述文件的命名为固定命名:

    • ac_setup:技术栈依赖的安装脚本,主要代码逻辑为读取 resources 目录下的文件,解压、安装、配置环境变量等。

    • ac_init_env:可选。用于部署前的相关任务处理。

    • ac_deploy:应用程序包的启动脚本。核心启动命令为:java -jar appname.jar

    • ac_check_service:可选。检测应用是否启动。

    • ac_shutdown:停止应用。

  • resources/:存放技术栈的依赖、生命周期代码的依赖等。如果您的技术栈足够简单,无需任何依赖,resources 文件夹可以为空。

示例

默认提供的 sofaboot-1.0.7 技术栈包的文件结构如下:

sofaboot_buildpack_1.0.7-j180t2114        // 默认没有 conf 文件夹
├── lifecycle                            // 生命周期代码
│├── ac_setup
│├── ac_init_env
│├── ac_deploy
│├── ac_check_service
│└── ac_shutdown
└── resources                            // 技术栈和生命周期代码的依赖
├── centos6.5// 该技术栈在 CentOS 6.5 操作系统上的依赖
│├── cronolog-1.7.0-0.x86_64.rpm
│├── jdk-1.8.0_131-normal-1.x86_64.rpm
│├── nginx-gray-module-0.0.2.rpm
│└── tengine-2.0.0-12298.el6u0.x86_64.rpm
├── centos7.2// 该技术栈在 CentOS 7.2 操作系统上的依赖
│├── cronolog-1.7.0.tgz
│├── jdk-1.8.0_131-normal-1.x86_64.rpm
│├── nginx-gray-module-0.0.2.rpm
│└── tengine-proxy-2.1.14.rpm
├── check_service.sh
├── deploy.sh
├── nginx.sh
├── stopApp.sh
├── util.py
└── util.sh

制作技术栈压缩包

技术栈打包的操作步骤如下:

  1. 创建 技术栈目录结构

  2. 在目录下创建技术栈生命周期脚本和相关依赖。

  3. 将目录下所有脚本和相关依赖压缩成 .tgz 文件,生成技术栈包。在以下示例中,假定技术栈目录名为 sofaboot-buildpack

    $ cd sofaboot-buildpack
    $ tar -cvzf sofaboot-buildpack.tgz ./*
    // ./* 表示:将当前目录下的所有文件打包
    说明

    .tgz 文件的名称与实际的技术栈名称无关。

技术栈与应用发布流程

将应用打包上传到 SOFAStack 平台,实现部署的发布方式请参见 关联技术栈并发布应用

技术栈支持的功能

发布 SOFABoot 应用时,您必须 将应用关联至技术栈 才能使用。SOFABoot 技术栈支持以下功能:

  • 使用 java -jar {XXXXX-executable.jar} 命令启动 JAR 文件。{XXXXX-executable.jar} 为工程编译运行后生成的 fat JAR 文件。JAR 文件在 ECS 服务器上的路径为:

    • 默认上传路径: /home/admin/release/run

    • 可执行文件路径:/home/admin/app-run

  • 支持在云端部署时通过 -D 动态参数来指定配置中心地址。默认会拼接注册中心的地址,并传递给 Java 进程。

  • 支持在代码中设置 java_opts 作为 JVM 的启动参数。详见 JVM 参数配置

  • 根据当前 ECS 所在的工作空间名,即 /etc/metafile 文件中的 workspace_nametenant_name,指定启动参数。详见 技术栈配置方案

  • 使用 tenginx-conf/tengine.conf 文件配置 Tengine 启动参数。详见 Tengine 静态配置

  • 如果应用发布后没有检测到 java -jar 进程,则在健康检查阶段会返回失败。

  • com.alipay.confreg.url 配置项指定配置中心的地址,仅对开通 VPN 或专线的租户有效。当应用部署至阿里云 ECS 时,技术栈会自动完成此设置。如有需要,您可通过 -D 参数指定此配置项。

  • 支持对自定义健康检查设置端口。配置方式:在应用实例环境参数中配置 ac.healthcheck.port

  • 支持对自定义健康检查设置超时时间。配置方式:在应用实例环境参数中配置 ac.healthcheck.timeout,单位为秒。

技术栈配置方案

我们约定把所有环境相关的配置,放在应用代码中可部署模块的 resources 目录下。其中,可部署模块指的是使用 spring-boot-maven-plugin 打包出 fat JAR 的模块,例如 SOFABoot Web 工程中的 Web 模块。

properties 配置

单环境

通过 resources/config/application.properties 即可实现全局配置。

多环境

开发者在项目发布前,可能需要频繁地在开发环境、测试环境、预发布环境、生产环境之间进行切换,通过 profile 的配置,您可以在使用同一套代码的情况下,为不同的工作空间提供相应配置,省去了多次打包的麻烦。根据 SOFABoot 技术栈版本的不同,配置方式有稍微变化。

配置文件生效优先级,完全参考了 Spring Boot 的 Profile 机制。更多详情,请参见 Profiles

多环境下的配置步骤如下:

  1. 登录云端服务器,在 /etc/mefile 中查询 tenant_nameworkspace_name 信息。

    说明

    在新版迭代后,将支持在 SOFAStack 控制台一键查询上述信息,敬请期待。

  2. 在本地工程的 resources/config/ 目录下创建多个 properties 文件。

    • 创建 租户空间的配置文件:命名格式为 application-{tenant_name}_{workspace_name}.properties

      • {tenant_name} 为租户名。其值来自于 /etc/metafile 文件中的 tenant_name

      • {workspace_name} 为工作空间名。其值来自于 /etc/metafile 文件中的 workspace_name

      • 示例:假定租户名 {tenant_name}=tenant1234, 工作空间名 {workspace_name}=dev,则命名格式为:application-tenant1234_dev.properties。其中,命名中第一个分割符为短横线,第二个分隔符为下划线。

    • 自定义配置文件:可以自定义多个 properties 文件。

      • 命名方式application-{profile}.properties,其中 {profile} 为占位符,表示自定义工作空间名。

      • 配置方式:需在 application.properties 中添加键值对: spring.profiles.include={profile1},{profile2}。其中 {profile} 为占位符,多个 {profile} 之间用英文逗号分隔。

      • 示例:假定自定义工作空间名为 testDev 和 testProd,则命名格式为:application-testDev.propertiesapplication-testProd.properties

  3. 将本地工程打包、上传到云端服务器,进行发布。详情参见 技术栈与应用发布流程

  4. 执行命令,让期望的配置文件生效。生效方式有下述默认和自定义 2 种:

    • 默认方式:服务器启动时,默认执行的命令为 -Dspring.profiles.active={workspace_name},{tenant_name}_{workspace_name}

    • 自定义生效方式:具体操作见下述步骤。

      1. 在云端服务器,通过远程连接,执行 cd /home/admin/app-run 命令,进入应用发布包所在目录。

      2. 执行命令 java -jar -Dspring.profiles.active={profile} xxxxx-executable.jar。其中的参数说明如下:

        • {profile} 为占位符,表示期待生效的工作空间。

        • xxxxx-executable.jar/home/admin/app-run 目录下的发布包的名称。

日志配置

配置路径

配置文件都在可部署模块下。可部署模块指使用 spring-boot-maven-plugin 打包的模块,例如 SOFABoot Web 工程中的 Web 模块。日志的配置文件路径为: resources/logback-spring.xml

配置文件名称来源

由于 SOFA 中间件技术栈对日志配置的解决方案使用 Spring Boot,需要引入 Maven 依赖 spring-boot-starter-logging,此依赖默认使用 logback.xml 进行日志打印,因此日志配置文件的名称使用 logback-spring.xml

日志依赖

  • 日志对应的依赖为:spring-boot-starter-logging

  • 此依赖默认使用 logback 进行日志打印。

  • 按照官网文档 创建工程 创建的 SOFABoot 工程,在可部署模块下的 pom.xml 文件中,默认已经引入该依赖。

生效方式

  • logback-spring.xml 配置文件中增加 <springProfile> 标签并使用 name={profile1,profile2} 属性来定义该段配置对应的运行环境。

  • application.properties 中配置:spring.profiles.active={profile}。只要 profile 中包含有 name 对应的值,配置就会被激活。

示例如下:

<springProfile name="dev,test">
    <appender name="DEV-TEST-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        ...
     </appender>
</springProfile>
  • springProfile 对应的环境为 dev,test

  • application.properties 中配置:spring.profiles.active=devspring.profiles.active=test后,这段配置被激活。

  • 激活后,<appender> 标签中定义的 DEV-TEST-APPENDER 可以通过 <appender-ref> 标签被引用。

Tengine 静态配置

可以使用 Tengine 静态配置文件来配置下述内容:

  • 资源的访问

  • 指定端口流量的转发

配置路径

配置文件都在可部署模块下。可部署模块指使用 spring-boot-maven-plugin 打包的模块,例如 SOFABoot Web 工程中的 Web 模块。

  • Tengine 配置文件路径:tenginx-conf/tengine.conf

  • 打包路径:BOOT-INF/classes

生效方式

当使用 SOFABoot 技术栈在 SOFAStack 平台上自动发布部署时,技术栈会读取 tenginx-conf/tengine.conf 中的配置,并按配置来启动 tengine。

JVM 参数配置

JVM 配置需求

在不同的 ECS 上启动应用时,需要指定的堆大小也可能不一致,这就产生了按照 ECS 内存大小,来选择不同 JVM 参数的需求。

JVM 配置规则

您可以通过提供多份 java_opts 开头的文件来设置不同 ECS 上的 JVM 参数。

关于 java_opts 文件,约定规则如下:

  • 存放路径:应用代码的 src/main/resources 目录下。即需要部署的 fat JAR 包中的 classpath 根目录下。

  • 多文件支持:有多份该文件时,文件名称以 java_opts 开头,以内存大小标识作为后缀,且内存大小为整数。如 java_opts_2gjava_opts_4g等。

  • 默认处理

    • 如果找不到正确的 java_opts_?g 文件,默认读取 java_opts 文件。

    • 如果不存在 java_opts 文件,则相当于没有任何 JVM 参数。

Shell 脚本 Hook 的配置

Hook 配置需求

SOFABoot 技术栈支持在应用代码中添加 hook 脚本。您可以通过添加 hook 脚本使应用在启动 Java 程序前执行其它操作,例如:启动一个 python 脚本,将一个 .so 文件添加到环境变量中等。在部署应用时,技术栈会调用这些脚本中的函数。

Hook 配置规则

hook 脚本配置规则如下:

  • 脚本路径:必须为 src/main/resources/hook.sh。即脚本需要部署在 fat JAR 包(即可部署模块)中的 classpath 根目录下。

  • 调用时机:在 hook.sh 脚本中声明待被调用的函数,不同函数名对应不同的调用时机:

    • before_appstart_hook:应用启动前

    • after_appstart_hook:应用启动后

    • 其他名字的函数不会被调用

  • 其它执行逻辑:hook.sh 脚本中,除了 Shell 函数的声明以外,不要有其它执行逻辑,否则每次在调用 hook 函数时都会触发这些执行逻辑。

  • 如果不需要这个功能,可以不提供 hook 脚本。

hook.sh 示例:

function before_appstart_hook {
    echo 'before_appstart_hook executed'
}

function after_appstart_hook {
    echo 'after_appstart_hook executed'
}