如何使用Docker进行Java开发

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(371)   2023-06-26 07:54:18

在开发过程中使用 代码头工 的承诺是为跨开发人员机器和使用中的各种环境(如 QA 和生产)进行测试提供一致的环境。困难在于 Docker 容器引入了开发人员在编码期间必须管理的额外抽象层。

Docker 使应用程序代码能够与其系统需求定义捆绑在一个跨平台、可运行的包中。这是一个优雅的抽象,用于解决部署和管理软件运行时的基本需求,但它引入了一个额外的间接层,当程序员在做他们所做的事情时必须处理:迭代修改和测试软件的内部及其依赖项.

您最不想做的就是放慢开发周期。 这里 在概念层面对这些问题进行了很好的讨论。

即使您或您的团队不致力于将 Docker 作为一个过程问题跨开发机器使用,也有几个用于修改和调试在容器内运行的代码的用例。例如,开发人员可以使用 Docker 模拟生产环境来重现错误或其他情况。此外,远程调试运行 Dockerized 应用程序的主机的能力可以允许对运行环境(如 QA)进行实际故障排除。

我们将在 Google Cloud Platform (GCP) 上的 VM 中建立一个简单的 Java 应用程序,将其 Dockerize,然后远程调试它并从本地主机上运行的 Visual Studio Code 修改其代码。

我们将涵盖两个基本需求:在不重新启动容器的情况下更新正在运行的代码库,以及调试到正在运行的容器化应用程序。作为一个额外的好处,我们将在远程运行的容器上执行此过程。这意味着您将拥有一种远程调试服务(如 QA 服务器)以及本地开发主机的方法。

设置 Java 和 Spring Boot

第一步是转到 GCP 控制台(如果没有免费帐户,请注册一个)。现在转到 Compute Engine 链接,这将为您提供 VM 列表,然后单击创建实例。

如果您选择 N1 微型服务器,它将处于免费层级。然而,Docker 有点耗费资源,所以我建议使用通用 E2 服务器(7 天 24 小时使用,每月花费大约 25 美元)。我将我的命名为 dev-1。

继续为此实例配置网络。单击 VM 详细信息中间的网络选项卡,然后在网络标记字段中,添加 port8080port8000

现在转到左侧菜单并打开 VPC 网络 -> 防火墙。创建两个新规则(单击创建防火墙规则按钮)以允许所有源 IP (0.0.0.0/0) 访问 TCP 端口 8080,标签为 port8080,TCP 端口为 8000,带有标签 port8000。有了这些,新的 VM 实例将允许流量流向您将在 8080 上创建的应用程序服务器和默认的 Java 调试端口 8000。

通过单击回到计算机引擎 -> VM 实例,找到新实例 (dev-1),然后单击 SSH 按钮,SSH 到新服务器。

现在让我们设置 Java。键入 sudo apt-get update,然后键入 sudo apt-get install default-jdk。完成后,java --version 应该返回一个值。

接下来,通过 SDKMAN(一个 SDK 管理器)安装 Spring CLI,这样我们就可以从 shell 使用 Initializr。运行以下命令:

sudo apt install zipcurl -s "https://get.sdkman.io" | bashsource "/home//.sdkman/bin/sdkman.sh"

现在 sdk version 应该可以工作了。

接下来使用 sdk install springboot 安装 Spring CLI 工具。现在您可以使用以下命令快速创建一个新的 Spring Boot Java Web 应用程序:

spring init --dependencies=web idg-java-docker

新项目将驻留在 /idg-java-docker 中。继续 cd 进入该目录。

Spring Boot 应用包含 mvnw 脚本,因此您无需手动安装 Maven。通过键入 sudo ./mvnw spring-boot:run 在开发模式下启动应用程序。

如果您在浏览器中导航到 http://<你的实例 IP>:8080(您可以在 GCP 控制台的列表中找到 IP 地址),您现在应该收到Spring White Label 错误页面,因为没有路由映射。

映射 URL 路由

只需添加一个快速而简单的端点进行测试。使用 vi src/main/java/com/example/javadocker/DemoApplication.java(或您选择的编辑器)将主类修改为如清单 1 所示。

清单 1. 添加端点

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@SpringBootApplication@RestControllerpublic class DemoApplication {  @RequestMapping("/")  public String home() {     return "Hello !";  }  public static void main(String[] args) {    SpringApplication.run(DemoApplication.class, args);  }}

现在您可以使用 Ctrl-c 停止 Tomcat,并通过键入 ./mvnw spring-boot:run 重建/重新启动。如果您在浏览器中导航到该应用程序,您将看到简单的“Hello ”响应。

Docker化项目

首先按照 Debian 的官方 Docker 说明 安装 Docker。依次键入以下每个命令:

sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-releasecurl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpgecho "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io

创建一个 Dockerfile

有多种创建 Dockerfile 的方法,包括使用 Maven 插件。对于这个项目,我们将手动构建简单的 Dockerfile 以查看它。有关 Java 和 Docker 的精彩介绍,请查看这篇信息世界文章

使用编辑器创建一个名为 dockerfile 的文件并添加清单 2 的内容。

清单 2. 一个基本的 Java/Spring Dockerfile

# syntax=docker/dockerfile:1FROM openjdk:16-alpine3.13WORKDIR /appCOPY .mvn/ .mvnCOPY mvnw pom.xml ./RUN ./mvnw dependency:go-offlineCOPY src ./srcCMD ["./mvnw", "spring-boot:run"]

为简单起见,我们在这里忽略组和用户,但在现实世界的情况下,您需要处理它。

这个 Dockerfile 使用 OpenJDK 作为基础层,然后我们移动到 /app 工作目录。接下来我们引入所有 Maven 文件并在离线模式下运行 Maven。 (这使我们能够避免以后重新下载依赖项。)Dockerfile 然后将应用程序源复制过来,并运行 spring-boot:run 命令。

请注意,我们正在朝着支持开发的图像发展,而不是生产图像。您不会将 spring-boot:run 用于生产环境。

如果仍在运行,请停止正在运行的应用程序。

让我们现在构建并运行它。首先运行 docker build 命令:

sudo docker build --tag idg-java-docker

等待构建,然后执行 docker run

sudo docker run -d -p 8080:8080 idg-java-docker

这将构建您的 Docker 映像,然后在新容器中启动它。当你调用运行命令时,它会吐出一个 UID,例如(在我的例子中):

d98e4d19dab71fa69b2331485b70b5c87f20de864238e5798ad3aa8c5b576014

您可以通过再次使用浏览器访问它来仔细检查该应用程序是否正在运行并在端口 8080 上可用。

您可以使用 sudo docker ps 检查正在运行的容器。您应该会看到相同的 UID 正在运行。使用 sudo docker kill 停止它。请注意,您只需键入足够多的唯一 UID(类似于 Git 签入 ID),所以在我的例子中是 sudo docker kill d98

这个 Dockerfile 是运行应用程序的合理开端(接下来是用户和层),但请稍等片刻,考虑一下您需要做什么来更新正在运行的应用程序。即使要更改简单的问候消息,您也需要更改代码,停止正在运行的 Docker 容器,使用 docker build 构建映像,然后使用 码头运行

我们怎样才能改善这种情况?

使用 Docker 组合

答案是我们将使用启用了远程调试的开发工具运行 Spring Boot,并在 Docker 中公开调试端口。为了以声明方式(而不是命令行参数)管理它,我们将使用 Docker Compose。 Docker Compose 是一种表达 Docker 运行方式的强大方式,它支持多个目标(也称为多阶段构建)和外部卷安装。

默认配置文件是 docker-compose.yml,它在 Dockerfile 中的配置之上运行。

First 安装 Docker 二进制文件:

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

然后运行:

sudo chmod +x /usr/local/bin/docker-compose

现在你可以运行:

docker-compose --version

提示如果您需要在运行的容器内部进行探索,您可以运行以下命令之一(取决于图像中的底层操作系统):

  • sudo docker exec -it 646 /bin/sh
  • sudo docker exec -it 646 /bin/bash
  • sudo docker exec -it 646 powershell

现在 Docker Compose 可用了,让我们为它创建一个配置文件 docker-compose.yml,如清单 3 所示。

清单 3.docker-compose.yml

version: '3.3'services:  idg-java-docker:    build:      context: .    ports:      - 8000:8000      - 8080:8080    environment:      - SERVER_PORT=8080    volumes:      - ./:/app    command: ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000"

这里的第一个关键事实是端口 8080 和 8000 都已打开。 8000 是常规的 Java 调试端口,由 command 字符串引用。 docker-compose 命令会覆盖 Dockerfile 中的 CMD 定义。重申一下,docker-compose 在 Dockerfile 之上运行。

输入 sudo docker-compose build --no-cache idg-java-docker 来构建图像。

使用 sudo docker-compose up 启动应用程序。现在用 Ctrl-c 杀死它。

现在使用 sudo docker-compose up -d 在后台运行容器以实现分离模式。然后你可以用 sudo docker-compose down 关闭它。

使用 git initgit add .git commit -m "initial"

现在访问 GitHub.com 并创建一个新的存储库。按照说明推送项目:

git remote add origin https://github.com//.gitgit branch -M maingit push -u origin main

现在在本地系统上打开 Visual Studio Code。 (或任何支持远程调试的 Java IDE;有关运行 VS Code 和 Java 的更多信息在这里检查。所有现代 IDE 都将直接从 GitHub 存储库克隆地址克隆一个存储库。)现在就做。

现在打开 IDE 的 Java 调试配置。在 VS Code 中,这是 launch.json 文件。创建一个如清单 4 所示的配置条目。其他 IDE(Eclipse、IntelliJ 等)将有类似的启动配置对话框,其中包含相同的条目字段。

清单 4. IDE 客户端的调试配置

{  "type": "java",  "name": "Attach to Remote Program",  "request": "attach",  "hostName": "<The host name or ip address of remote debuggee>",  "port": 8000},

从您的 VM 插入 IP 地址,然后通过转到调试并运行“附加到远程程序”配置来启动此配置。

附加调试器后,您可以修改 DemoApplication.java 文件(例如,将问候消息更改为“Hello !”)并保存。现在单击“热模块交换”按钮(闪电图标)。 VS Code 将更新正在运行的程序。

再次浏览到浏览器中的应用程序,您会看到它会反映更改。

现在是最后一个技巧。在 IDE 中双击第 13 行设置断点。现在再次访问该应用程序。断点将命中,IDE 将出现,并且将提供完整的调试功能。

还有其他方法可以对开发流程进行 Docker 化,但本文中描述的方法可以让您在相对简单的设置中为本地主机和远程系统进行代码更新调试。

地址:https://www.cundage.com/article/3638548-how-to-use-docker-for-java-development.html

相关阅读

在开发过程中使用 代码头工 的承诺是为跨开发人员机器和使用中的各种环境(如 QA 和生产)进行测试提供一致的环境。困难在于 Docker 容器引入了开发人员在编码期间必须管理的额外抽象层。 Do...
当应用程序开发人员或架构师的任务是探索容器化应用程序提供的可能性时,没有什么比红帽容器开发套件 (CDK) 更容易了。 Red Hat CDK 拥有本地 OSX、Linux 或 Windows ...
Just like we use a version control system for source code management, in a similar way, we can us...
基础设施即代码 vendor 缅甸语 is adding support for 爪哇 and YAML, as it looks to allow software developers to...
最近,我的一个好朋友在使用公共 Oracle Maven 存储库构建 ADF 应用程序 v.12.2.1.2 时遇到了一个常见问题。他让我检查它是否对我有用。好吧……它没有。
ArrayList contains() 方法用于检查指定的元素是否存在于给定的数组列表中。如果元素存在,则方法返回 true,否则返回 false。 1. ArrayList contains...
关于微服务的资料很多,只需google 一下!几年前,我在 Devoxx Belgium 上做了一个关于将整体重构为微服务的演讲,它得到了很好的评价: 该博客将展示 Docker 如何简化微服务...
尽管 Java 8 已经问世近八年了,但在 Perforce Software 公司最近的一项调查中,它仍然是用户中最常用的 Java 版本。然而,调查发现,许多商店计划升级到更新得多的 Jav...
容器注定是短暂的,因此可以很好地扩展无状态应用程序。有状态的容器,例如 Couchbase,需要区别对待。 管理 Docker 容器的持久性 很好地概述了如何管理有状态容器的持久性。 此博客将解...
Spring Boot Docker 教程展示了如何对 Spring Boot 应用程序进行 docker 化。 春天 是一个流行的 Java 应用程序框架。 弹弓贴 致力于轻松创建独立的、生产...