Java

Erda 通过统一的任务插件机制支撑不同的构建能力,并利用这一机制提供开箱即用的 Java 构建插件。

Java 版本

平台支持 Java 1.8 和 Java 11,默认为前者。

打包工具

  • Maven
  • Gradle

依赖管理

若使用平台提供的配置文件则无需改动代码。平台打包时将自动准备如下文件并自动填充占位符。

  • Maven: settings.xml
  • Gradle: init.gralde

settings.xml 示例如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  5. <servers>
  6. <server>
  7. <id>terminus</id>
  8. <username>{{NEXUS_USERNAME}}</username>
  9. <password>{{NEXUS_PASSWORD}}</password>
  10. </server>
  11. </servers>
  12. <mirrors>
  13. <mirror>
  14. <id>terminus</id>
  15. <mirrorOf>*</mirrorOf>
  16. <url>{{NEXUS_URL}}/repository/public/</url>
  17. </mirror>
  18. </mirrors>
  19. <profiles>
  20. <profile>
  21. <activation>
  22. <activeByDefault>true</activeByDefault>
  23. </activation>
  24. <repositories>
  25. <repository>
  26. <id>placeholder</id>
  27. <url>{{NEXUS_URL}}/repository/public/</url>
  28. <releases>
  29. <enabled>true</enabled>
  30. </releases>
  31. <snapshots>
  32. <enabled>true</enabled>
  33. <updatePolicy>always</updatePolicy>
  34. <checksumPolicy>warn</checksumPolicy>
  35. </snapshots>
  36. </repository>
  37. </repositories>
  38. <pluginRepositories>
  39. <pluginRepository>
  40. <id>placeholder</id>
  41. <url>{{NEXUS_URL}}/repository/public/</url>
  42. <releases>
  43. <enabled>true</enabled>
  44. </releases>
  45. <snapshots>
  46. <enabled>true</enabled>
  47. <updatePolicy>always</updatePolicy>
  48. <checksumPolicy>warn</checksumPolicy>
  49. </snapshots>
  50. </pluginRepository>
  51. </pluginRepositories>
  52. </profile>
  53. </profiles>
  54. </settings>

init.gradle 示例如下:

  1. def NEXUS_SERVER = "{{NEXUS_URL}}/repository/public/"
  2. def NEXUS_USERNAME = "{{NEXUS_USERNAME}}"
  3. def NEXUS_PASSWORD = "{{NEXUS_PASSWORD}}"
  4. allprojects {
  5. buildscript {
  6. repositories {
  7. maven {
  8. credentials {
  9. username NEXUS_USERNAME
  10. password NEXUS_PASSWORD
  11. }
  12. url NEXUS_SERVER
  13. }
  14. }
  15. }
  16. repositories {
  17. maven {
  18. credentials {
  19. username NEXUS_USERNAME
  20. password NEXUS_PASSWORD
  21. }
  22. url NEXUS_SERVER
  23. }
  24. }
  25. }

推送 JAR 包至私服

上传 maven settings.xml

进入 我的应用 > 选择应用 > 设置 > 流水线 > 变量配置 > 选择环境

点击 增加变量, 选择类型为 文件 并开启加密,将 settings.xml 上传,变量名称定义为 MAVEN_SETTING_FILE

warning 警告 因文件内含有密码等敏感信息,配置必须开启加密。

settings.xml 示例如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  5. <servers>
  6. <server>
  7. <id>terminus</id>
  8. <username>deployment</username>
  9. <password>******</password>
  10. </server>
  11. </servers>
  12. </settings>

配置 pom.xml 推送地址

请在对应项目的 pom.xml 中添加需要如下配置,否则将报错无法推送。

  1. <distributionManagement>
  2. <repository>
  3. <id>terminus</id> <!-- settings.xml 里配置的 server.id -->
  4. <name>Releases</name>
  5. <url>http://私服地址/repository/releases</url> <!-- release 私服的地址 -->
  6. </repository>
  7. <snapshotRepository>
  8. <id>terminus</id>
  9. <name>Snapshots</name>
  10. <url>http://私服地址/repository/releases</url> <!-- snapshot 私服的地址 -->
  11. </snapshotRepository>
  12. </distributionManagement>

配置流水线实现 JAR 包上传

MAVEN_SETTING_FILE 即上文配置的名称。

  1. version: "1.1"
  2. stages:
  3. - stage:
  4. - git-checkout:
  5. alias: git-checkout
  6. params:
  7. depth: 1
  8. - stage:
  9. - java-build:
  10. alias: java-build
  11. version: "1.0"
  12. params:
  13. build_cmd:
  14. - "rm -rf /usr/share/maven/conf/setting.xml"
  15. - "mvn clean deploy -e -B -U --settings ((MAVEN_SETTING_FILE)) -Dmaven.test.skip"
  16. jdk_version: 8
  17. workdir: ${git-checkout}

如需自动触发构建,可增加持续集成配置。

  1. on:
  2. push:
  3. branches:
  4. - develop # 持续集成

tip 提示

  • maven 401 错误即账号密码错误。
  • maven 405 错误可能为私服地址错误,部分私服地址是无法推送的,例如 public。

推送 JAR 包至私服(Gradle)

配置 Nexus 私服密码

进入 我的应用 > 选择应用 > 设置 > 流水线 > 变量配置 > 选择环境

点击 增加变量, 选择类型为 并开启加密,配置以下变量:

  • NEXUS_USERNAME
  • NEXUS_PASSWORD

warning 警告 因文件内含有密码等敏感信息,配置必须开启加密。

配置 build.gradle 推送地址

对应项目的 build.gradle 需增加如下配置,若未添加则会报错无法推送。更多信息请参见 build.gradle 配置方式

  1. publishing{
  2. ...
  3. repositories {
  4. maven {
  5. // change URLs to point to your repos, e.g. http://my.org/repo
  6. def releasesRepoUrl = "http://私服地址/repository/releases"
  7. def snapshotsRepoUrl = "http://私服地址/repository/snapshots"
  8. url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
  9. credentials {
  10. username = System.getenv("NEXUS_USERNAME")
  11. password = System.getenv("NEXUS_PASSWORD")
  12. }
  13. }
  14. }
  15. }

配置流水线实现 JAR 包上传

  1. version: "1.1"
  2. stages:
  3. - stage:
  4. - git-checkout:
  5. alias: git-checkout
  6. params:
  7. depth: 1
  8. - stage:
  9. - java-build:
  10. alias: java-build
  11. version: "1.0"
  12. params:
  13. build_cmd:
  14. - "./gradlew publish"
  15. jdk_version: 8
  16. workdir: ${git-checkout}

如需自动触发构建,可增加持续集成配置。

  1. on:
  2. push:
  3. branches:
  4. - develop # 持续集成

tip 提示

  • maven 401 错误即账号密码错误。
  • maven 405 错误可能为私服地址错误,部分私服地址是无法推送的,例如 public。

接入平台日志

平台仅采集输出至控制台(Console)的日志,因此需应用程序将日志导入控制台。

warning 警告 请勿将日志写入磁盘文件,这可能导致性能下降或者磁盘资源耗尽等严重问题。

通过 Logback 配置,将日志输出至控制台:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration scan="true" scanPeriod="30 seconds">
  3. <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  4. <encoder>
  5. <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZ} [%thread] %-5level %logger{5} - %msg%n</pattern>
  6. </encoder>
  7. </appender>
  8. <root level="DEBUG">
  9. <appender-ref ref="CONSOLE"/>
  10. </root>
  11. </configuration>

若采用平台提供的运行容器,平台将自动关闭 RollingFileAppender 等非 ConsoleAppender 的 appender,以确保日志无法写入磁盘。请确保已配置 ConsoleAppender,否则将无法查看日志。

构建打包

Java 构建分为两部分:

  1. 通过指明的打包方式和上下文参数,将源代码编译为打包产物。
  2. 按照指明的运行环境和版本,选择基础镜像,将 JAR 包制作成运行镜像。

tip 提示 此处特指打包产物而非 JAR 包,原因在于很多场景下编译的结果并非是 JAR 包,例如传统的 Spring MVC 程序产出 WAR 包,gradle distribution 产出的则是 Tar 或者 ZIP 包,通过解压执行 bin/xxx 运行。

通过 Spring Boot 技术制作而成的 JAR 包称为 fat jar,因其 JAR 包中嵌入了除 Java 虚拟机以外的所有依赖,故此得名。

由于 fat jar 是一个 all-in-one 的 JAR 包,因此仅需 Java 虚拟机环境便可通过 java -jar app.jar 直接运行。

pipeline.yml 示例如下:

  1. version: "1.1"
  2. stages:
  3. - stage:
  4. - git-checkout:
  5. - stage:
  6. - java:
  7. params:
  8. build_type: maven
  9. workdir: ${git-checkout}
  10. options: -am -pl user
  11. target: ./user/target/user.jar
  12. container_type: openjdk

打包加速

Gradle

自带 Gradle Cache Node,默认开启。

Caches

示例如下:

  1. - stage:
  2. - java:
  3. caches:
  4. - path: /root/.m2/repository
  5. params:
  6. build_type: maven
  7. workdir: ${git-checkout}
  8. options: -am -pl user
  9. target: ./user/target/user.jar
  10. container_type: openjdk

/root/.m2/repository 目录为 Linux 中 Maven 本地仓库的地址,缓存过后即可进行加速构建。

JVM 诊断

Arthas

可以通过 curl -sf https://arthas.aliyun.com/arthas-boot.jar -o arthas-boot.jar 命令安装 arthas。 安装成功后,根据安装目录,执行 java -jar arthas-boot.jar 命令启动。

关于 Arthas 更多信息,请参见 Arthas 用户文档

Greys

若使用平台提供的运行容器,则已安装 Greys。

关于 Greys 更多信息,请参见 Greys 文档

远程调试&热更新

平台提供 VPN 的方式,支持本地远程连接平台上运行的服务。

为开启远程调试,需进入 我的应用 > 选择应用 > 设置 > 流水线 > 变量配置,添加 JAVA_OPTS 变量配置如下:

JDK 9 及以上:

  1. JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

JDK 5~8:

  1. JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

此外,如需使用本地 IDE 进行连接,请进入 DevOps 平台 > 应用中心 > 环境部署 查看需调试的容器 IP,在 IDE 新建 Remote 配置如下:

JDK 9 及以上:

Java - 图1

JDK 5~8:

Java - 图2