在桌面运行云环境
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
通过以上的步骤和技术,我们可以在桌面环境中搭建一个完整的云环境,实现微服务应用的开发和测试。同时,通过对关键技术的深入理解和常见问题的解决,我们可以更好地应对实际开发中遇到的挑战。
利用Maven与Docker在桌面运行云环境
超级会员免费看
4024

被折叠的 条评论
为什么被折叠?



