一、项目结构

我这里准备了一个微服务项目。
里面包含三个服务模块:
card-service、use-rservice以及网关gateway。
一个公共模块:
fegin-api。
其中fegin-api被card-service和user-service引用。
二、基于项目构建部署目录结构

这个springcloud-app目录中的全部内容,之后就是要上传到服务上进行部署的源文件。
springcloud-app一级目录下包含了放gateway、card-service、user-service三个微服务的文件夹。
一个放mysql数据和配置文件的文件夹。
以及一个dockercompose配置文件。
关于它们的详解如下。
2.1 gateway目录构建详解
在我提供的项目中,gateway、card-service、user-service都属于微服务,构建方式是一样的。
这里就以gateway为例,解析怎么构建文件目录。
1)进入gateway目录:

里面只有一个我提前写好的Dockerfile文件。
要使用Docker构建镜像肯定是需要编写Dockerfile,在其中编写构建规则的。
2)打开Dockerfile文件:
里面只需要三句话即可。
# 指定java:8-alpine作为基础镜像,它包含了java程序部署的基本环境依赖
FROM java:8-alpine
# 把当前目录下的javaApp.jar移动到/soft目录下
COPY ./javaApp.jar /soft/javaApp.jar
# 程序运行入口,就是java项目的启动命令
# 这句话也是容器成功运行后,第一个执行的命令
ENTRYPOINT java -jar /soft/javaApp.jar
card-service、use-rservice两个文件夹下的内容和gateway中的一致。
并且Dockerfile文件的内容也一样。因为它们三种都是基于java开发的微服务,构建镜像的方式都是一致的。
2.2 mysql 目录构建详解

由于所有微服务都是使用的mysql数据库。
这样也就涉及到了Docker中运行mysql容器。
而为了mysql数据和配置的可移植性和可维护性。一般都会进行数据卷挂载或者磁盘挂载。
把自定义的mysql配置合并到容器中,以及把容器内被隔离的mysql数据与宿主机进行关联。
1)conf目录

hmy.cnf中存放着自定义mysql配置。可以是字符集配置,主从复制中的配置等等等。
如果暂时没有自定义配置,最好也先挂载上。由于容器启动后无法再挂载新的数据卷或者磁盘。
如果第一次不挂载,今后再想给mysql添加配置。
就只能删除容器再重新运行镜像生成新容器时再去挂载配置文件了。
2)data目录
里面包含着mysql数据库服务器下存放的所有数据库的数据。这些数据都以二进制文件的形式存储在本地磁盘。
每个电脑存放mysql本地二进制表格数据的位置不同,一般是安装的时候自己设定的。
只有找到那个文件夹,把需要的数据库二进制文件复制进来即可。
这个目录和容器磁盘进行挂载后,里面的数据会直接覆盖mysql容器中的数据。
之后容器中mysql的数据发生变化之后,也会同步更新到宿主机本地磁盘中的对应位置。
也就是说这里的data目录里的对应文件,也会随之修改。这属于Docker的基础知识了。
2.3 dcoker-compose.yml文件详解
# Compose 文件格式有3个版本,分别为1, 2.x 和 3.x
# 目前主流的为 3.x 其支持 docker 1.13.0 及其以上的版本
version: "3.0"
services: # 具体的服务定义
nacos: # nacos配置 nacos也是未来naocs服务的容器名称
image: nacos/nacos-server # nacos镜像名称
environment: # nacos环境变量
MODE: standalone # MODE相当于之前命令行的-m参数,指代运行模式。
# standalone单机运行(如果有nacos集群就不是这么写了)
ports: # 端口映射
- "8848:8848" # 把宿主机8848端口和nacos容器的8848端口相关联
mysql: # mysql配置 mysql也是未来mysql服务的容器名称
image: mysql:5.7.25 # mysql镜像名称
environment: # mysql环境变量
MYSQL_ROOT_PASSWORD: root # mysql密码为root
volumes: # 数据卷挂载配置
- "$PWD/mysql/data:/var/lib/mysql"
# 宿主/mysql/data目录挂载到器/var/lib/mysql目录
- "$PWD/mysql/conf:/etc/mysql/conf.d/"
# 宿主/mysql/conf目录挂载到器/etc/mysql/conf.d/目录
# $PWD 代表运行Linux的pwd命令,获取当前文件的路径
# 这样可以确保在Linux中任意位置都能找到/mysql/conf目录
ports: # 端口映射
- "3306:3306" # 把宿主机3306端口和mysql容器的3306端口相关联
userservice: # userservice微服务配置 userservice也是未来微服务的容器名称
build: ./user-service # 代表在当前目录下的user-service目录下构建userservice镜像
cardservice: # cardservice微服务配置 cardservice也是未来微服务的容器名称
build: ./card-service # 代表在当前目录下的card-service目录下构建cardservice镜像
gateway: # gateway微服务配置 gateway也是未来微服务的容器名称
build: ./gateway # 代表在当前目录下的gateway目录下构建gateway镜像
ports: # 端口映射
- "9999:9999" # 把宿主机9999端口和gateway容器的9999端口相关联
关于mysql端口映射的说明:
mysql只在微服务集群内部进行访问,只需要在userservice和cardservice的application.yml文件中。
把mysql的注册中心的地址,由ip格式改为dcoker-compose.yml文件中配置的服务命名称即可。
compose-file文件的官方文档:
https://docs.docker.com/compose/compose-file/
自定义的微服务配置可以在这里找配置怎么写。
像nacos这种地三方镜像,就去它们对应的官网或者dockerHub上看看。
三、准备各个微服务的jar包
这里主要涉及了三个微服务userservice和cardservice和gateway。
在打jar包前,需要先修改配置文件。
修改各个微服务的application.yml文件或者bootstrap.yml文件中的mysql和nacos的地址配置。
由ip格式改为dcoker-compose.yml文件中配置的服务命名称。
这是因为使用dcoker-compose配置时。
所有的服务之间都可以直接使用dcoker-compose.yml文件中配置的服务命名称来访问对方。
这里就以打包user-service这个模块为例。
3.1 修改mysql和nacos地址
1)修改bootstrap.yml文件

# 把红框处的localhost改为dcoker-compose.yml文件中配置的nacos
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: nacos:8848 # Nacos地址
config: # discovery 代表注册中心配置 config代表配置中心配置
file-extension: yaml # 文件后缀名
2)修改application.yml

server:
port: 8081
spring:
datasource:
url: jdbc:mysql://mysql:3306/cloud_user?useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
card-service和gateway模块中的配置也按上面的方式修改即可。
3.2 在pom.xml文件中添加打包插件
<!-- finalName中的配置就能确定打出来的jar包是什么名称 -->
<!-- plugins中配置的就是常规的maven打包插件 -->
<build>
<finalName>javaApp</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.3 使用Idea的Maven打包工具打包微服务

点击右侧Maven工具栏的package即可。
打包完成后到对应模块的target目录下获取jar包。
card-service和gateway模块的jar包也按上面的方式打出来即可,jar包名字都叫javaApp。
四、把jar包复制到springdata-app下的对应子目录中
以user-service为例。
在idea中的user-service模块下,找到target目录。
把打好的jar包复制到springdata-app目录下的userservice目录里。

card-service和gateway模块的jar包也按上面的方式制到springdata-app下的对应子目录中。
五、使用finallshell上传文件夹到服务器

可以选择任意自己想放的位置。只要便于查找即可。
六、compose相关命令
1)部署命令
# 对命令不熟悉可以查看命令文档
docker-compose --help
# docker-compose 是有非常多命令选项参数的,这里涉及到的两个
# up 创建并启动一个容器
# -d 后台运行
docker-compose up -d
2)停止命令
docker-compose stop
3)停止并删除
docker-compose down
4)重启
docker-compose restart
# 重启某些具体服务的写法
docker-compose restart gateway userservice
5)查看日志
docker-compose logs
# 查看具体的服务日志
# -f 持续更新日志变化,按ctrl+c可以结束
docker-compose logs -f userservice
上述都是常用命令,还有更多操作,不一一列举。
使用docker-compose --help就能知道所有docker-compose的用法。
七、具体部署操作
1)进入springdata-app文件目录
# 这个位置看自己把东西放哪,是不固定的
cd /usr/local/composrApp
2)执行部署命令
docker-compose up -d
3)部署后查看日志
docker-compose logs
4)部署问题解决方案
首次部署时日志中会出现如下错误:

主要是因为nacos容器启动速度比其他依赖nacos的微服务慢。
其它微服务已经启动了却连接不上nacos,也获取不到nacos中的配置信息。
解决方案:重启所有依赖nacos的微服务
docker-compose restart gateway userservice cardservice
重启完成后查看cardservice的日志
docker-compose logs -f cardservice
发现新出现的日志已经没有任何错误了。
八、基于自定义的jdk镜像部署微服务(推荐)
上面的方式有的人可能会觉得繁琐,每个微服务都有一个单独的文件夹,而且里面都有一个Dockerfile文件。
确实文件有点多。
还有一种方法可以让所有jar包放在一个文件夹中,并且不需要这么多重复的Dockerfile文件。
越来越多人也会选用这种方式来部署,并且这种方式,未来如果使用portainer管理docker时会很容易移植。
具体选择哪种方式,可以结合自己实际情况决定。
1)新建存放目录和文件
# 进入目录/usr/local/
cd /usr/local
# 新建app目录
mkdir app
# 新建Dockerfile文件
touch Dockerfile
存放位置可以根据部署需求自行指定
2)编写Dockerfile文件
# 构建镜像,执行命令:【docker build -t openjdk:8 .】
FROM openjdk:8u212-jre # 基础镜像
MAINTAINER xxx # 作者
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
ENTRYPOINT ["java", "-server", "-Xms512M", "-Xmx512M", "-Djava.security.egd=file:/dev/./urandom", "-Dfile.encoding=UTF-8", "-XX:+HeapDumpOnOutOfMemoryError", "-jar", "/app/app.jar" ]
3)使用Dockerfile文件构建一个openjdk镜像
docker build -t openjdk:8 .
4)编写docker-compose.yml文件
version: '3'
services:
mysql:
image: mysql:8
container_name: gddst-mysql-dev
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=89225300
- MYSQL_DATABASE=nacos_config
- MYSQL_USER=gddst
- MYSQL_PASSWORD=123456
ports:
- "3306:3306"
volumes:
- /usr/local/workspace/mysql/data:/var/lib/mysql
- /usr/local/workspace/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf
nacos:
image: nacos/nacos-server:v2.1.1-slim
container_name: gddst-nacos-dev
environment:
- MODE=standalone
- PREFER_HOST_MODE=hostname
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos_config
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=89225300
- MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
ports:
- "8848:8848"
- "9848:9848"
- "9555:9555"
volumes:
- /usr/local/workspace/nacos/logs:/home/nacos/logs
- /usr/local/workspace/nacos/data:/home/nacos/data
depends_on:
- mysql
gateway:
image: openjdk:8
container_name: gateway
ports:
- 8080:8080
environment:
- nacos_host=nacos
- nacos_port=8848
volumes:
- /usr/local/workspace/app/gddst-cloud-gateway.jar:/app/app.jar
userservice:
image: openjdk:8
container_name: userservice
environment:
- nacos_host=nacos
- nacos_port=8848
volumes:
- /usr/local/workspace/app/userservice.jar:/app/app.jar
depends_on:
- mysql
- nacos
cardservice:
image: openjdk:8
container_name: cardservice
environment:
- nacos_host=nacos
- nacos_port=8848
volumes:
- /usr/local/workspace/app/cardservice.jar:/app/app.jar
depends_on:
- mysql
- nacos
如文件中所示:
执行编排容器命令时,会创建一个mysql、nacos、userservice、cardservice四个容器。
其中userservice、cardservice是自己编写的基于SpringBoot的微服务项目。
这里的部署配置会复杂一些,和文章上部分有所不同,更偏向于实际开发。
按照这个配置,微服务中的pom文件中mysql的依赖需要改成8的版本,同时yml文件的驱动也需要更改。
这些都属于项目基本配置,就不再这里缀述了。
这样编写docker-compose.yml有一些明显的好处:
-
更容易管理每个微服务的端口、容器名称、环境变量、数据卷等何种参数,可维护性是大大提升的
-
不再需要把每个微服务的
jar搞成一样的名字,可以通过直接看jar包名称就知道是哪个微服务了 -
不再有那么多重复的
Dockerfile文件 -
今后部署只有在
docker-compose.yml中按userservice新增一项配置,并且把它的jar包上传到/usr/local/app下即可
5)上传需要部署的jar文件
根据docker-compose的配置内容,把网关和业务模块所的jar包,
即gddst-cloud-gateway.jar、userservice.jar、cardservice.jar的三个jar包上传到以下目录:
/usr/local/workspace/app/
6)执行部署命令
在docker-compose.yml文件所在目录下执行:
docker-compose up -d
即可完成部署。
写这步更多的是为了这套步骤的完整性、实际一般会使用
portainer来进行微服务的可视化部署管理
九、拓展
1)关于能否在一个文件中配置多个相同服务的问题
关于userservice和cardservice在一个dcoker-compose.yml文件里也是可以配置多个的。
只需要打出不同端口号的jar包即可。
包括mysql也是,这里只使用了一个,是最简单的格式。即使以后有了主从复制,也可以配置多个mysql。
这样就能完成一个更完善一些的集群配置。
2)关于fegin-api模块为什么不需要部署
fegin-api模块只是一个公共模块,被其它微服务所引用。
使用Maven打包SpringBoot项目的时候,有关的Maven依赖会自动打包进当前微服务项目的jar包中。
也就是说,每个依赖了fegin-api模块的微服务的jar包中内部,就已经有了fegin-api模块的内容。


















