35、在桌面运行云环境

利用Maven与Docker在桌面运行云环境

在桌面运行云环境

1. 目标与技术概述

在规划代码示例和选择部署所需的运行时技术时,有两个主要目标。一是确保代码示例易于理解和设置,因为微服务应用有多个组件,提前规划才能让读者轻松部署。二是让每个部分都能独立运行,读者可以选择任意部分,拥有完整的运行时环境,无需依赖其他部分。

为实现这些目标,采用了以下技术和模式:
1. Apache Maven :作为构建工具,每个服务都采用Maven项目结构,且各部分结构一致。
2. Docker :将开发的服务编译为Docker容器镜像。Docker是出色的运行时虚拟化引擎,可在多种操作系统上运行,能在桌面构建完整运行时环境,且易于在多个云提供商间移植。使用Spotify的Docker Maven插件将Docker容器构建与Maven构建过程集成。
3. Docker Compose :在服务编译为Docker镜像后,使用Docker Compose将服务作为组启动,避免使用复杂的Docker编排工具,使示例简单且可移植。所有Docker镜像的配置通过简单的shell脚本完成。

2. 所需软件

要构建相关软件,需要在桌面安装以下软件:
| 软件名称 | 版本 | 说明 |
| ---- | ---- | ---- |
| Apache Maven | 3.3.9 | 在Java生态系统中仍占主导地位,代码示例使用Java 1.8编译 |
| Docker | V1.12 | 代码示例基于此版本构建,早期版本也可能适用,但可能需切换docker-compose链接格式 |
| Git Client | 2.8.4 | 所有源代码存储在GitHub仓库中 |

这些软件的安装说明简单,Docker有GUI客户端用于安装。

3. 从GitHub下载项目

所有源代码存储在GitHub仓库中,各部分都有自己的源代码仓库,例如:
- Chapter 1:http://github.com/carnellj/spmia-chapter1
- Chapter 2:http://github.com/carnellj/spmia-chapter2
- Chapter 3:http://github.com/carnellj/spmia-chapter3 和 http://github.com/carnellj/config-repo

可以通过GitHub的Web UI将文件下载为zip文件,也可以使用命令行,例如使用git client下载Chapter 1:

git clone https://github.com/carnellj/spmia-chapter1.git 

这将把Chapter 1的项目文件下载到运行git命令的目录下的spmia-chapter1目录中。

4. 各部分结构

每个部分都有一个或多个相关服务,每个服务有自己的项目目录。以Chapter 6为例,包含以下服务:
1. confsvr — Spring Cloud Config server
2. eurekasvr — Spring Cloud/with Eureka
3. licensing-service — Eagle Eye Licensing service
4. organization-service — Eagle Organization service
5. orgservice-new — New test version of the EagleEye service
6. specialroutes-service — A/B routing service
7. zuulsvr — EagleEye Zuul service

每个服务目录都是基于Maven的构建项目,内部的src/main目录有以下子目录:
1. java :包含用于构建服务的Java源代码。
2. docker :包含构建Docker镜像所需的两个文件,Dockerfile和run.sh。Dockerfile包含构建Docker镜像的步骤,run.sh是在Docker容器内运行的自定义Bash脚本,确保服务在关键依赖项可用后才启动。
3. resources :包含服务的application.yml文件,部分配置存储在此处,还包含schema.sql文件,用于创建表和预加载数据到PostgreSQL数据库。

5. 项目构建与编译

由于各部分结构相同且使用Maven作为构建工具,构建源代码非常简单。每个部分的根目录都有一个pom.xml作为所有子部分的父pom。如果要编译源代码并为单个部分的所有项目构建Docker镜像,在该部分的根目录运行以下命令:

mvn clean package docker:build

如果要构建部分内的单个服务,可切换到该服务目录并运行相同命令。

6. 构建Docker镜像

使用Spotify的Docker Maven插件将服务打包为Docker镜像。以下是配置该插件的XML片段:

<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <version>0.4.10</version>
  <configuration>           
    <imageName>
        ${docker.image.name}:
          [ca]${docker.image.tag} 
    </imageName>                 
    <dockerDirectory>
        ${basedir}/target/dockerfile                        
    </dockerDirectory>
    <resources>
       <resource>
         <targetPath>/</targetPath>
         <directory>${project.build.directory}</directory>       
         <include>${project.build.finalName}.jar</include>
       </resource>
    </resources>
  </configuration>
 </plugin>

该XML片段完成以下操作:
1. 将服务的可执行jar和src/main/docker目录的内容复制到target/docker。
2. 执行target/docker目录中的Dockerfile,该文件包含构建Docker镜像的命令。
3. 将Docker镜像推送到安装Docker时安装的本地Docker镜像仓库。

以下是licensing服务的Dockerfile内容:

FROM openjdk:8-jdk-alpine                                            
RUN  apk update && apk upgrade && apk add netcat-openbsd             
RUN mkdir -p /usr/local/licensingservice
ADD licensing-service-0.0.1-SNAPSHOT.jar /usr/local/licensingservice/  
ADD run.sh run.sh                                               
RUN chmod +x run.sh
CMD ./run.sh

在这个Dockerfile中,使用Alpine Linux构建实例,安装了命令行工具nc用于检查依赖服务的端口是否可用。run.sh脚本确保服务在依赖服务启动后才启动。

7. 使用Docker Compose启动服务

Maven构建完成后,可使用Docker Compose启动部分的所有服务。Docker Compose是服务编排工具,使用YAML文件定义要启动的服务。以Chapter 3的docker-compose.yml文件为例:

version: '2'
services:
  configserver:                                  
    image: johncarnell/tmx-confsvr:chapter3      
    ports:
       - "8888:8888"                              
    environment:
      ENCRYPT_KEY:       "IMSYMMETRIC"     
  database:
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "p0stgr@s"
      POSTGRES_DB:       "eagle_eye_local"
  licensingservice:
    image: johncarnell/tmx-licensing-service:chapter3
    ports:
      - "8080:8080"
    environment:
      PROFILE: "default"
      CONFIGSERVER_URI: "http://configserver:8888"         
      CONFIGSERVER_PORT:   "8888"
      DATABASESERVER_PORT: "5432"
      ENCRYPT_KEY:       "IMSYMMETRIC" 

在这个文件中,定义了三个服务(configserver、database和licensing service),每个服务指定了Docker镜像、暴露的端口和环境变量。

启动Docker容器的命令如下:

docker-compose –f docker/common/docker-compose.yml up

执行该命令后,docker-compose将启动docker-compose.yml文件中定义的所有服务,每个服务的标准输出将打印到控制台。

如果想查看特定容器的日志,可以先以分离模式启动:

docker-compose -f docker/common/docker-compose.yml up –d

然后查看特定容器的日志:

docker-compose -f docker/common/docker-compose.yml logs -f licensingservice

需要注意的是,所有Docker容器是临时的,重启后不会保留状态。如果想让PostgreSQL数据库在容器启动和停止之间保持持久化,可以参考Postgres Docker笔记。

以下是整个过程的流程图:

graph LR
    A[安装所需软件] --> B[从GitHub下载项目]
    B --> C[了解各部分结构]
    C --> D[构建与编译项目]
    D --> E[构建Docker镜像]
    E --> F[使用Docker Compose启动服务]

在桌面运行云环境

8. 关键技术细节解析
8.1 Apache Maven

Apache Maven是一个强大的项目管理和构建工具,在整个流程中起到了核心的构建作用。它通过 pom.xml 文件来管理项目的依赖、插件和构建过程。在本项目中,所有服务都采用Maven项目结构,这种一致性使得项目的构建和管理更加方便。

Maven的生命周期包括清理、编译、测试、打包等阶段。在执行 mvn clean package docker:build 命令时,Maven首先执行 clean 目标,清除之前构建生成的文件,然后执行 package 目标,将项目编译并打包成可执行的JAR文件。最后,通过 docker:build 目标,结合Spotify的Docker Maven插件,将项目打包成Docker镜像。

8.2 Docker

Docker是一种容器化技术,它可以将应用程序及其依赖项打包成一个独立的容器,实现应用的快速部署和迁移。在本项目中,每个服务都被打包成一个Docker镜像,这些镜像可以在不同的环境中运行,确保了应用的一致性和可移植性。

Docker的核心是Dockerfile,它是一个文本文件,包含了一系列的指令,用于构建Docker镜像。例如,在licensing服务的Dockerfile中:

FROM openjdk:8-jdk-alpine                                            
RUN  apk update && apk upgrade && apk add netcat-openbsd             
RUN mkdir -p /usr/local/licensingservice
ADD licensing-service-0.0.1-SNAPSHOT.jar /usr/local/licensingservice/  
ADD run.sh run.sh                                               
RUN chmod +x run.sh
CMD ./run.sh
  • FROM openjdk:8-jdk-alpine :指定基础镜像为基于Java 8的Alpine Linux镜像,Alpine Linux是一个轻量级的Linux发行版,适合用于构建Docker镜像。
  • RUN apk update && apk upgrade && apk add netcat-openbsd :在镜像中执行命令,更新系统并安装 netcat-openbsd 工具,用于检查依赖服务的端口是否可用。
  • ADD :将本地的文件添加到镜像中,这里将可执行的JAR文件和 run.sh 脚本添加到镜像中。
  • RUN chmod +x run.sh :给 run.sh 脚本添加可执行权限。
  • CMD ./run.sh :指定容器启动时执行的命令,即运行 run.sh 脚本。
8.3 Docker Compose

Docker Compose是一个用于定义和运行多容器Docker应用的工具。它使用YAML文件来配置应用的服务、网络和卷等。在本项目中,每个部分都有一个 docker-compose.yml 文件,用于定义要启动的服务。

以Chapter 3的 docker-compose.yml 文件为例:

version: '2'
services:
  configserver:                                  
    image: johncarnell/tmx-confsvr:chapter3      
    ports:
       - "8888:8888"                              
    environment:
      ENCRYPT_KEY:       "IMSYMMETRIC"     
  database:
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "p0stgr@s"
      POSTGRES_DB:       "eagle_eye_local"
  licensingservice:
    image: johncarnell/tmx-licensing-service:chapter3
    ports:
      - "8080:8080"
    environment:
      PROFILE: "default"
      CONFIGSERVER_URI: "http://configserver:8888"         
      CONFIGSERVER_PORT:   "8888"
      DATABASESERVER_PORT: "5432"
      ENCRYPT_KEY:       "IMSYMMETRIC" 
  • version :指定 docker-compose.yml 文件的版本。
  • services :定义要启动的服务,每个服务都有一个名称,如 configserver database licensingservice
  • image :指定服务使用的Docker镜像。
  • ports :指定容器暴露的端口,格式为 宿主机端口:容器端口
  • environment :指定传递给容器的环境变量。
9. 常见问题与解决方案
9.1 镜像构建失败

如果在执行 mvn clean package docker:build 命令时,镜像构建失败,可能有以下原因:
- 依赖问题 :检查 pom.xml 文件中的依赖是否正确,确保所有依赖都可以正常下载。
- 网络问题 :Docker在构建镜像时可能需要从网络下载一些文件,确保网络连接正常。
- Dockerfile错误 :检查Dockerfile中的指令是否正确,特别是文件路径和命令的拼写。

解决方案:
- 检查 pom.xml 文件,使用 mvn dependency:tree 命令查看依赖树,排除依赖冲突。
- 检查网络设置,确保可以访问Docker Hub等镜像仓库。
- 仔细检查Dockerfile,使用 docker build 命令手动构建镜像,查看详细的错误信息。

9.2 服务启动失败

如果使用 docker-compose up 命令启动服务时,服务启动失败,可能有以下原因:
- 依赖服务未启动 :某些服务可能依赖于其他服务,如数据库服务。确保所有依赖服务都已正常启动。
- 环境变量配置错误 :检查 docker-compose.yml 文件中的环境变量配置是否正确。
- 端口冲突 :检查宿主机上的端口是否已被占用。

解决方案:
- 使用 docker-compose logs 命令查看服务的日志,找出错误信息。
- 检查 docker-compose.yml 文件中的环境变量配置,确保与服务的配置一致。
- 使用 netstat -tuln 命令查看宿主机上的端口占用情况,修改 docker-compose.yml 文件中的端口配置。

10. 总结与展望

通过使用Apache Maven、Docker和Docker Compose等技术,我们可以在桌面环境中轻松地运行云环境,实现微服务应用的快速开发和部署。这种方式不仅提高了开发效率,还确保了应用在不同环境中的一致性和可移植性。

在未来的发展中,我们可以进一步优化这个流程,例如使用更高级的容器编排工具如Kubernetes来管理大规模的容器集群,提高系统的可靠性和可扩展性。同时,我们也可以结合持续集成和持续部署(CI/CD)工具,实现代码的自动化构建、测试和部署,进一步提高开发效率和质量。

以下是整个流程的详细步骤表格:
| 步骤 | 操作 | 命令示例 |
| ---- | ---- | ---- |
| 1 | 安装所需软件 | 安装Apache Maven 3.3.9、Docker V1.12、Git Client 2.8.4 |
| 2 | 从GitHub下载项目 | git clone https://github.com/carnellj/spmia-chapter1.git |
| 3 | 了解各部分结构 | 查看每个服务目录的 src/main 子目录 |
| 4 | 项目构建与编译 | mvn clean package docker:build |
| 5 | 构建Docker镜像 | 执行Maven命令,结合Spotify插件和Dockerfile |
| 6 | 使用Docker Compose启动服务 | docker-compose –f docker/common/docker-compose.yml up |

graph LR
    A[安装软件] --> B[下载项目]
    B --> C[了解结构]
    C --> D[构建编译]
    D --> E[构建镜像]
    E --> F[启动服务]
    F --> G{服务是否正常}
    G -- 是 --> H[完成]
    G -- 否 --> I[排查问题]
    I --> D

通过以上的步骤和技术,我们可以在桌面环境中搭建一个完整的云环境,实现微服务应用的开发和测试。同时,通过对关键技术的深入理解和常见问题的解决,我们可以更好地应对实际开发中遇到的挑战。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值