我们已经到了旅程的终点。在上一章中,我们编写了一些测试来确认我们的代码工作正常。在本章中,我们会将 Spring 应用程序发布到生产环境中。我们将介绍如何逐步发布它的示例,并为您提供有关此主题的进一步阅读的指南和建议。
在本书的最后一章中,我们将介绍以下内容:
- What will be deployed?
- Deployment options
- Deploying to the Cloud (AWS)
我们已经到了旅程的终点。在上一章中,我们编写了一些测试来确认我们的代码工作正常。在本章中,我们会将 Spring 应用程序发布到生产环境中。我们将介绍如何逐步发布它的示例,并为您提供有关此主题的进一步阅读的指南和建议。
在本书的最后一章中,我们将介绍以下内容:
在我们部署任何东西之前,我们必须提供将要部署的所有东西。为此,我们将部署 API 模块的 JAR。 JAR 是应用程序构建的结果。我们要做的第一件事是准备发布应用程序。我们将把端口从 9000 更改为 80。打开 application.properties 文件并进行以下更改:
spring.application.name= journaler server.port= 80 logging.level.root=INFO logging.level.com.journaler.api=DEBUG logging.level.org.springframework.jdbc=ERROR endpoints.health.enabled=true endpoints.trace.enabled=true endpoints.info.enabled=true endpoints.metrics.enabled=true spring.datasource.url=jdbc:mysql://localhost/journaler_api?useSSL=false&useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=localInstance2017 spring.datasource.tomcat.test-on-borrow=true spring.datasource.tomcat.validation-interval=30000 spring.datasource.tomcat.validation-query=SELECT 1 spring.datasource.tomcat.remove-abandoned=true spring.datasource.tomcat.remove-abandoned-timeout=10000 spring.datasource.tomcat.log-abandoned=true spring.datasource.tomcat.max-age=1800000 spring.datasource.tomcat.log-validation-errors=true spring.datasource.tomcat.max-active=50 spring.datasource.tomcat.max-idle=10 spring.jpa.hibernate.ddl-auto=update
我们需要做的下一件事是通过执行 ./gradlew clean 命令来清理项目,如以下屏幕截图所示:
上述命令的输出如以下屏幕截图所示:
现在,我们将执行 ./gradlew assemble 来构建应用程序:
上述命令的输出如下图所示:
让我们通过执行 ls 命令列出我们项目目录的内容:
导航到 build/libs 目录并使用 ls
命令列出该目录的内容,如以下屏幕截图所示:
将您看到的 JAR 复制到您要保存的位置。我们将它复制到当前用户的 Desktop 中,如下图所示:
现在,导航到您刚刚复制 JAR 文件的位置并尝试运行它,如以下屏幕截图所示:
正如您在以下屏幕截图中看到的那样,这将失败:
为了能够在端口 80 上运行我们的应用程序,您必须以 sudo 用户身份运行它,如以下屏幕截图所示:
系统将要求您输入用户密码。输入并点击 Enter。应用程序将运行,如以下屏幕截图所示:
再次确认一切正常。打开 Postman 并触发几个 API 调用,目标是端口 80 上的本地主机。
我们将在这里插入一些注释:
我们将阅读它们:
一旦我们确定这个构建是好的,我们就可以继续我们的部署任务的下一步。
在本节中,我们将解释有关 Spring 应用程序部署的选项。如您所知,我们在这个项目中使用了 Spring Boot,这意味着 Spring Boot 提供了一个公共静态 void 主入口点,可以为您启动一个嵌入式 Web 服务器。
我们最近执行的 assemble 命令为我们创建了一个胖 JAR,因此包含了所有依赖项。如果我们通过运行 $ java - jar api-0.0.1-SNAPSHOT.jar 像上一节中那样运行应用程序。
我们还将启动嵌入式服务器,我们的应用程序将开始监听 application.properties 文件中定义的端口。
通过运行我们的 JAR,Spring Boot 将检测到您拥有 Spring MVC 控制器并将启动一个嵌入式 Apache Tomcat 实例。这是它的默认行为。
服务器运行后,您将能够访问您的应用程序,就像我们在上一节中使用 Postman 一样。
要自定义 Tomcat,我们可以使用我们的 application.properties 文件并分配其他配置,例如:
以下配置特定于 Tomcat 数据源:
spring.datasource.tomcat.*= ...
在我们的应用程序中,数据源配置如下所示:
spring.datasource.tomcat.test-on-borrow=true spring.datasource.tomcat.validation-interval=30000 spring.datasource.tomcat.validation-query=SELECT 1 spring.datasource.tomcat.remove-abandoned=true spring.datasource.tomcat.remove-abandoned-timeout=10000 spring.datasource.tomcat.log-abandoned=true spring.datasource.tomcat.max-age=1800000 spring.datasource.tomcat.log-validation-errors=true spring.datasource.tomcat.max-active=50 spring.datasource.tomcat.max-idle=10
要将 Spring 应用程序部署到主流 Java EE 应用程序服务器之一,您需要对代码进行一些更改,然后您的项目就准备就绪了。为此,我们需要一个 WAR 版本而不是 JAR。
打开 build.gradle 并更新它,以便应用 Gradle WAR 插件:
buildscript { ext { kotlinVersion = '1.2.21' springBootVersion = '2.0.0.M4' } repositories { mavenCentral() maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/milestone" } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}") } } apply plugin: 'kotlin' apply plugin: 'kotlin-spring' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' apply plugin: 'war' group = 'com.journaler' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } repositories { mavenCentral() maven { url "https://repo.spring.io/snapshot" } maven { url "https://repo.spring.io/milestone" } } dependencies { compile 'org.springframework.boot:spring-boot-starter-security' compile 'org.springframework:spring-context' compile 'org.springframework:spring-aop' compile 'org.springframework.boot:spring-boot-starter' compile 'org.springframework.boot:spring-boot-starter-web' compile 'org.springframework.boot:spring-boot-starter-actuator' compile 'org.springframework:spring-web' compile 'org.springframework:spring-webmvc' runtime 'mysql:mysql-connector-java' compile 'org.springframework.boot:spring-boot-starter-data-jpa' compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}" compile "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}" testCompile 'org.springframework.boot:spring-boot-starter-test' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' }
由于我们使用 Gradle,以下代码将我们的 servlet 容器标记为已提供:
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
需要进行另一次修改。我们必须改变我们的 ApiApplication 类:
package com.journaler.api import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.web.servlet.support.SpringBootServletInitializer import org.springframework.boot.builder.SpringApplicationBuilder @SpringBootApplication class ApiApplication : SpringBootServletInitializer() { override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder { return application.sources(ApiApplication::class.java) } } fun main(args: Array<String>) { SpringApplication.run(ApiApplication::class.java, *args) }
现在,我们准备好生成 WAR。打开终端并使用 Gradle 的 ./gradlew clean 命令,如以下屏幕截图所示:
上述命令完成后,运行 Gradle 的 .gradlew assemble 命令,如下图所示:
在前面的命令完成它的过程之后,我们应该准备好我们的 WAR。导航到 libs 目录,如以下屏幕截图所示:
现在,使用 ls 命令列出目录中的文件,如以下屏幕截图所示:
如您所见,api-0.0.1-SNAPSHOT.war 构建可用。
今天,Amazon Web Services (AWS) 是最流行的托管应用程序平台。 AWS 是 Amazon.com 的子公司,以付费订阅的方式为个人、公司和政府提供按需云计算平台。它受欢迎的原因是它提供了可靠、可扩展和廉价的云计算服务。
由于这是本章的最后一部分,我们将逐步指导您完成部署到 AWS 的过程。我们将向您展示如何使用 AWS Elastic Beanstalk 部署我们的 API Spring Boot 应用程序。我们还将向您展示如何通过使用环境变量来自定义 Spring Boot 配置。
AWS Elastic Beanstalk 提供约定优于配置,但它仍然使我们能够在需要时进行调整。 Elastic Beanstalk 是一种托管服务,旨在部署和扩展 Web 应用程序和服务。它支持各种编程语言,以及各种 Web 和应用程序服务器,例如 Apache、Nginx、Passenger、Tomcat 和 IIS。
为了能够部署我们的应用程序,我们需要设置一个 AWS 账户。您可以在此处注册免费帐户以试用 AWS Elastic Beanstalk:https://aws.amazon.com/免费/。
打开链接。您应该会看到以下 AWS 免费套餐页面:
点击 创建免费帐户 按钮。将出现注册表:
填充您的数据并点击继续。然后,联系信息表格会出现:
插入您的个人数据并点击创建帐户并继续按钮。然后,会出现下面的支付信息表单:
填充您的数据并单击 安全提交 按钮继续。然后,会出现下面的Phone Verification页面:
按照电话验证说明操作,直到验证过程完成:
点击 Continue 并通过点击 Free 按钮选择 基本计划:
恭喜!您已成功注册 AWS 账户:
现在,单击右上角的 登录控制台 按钮。 登录 表单将出现:
填写您的信息,然后单击 下一步 按钮继续。填写密码并继续前进。几秒钟后,您将被重定向到 AWS 管理控制台:
现在,我们准备好部署我们的应用程序了!
通过单击 构建 Web 应用程序 链接打开 Elastic Beanstalk 控制台。 Elastic Beanstalk 控制台 将打开:
对于 Application name,输入 Journaler API,对于 Description,输入 Example application。单击 下一步 按钮。将出现一个名为 New Environment 的页面:
单击 创建 Web 服务器 按钮。将出现一个名为 Environment Type 的页面:
对于 预定义配置,选择 Java。对于 环境类型,选择 单实例。单击 下一步 按钮继续。将出现一个名为 Application Version 的页面:
选择上传你自己的,然后点击选择文件按钮。导航到您保存 JAR 的位置并选择它:
点击 Next 按钮上传 JAR:
上传这个版本的应用程序需要一些时间。将出现以下环境信息页面:
在继续之前单击 检查可用性 按钮。检查完成后,我们的 API URL 会变成绿色:
写下您的应用程序的完整 URL。在我们的例子中,这将是以下内容:
journalerapi-env.us-east-2.elasticbeanstalk.com
现在,单击 下一步 按钮。将出现以下 Additional Resources 页面:
选中这两个复选框并单击 Next 按钮。填充以下 配置详细信息 页面:
单击 下一步 按钮继续。将出现以下 Environment Tags 页面:
单击 下一步 按钮继续。将出现以下 RDS 配置 页面:
对于用户名和密码,输入我们在 application.properties 文件中使用的值。用这些数据填写表格,然后单击 下一步 按钮继续。将出现以下 VPC 配置 页面:
选择 关联公共 IP 地址:
完成后,单击 下一步 按钮继续。将出现以下 Permissions 页面:
单击 下一步 按钮。将出现以下 Review 页面:
查看配置并单击 Launch 以完成向导。部署将开始:
完成部署需要一些时间。等到部署完成:
恭喜!您已成功部署应用程序!在我们尝试之前,还有一些事情要做。
默认情况下,我们的 Spring Boot 应用程序将侦听端口 80。 Elastic Beanstalk 假定应用程序将侦听端口 5000。我们必须解决这个问题。
在您环境中的 配置 页面上,找到 软件配置:
单击设置图标并滚动到页面底部:
添加 5000 的 SERVER_PORT 值:
点击 Apply 按钮保存更改。除了配置应用程序侦听的端口外,我们还必须指定环境变量来配置应用程序将使用的数据库。
让我们获取数据库的端点 URL。在 Environment Configuration 页面的 Data Tier 部分下,您会在 RDS:
写下来。在我们的例子中,如下所示:
aa5d0lzzf02dnm.cbpdar2dvspv.us-east-2.rds.amazonaws.com:3306
返回 Environment Properties 部分并使用以下内容对其进行扩展:
总而言之,我们添加了以下环境属性:
单击 Apply 以保存更改并等待更改应用。现在,您已准备好试用 API。打开 Postman 并针对我们 API 的生产 URL 执行几个 API 调用。
准备好应用程序可能需要一些时间!刷新应用程序的 URL,直到错误 502 停止出现。当您看到 Spring 的 Whitelabel Error Page 时,您将知道应用程序已准备就绪:
让我们插入一些注释。我们将用我们的生产 URL 替换我们的 localhost URL(输入您在部署期间记下的 URL):
插入注释后,验证它们是否确实存在:
最后,我们可以确认我们的 Rest API 已启动并运行!现在,您可以将其公开给客户端应用程序。您可以将它与 Angular 客户端、Android、iOS 应用程序或您选择的任何其他应用程序一起使用。
一旦发布了应用程序的新版本(当新 JAR 准备就绪时),部署它就非常简单了。您所要做的就是使用 AWS Elastic Beanstalk 控制台的登录页面并上传新构建。我们设置的所有环境属性都将被使用,应用程序将立即准备就绪。
由您决定使用哪种部署方法。调查和比较其他选项。写下所有的优点和缺点。尝试每一个。我们推荐 AWS 作为我们首选的应用程序部署方法,因为它易于配置和部署,并且稳定且灵活。
在本章中,我们将应用程序发布到生产环境中。这是完成本书旅程的完美方式。在本书的章节中,我们对应用程序进行了雕刻,并在最后阶段将其部署到 AWS。 Spring 是一个很大的框架,它可能需要一些时间来学习它所提供的一切。我们鼓励您继续学习和提高您的 Spring 知识。尽可能多地编写代码并研究 Spring 为您提供的所有选项。正如我们在上一节末尾已经提到的,尝试所有可以使用的部署选项。了解它们中的每一个都可能是一个巨大的优势!
如需进一步阅读,我们建议您查看针对特定 Spring 相关领域的官方 Spring 文档或书籍。不要犹豫,开始行动。创建一个新的存储库并开始编写新的 Spring 应用程序!