如果您对docker封装SpringCloud(单机版)感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于docker封装SpringCloud(单机版)的详细内容,我们还将为
如果您对docker封装Spring Cloud(单机版)感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于docker封装Spring Cloud(单机版)的详细内容,我们还将为您解答docker封装应用的相关问题,并且为您提供关于Docker 部署Spring Boot、Spring Cloud构建的jar包、Docker 集群部署 SpringCloud 应用、Docker下的Spring Cloud三部曲之二:细说Spring Cloud开发、docker初体验:Docker部署SpringCloud项目eureka-server的有价值信息。
本文目录一览:- docker封装Spring Cloud(单机版)(docker封装应用)
- Docker 部署Spring Boot、Spring Cloud构建的jar包
- Docker 集群部署 SpringCloud 应用
- Docker下的Spring Cloud三部曲之二:细说Spring Cloud开发
- docker初体验:Docker部署SpringCloud项目eureka-server
docker封装Spring Cloud(单机版)(docker封装应用)
一、概述
微服务统一在一个git项目里面,项目的大致结构如下:
./
├── auth-server
│ ├── pom.xml
│ └── src
├── common
│ ├── pom.xml
│ └── src
├── config-server
│ ├── pom.xml
│ └── src
├── eureka-server
│ ├── pom.xml
│ └── src
├── gateway
│ ├── pom.xml
│ └── src
├── pom.xml
└── service-user
├── pom.xml
└── src
主要有5个微服务器,分别是eureka,config,auth,user,gateway
二、封装docker镜像
dockerfile
先来介绍eureka-server服务的dockerfile,其他微服务也是类似的,只不过jar包名和端口不一样,其他的都一样。
内容如下:
FROM mayan31370/openjdk-alpine-with-chinese-timezone:8-jdk
ADD repositories /etc/apk/repositories
ADD eureka-server.jar /
ADD run.sh /
RUN chmod 755 run.sh && mkdir -p /data/log/tomcat && apk update && apk add git
EXPOSE 8761
ENTRYPOINT [ "/run.sh"]
解释:
这里使用基础镜像为:mayan31370/openjdk-alpine-with-chinese-timezone:8-jdk
它使用的是openjdk-8,解决了中文乱码问题,时区问题等等。
/etc/apk/repositories 是alpine系统的更新源配置。相当于ubuntu的/etc/apt/soure.list
eureka-server.jar 是eureka微服务打的jar包
run.sh 是eureka微服务启动命令,由于命令过程,写在了shell脚本里面
RUN 里面写了一些命令,主要是添加脚本执行权限,创建日志目录,由于eureka微服务写的日志是这个,因此需要提前创建。
由于config微服务器,需要从gitlab拉取配置文件,因此还需要安装git命令才能执行:git clone http://xxx。
EXPOSE 是这容器需要暴露的端口
ENTRYPOINT 表示容器里面的服务器启动命令
repositories
这个采用的的是阿里云的更新源
#aliyun
https://mirrors.aliyun.com/alpine/v3.6/main/
https://mirrors.aliyun.com/alpine/v3.6/community/
run.sh
这个是Java应用的启动命令
#!/bin/sh
java -Xms${JVM} -Xmx${JVM} -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=256m -jar /eureka-server.jar
这里有一个jvm变量,待会docker启动时,会传入此变量。
构建镜像
上面介绍的几个文件,都在eureka-server目录。进入此目录,使用build命令构建
cd eureka-server
docker build -t eureka-server:1 .
运行镜像
先创建网桥,1台服务器只需要创建一次即可。
再运行容器
docker network create testnet
docker run -it -d --restart=always --name eureka-server --network testnet --network-alias eureka-server -p 8761:8761 -v /data/log/tomcat:/data/log/tomcat -e JVM=128m eureka-server:1
三、jenkins发布java项目
环境介绍
gitlab版本:GitLab 社区版 10.5.1
jenkins版本:2.219
服务器:centos 7.6(单机)
由于jenkins服务器的操作系统为:centos 6.9,它不能安装docker,因此docker打包动作需要在服务器上面执行。
ansible分组
vi /etc/ansible/hosts
内容如下:
[test_java]
192.168.28.34
ansible playbook
发布模板
vi /opt/ansible/test/docker_java.yml
内容如下:


---
# 需要传入变量HOSTS,ENV,PROJECT_NAME,PREFIX,PORT,JVM
# 分别表示: 主机, 环境,项目名,路径前缀(拼接jenkins jar包路径),端口,jvm大小
- hosts: "{{ HOSTS }}"
remote_user: root
become: yes
become_method: sudo
# 声明变量
vars:
# 远程项目基础目录
BASE_DIR: "/data/code"
# 远程项目目录名
PROJECT_DIR: "{{ ENV }}_{{ PROJECT_NAME }}_{{ PORT }}"
# 完整的jenkins 项目跟路径
JENKINS_DIR: "/data/jenkins_data/workspace/{{ JOB_NAME }}/{{ PREFIX }}"
tasks:
#删除原来的包
- name: move old package
file: path={{ BASE_DIR }}/{{ PROJECT_DIR }}/{{ PROJECT_NAME }}.jar state=absent
#同步jar包到目标服务器
- name: synchronous jar packet
synchronize:
src: "{{ JENKINS_DIR }}/target/{{ PROJECT_NAME }}.jar"
dest: "{{ BASE_DIR }}/{{ PROJECT_DIR }}/"
#复制jmx_exporter文件
- name: copy repositories
shell: \cp /data/alpine/repositories {{ BASE_DIR }}/{{ PROJECT_DIR }}/
#同步dockerfile到目标服务器
- name: synchronous dockerfile
synchronize:
src: "{{ JENKINS_DIR }}/dockerfile"
dest: "{{ BASE_DIR }}/{{ PROJECT_DIR }}/"
#同步run.sh到目标服务器
- name: synchronous run.sh
synchronize:
src: "{{ JENKINS_DIR }}/run.sh"
dest: "{{ BASE_DIR }}/{{ PROJECT_DIR }}/"
# 打包镜像
- name: docker build
shell: cd {{ BASE_DIR }}/{{ PROJECT_DIR }} && docker build -t {{ PROJECT_NAME }}:{{ BUILD_NUMBER }} .
#删除之前的docker
- name: docker rm image
shell: docker rm -f {{ PROJECT_NAME }}
ignore_errors: yes
#启动docker
- name: docker run image
# # 提前创建bridge网络:docker network create testnet
shell: docker run -it -d --restart=always --name {{ PROJECT_NAME }} --network testnet --network-alias {{ PROJECT_NAME }} -p {{ PORT }}:{{ PORT }} -v /data/log/tomcat:/data/log/tomcat -e JVM={{ JVM }} {{ PROJECT_NAME }}:{{ BUILD_NUMBER }}
- name: view port,Wait for 55 seconds
shell: sleep 55;docker exec {{ PROJECT_NAME }} netstat -anpt|grep {{ PORT }}
回滚模板
vi /opt/ansible/test/docker_java_rollback.yml
内容如下:


---
# 需要传入变量HOSTS,PROJECT_NAME,PORT,JVM,BUILD_ID
# 分别表示: 主机, 项目名,端口,jvm大小,回滚的构建ID
- hosts: "{{ HOSTS }}"
remote_user: root
become: yes
become_method: sudo
tasks:
#删除之前的docker
- name: docker rm image
shell: docker rm -f {{ PROJECT_NAME }}
ignore_errors: yes
#启动docker
- name: docker run image
# # 提前创建bridge网络:docker network create testnet
shell: docker run -it -d --restart=always --name {{ PROJECT_NAME }} --network testnet --network-alias {{ PROJECT_NAME }} -p {{ PORT }}:{{ PORT }} -v /data/log/tomcat:/data/log/tomcat -e JVM={{ JVM }} {{ PROJECT_NAME }}:{{ BUILD_ID }}
- name: view port,Wait for 55 seconds
shell: sleep 55;docker exec {{ PROJECT_NAME }} netstat -anpt|grep {{ PORT }}
新建job
新建一个job,名字为:test_eureka_server,使用自由风格
通用配置
参数化构建
源码管理
构建
执行shell
完整内容如下:


case $Status in
Deploy)
echo "Status:$Status"
ansible-playbook -v /opt/ansible/test_java.yml -e "HOSTS=test_java JOB_NAME=${JOB_NAME} BUILD_NUMBER=${BUILD_NUMBER} ENV=test PROJECT_NAME=eureka-server PREFIX=eureka-server PORT=8761 JVM=128m"
echo "Completing!"
;;
Rollback)
echo "Status:$Status"
echo "BUILD_ID:$BUILD_ID"
ansible-playbook -v /opt/ansible/test_java_rollback.yml -e "HOSTS=test_java JOB_NAME=${JOB_NAME} BUILD_ID=${BUILD_ID} PROJECT_NAME=eureka-server PORT=8761 JVM=128m"
echo "Completing!"
;;
*)
exit
;;
esac
点击最下面的保存,最后点击构建即可
发布时,build_id无需填写。回滚时,选择Rollback,输入指定的build_id即可。
Docker 部署Spring Boot、Spring Cloud构建的jar包
安装docker
略
方法一
找一个无人的角落……新建一个文件夹,切记切记,这个文件夹千万不要有其他任何没有关联的文件,因为这个文件夹的所有文件都会被打包到镜像中。
mkdir /home/yu/jar
把你的test.jar包复制到这个文件夹
mv nimeide.jar /home/yu/jar/test.jar
新建一个Dockerfile文件,注意,不要改名
vi Dockerfile
给Dockerfile文件写点暗号
FROM openjdk:8
MAINTAINER nierdaye
ADD test.jar demo.jar
EXPOSE 80
ENTRYPOINT ["java","-jar","demo.jar"]
暗号解释
//引用公共仓库的openjdk镜像,版本号是8,如果不清楚这个镜像在不在,可以跑命令docker search xxx自己搜一下看看有没有你想要的镜像
FROM openjdk:8
//声明作者是你二大爷
MAINTAINER nierdaye
//就是把文件塞镜像里面,test.jar是外面的文件,demo.jar是镜像里面的文件名,这里不带目录的话就是放在根目录,你也可以改成带目录的形式,如:ADD /home/yu/jar/test.jar /home/nimei/demo.jar。
ADD test.jar demo.jar
//程序运行的端口号
EXPOSE 80
//这一句就是运行程序的代码了,如果你需要jvm加上啥参数的话或者是启动的时候需要带什么格式的命令之类的,均可以加这里,同时也需要注意后面jar包的路径,建议是写成绝对路径
ENTRYPOINT ["java","-jar","demo.jar"]
保存好文件之后,在本路径运行命令
//java-demo是镜像名称,1.0.0是版本号,中间用冒号隔开,最后面的点表示的是这个Dockerfile配置文件在当前目录
docker build -t java-demo:1.0.0 .
不报错就是成功了,可以运行一下docker images命令查看本地的镜像列表,就看到了
这个镜像是已经可以用的了,把这个镜像传到你的服务器,直接用就可以用了
也可以直接跑一下试试效果
-d 后台运行
--name 项目名称
-p 端口映射,外面的8080映射到里面的80
java-demo 镜像名称
docker run -d --name haha -p 8080:80 java-demo
跑起来直接就是可以了
方法二(不推荐)
搜索java镜像,这里用的是官方仓库(说出来比较丢人,主要是还没学会怎么切仓库)
docker search java
把java镜像拉取下来
docker pull java
不报错的话就下载到本地了,查看一下本地镜像库的列表
docker images
然后把我们要运行的test.jar包复制到目录:/home/yu
docker run -d --restart=always -p 9899:9899 -v /home/yu:/home/jar --name test-name java /usr/bin/java -jar /home/jar/test.jar
命令解析
docker run
-d --restart=always
//映射端口号
-p 9899:9899
//挂载主机目录,/home/yu是安装docker的这台机器的路径,即主机的目录,/home/jar是docker内部的路径,映射了之后,就是docker里面访问的/home/jar这个目录,其实访问的是主机的/home/yu目录
-v /home/yu:/home/jar
//给项目起一个名字
--name test-name
//运行jar的命令(由于没设置环境变量)
java /usr/bin/java -jar /home/jar/test.jar
看一下当前的docker列表
docker ps -a
看到状态是UP,证明已经跑起来了,访问一下IP:9899端口,应该是可以访问到你的程序了。
我们可以进入到docker里面看看里面的情况。
docker exec -it test-name /bin/bash
进去之后,可以打开/home/jar目录,在对比外面的/home/yu目录,就会发现,他两的内容是一样的,这里要注意的是,目录是映射的,并非复制,即你在docker的/home/jar目录删除文件,出来了到/home/yu目录发现文件也是不在了的。
退出docker空间
exit
停止test-name这个任务
docker stop test-name
启动test-name这个任务
docker start test-name
启动了之后发现,程序已经自动启动起来了,可以直接调用。
但是这种有风险,如果你环境发生了变化,你挂载的路径无法访问,基本上就凉凉了。
Docker 集群部署 SpringCloud 应用
整体架构
docker 环境准备
# linux下的安装,自行百度
# windows docker toolbox下载地址
https://download.docker.com/win/stable/DockerToolbox.exe
# 创建myvm3 这个虚拟机内存尽量大,6g以上最好
# https://0eenj1uv.mirror.aliyuncs.com这个是阿里云加速器的地址。
docker-machine create --virtualbox-memory "6144" --engine-registry-mirror="https://s0iielsh.mirror.aliyuncs.com" --engine-insecure-registry="0.0.0.0/0" -d virtualbox myvm3
# 停止
docker-machine.exe stop myvm3
# 启动
docker-machine.exe start myvm3
docker-machine env myvm3
# windows cmd下 执行下面这个命令,代表当前cmd控制台会使用myvm3中的docker
@FOR /f "tokens=*" %i IN (''docker-machine env myvm3'') DO @%i
# windows powershell下 执行下面这个命令,代表当前cmd控制台会使用myvm3中的docker
& "docker-machine.exe" env myvm3 | Invoke-Expression
创建 swarm 集群
# 创建swarm集群
# 在myvm1中创建一个swarm manage主节点。 linux下直接写IP,windows下写虚拟机IP
docker swarm init --advertise-addr <机器ip>
# 创建集群下的网络
docker network create -d overlay --subnet 10.0.0.1/24 --attachable swarm_net
# 确定集群是否完成,在manage节点上可以看到当前集群有哪些机器。
docker node ls
# 添加集群可视化管理的工具portainer,它实际上还是docker提供的命令在干活
# 9001端口,进去后改密码,用户名 admin 密码 tryportainer
docker service create --name docker_portainer --publish 9001:9000 --constraint ''node.role == manager'' --mount type=bind,src=/etc/localtime,dst=/etc/localtime --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock portainer/portainer -H unix:///var/run/docker.sock
# 新的节点怎么加入?
# 在manage节点上执行下面这个命令,生成一个用于新manage加入的token。 在新节点中心执行输出的内容可以用于manage加入swarm集群
docker swarm join-token manager
# 在manage节点上执行下面这个命令,生成一个用于worker节点加入的token。在新节点中心执行输出的内容可以用于worker子节点加入swarm集群
docker swarm join-token worker
# 如果要退出swarm集群,使用下面这个命令,退出不了就加个 --force
docker swarm leave
部署基础环境
# 一键运行(这些基础中间件是单机部署的)单机和集群两种方式
# swarm集群部署(注:中间件并不是说部署了多个实例就是集群了,要注意。)
docker stack deploy --compose-file .\docker-compose-middleware.yml base
maven 配置
<!--修改maven中conf/settings.xml文件-->
<!--servers节点加入docker私有仓库的用户名和密码信息-->
<servers>
<server>
<id>docker-aliyun-hub</id>
<username>用户名</username>
<password>密码</password>
<configuration>
<email>邮箱</email>
</configuration>
</server>
</servers>
构建微服务的 docker 镜像
# 1、添加环境变量,设置docker私有仓库的地址。可以设置永久的,也可以通过下面的命令设置临时的。(永久环境变量的方法自行百度)
# ip记得改成你自己的仓库地址
# windows下powershell临时设置,当前窗口有效
$Env:DOCKER_REGISTRY_URL = "192.168.99.100:5000"
# windows 下cmd临时设置
set DOCKER_REGISTRY_URL=192.168.99.100:5000
# linux 下临时设置,当前登录session有效
export DOCKER_REGISTRY_URL=192.168.99.100:5000
# 注意:私服需要密码的情况,通过 docker pull 拉取镜像之前,需要先登录 docker login ...
# 2、通过maven插件打包、构建镜像并推送到私有仓库
# 使用maven打包
mvn clean install
# 将指定的服务 构建镜像 并 推送到私有仓库。 这个一定要在具体的服务下执行
mvn docker:build -DpushImage
# mvn clean install docker:build -DpushImage
# 管理私有镜像仓库
# 查看镜像,通过http请求
http://192.168.99.100:5000/v2/_catalog
http://192.168.99.100:5000/v2/<镜像名>/tags/list
# 删除镜像,这个操作需要在虚拟机内部去操作,喜欢折腾的去做。
# 进入容器内部
# docker exec -it registry bash
# 镜像保存在这个文件夹下,可以手动删除里面的镜像
# /var/lib/registry/docker/registry/v2/repositories/
# 退出容器 exit
部署公共组件
# 公共组件有:eureka、configserver
# 集群模式部署
docker stack deploy --compose-file .\docker-compose-common.yml common-service
部署核心组件
# 核心组件部署
# 基础组件 网关和uaa
# 数据库初始化
# 连接mysql服务器,创建uaa-db数据库
# 集群模式部署
docker stack deploy --compose-file .\docker-compose-core.yml core-service
# 启动完成以后,往uaa数据库中添加一个用户
INSERT INTO `uaa-db`.`tb_user` (`user_id`, `email`, `password`, `phone`, `user_name`) VALUES (''1'', ''123@qq.com'', ''123'', ''10086'', ''tony'');
部署业务服务
# 业务服务部署
# 订单服务、仓储服务、短信服务、邮件服务
# 数据库初始化
# 连接mysql服务器,创建四个数据库order-db,wms-db,sms-db,mail-db
# 集群模式部署
docker stack deploy --compose-file .\docker-compose-service.yml biz-service
# 启动完成以后,往wms数据添加一个商品
INSERT INTO `wms-db`.`tb_goods` (`goods_id`, `goods_name`, `sku_id`, `stock_count`, `version`) VALUES (''1'', ''充气玩具'', ''1'', ''50'', ''0'');
验证方式
1、获取token
post 请求 http://192.168.99.101:8765/api/token/byPhone
{
"phone":"10086",
"password":"123"
}
2、 http请求时header中设置Authorization的值为上面获取的token内容。
3、下单:http://192.168.99.101:8765/api/order-service/order/new/1
返回end代表正常。
检查方式:看数据库有米有数据
集群 service 扩容 / 更新方式
# 1、通过postainer可视化界面操作
# 2、通过命令管理service 文档地址:https://docs.docker.com/engine/reference/commandline/service/
查看集群中所有服务: docker service ls
更新指定的服务: docker service update
服务扩容: docker service scale
# 服务栈 - 批量管理service 文档地址:https://docs.docker.com/engine/reference/commandline/stack/
查看所有栈: docker stack ls
查看栈中服务的状态: docker stack ps <stack名称>
其他常用的命令
# 1、查看所有docker容器的资源占用情况
docker stats -a
# 2、看容器执行日志
docker logs -f <容器ID或名称>
maven 插件
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>${env.DOCKER_REGISTRY_URL}/${project.artifactId}:${project.version}</imageName>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<!-- 以下两行是为了docker push到DockerHub使用的。 -->
<serverId>docker-aliyun-hub</serverId>
<registryUrl>${env.DOCKER_REGISTRY_URL}</registryUrl>
</configuration>
</plugin>
编排服务
# 业务组件部署
# 订单服务、仓储服务、短信服务、邮件服务
version: "3.2"
services:
# 1、订单服务
order-service:
# 镜像地址
image: 192.168.99.100:5000/order-service:1.0.0
# 容器名称
container_name: order-service
# 端口不对外开放
env_file:
# 加载环境变量
- ./service.env
networks:
# 加入集群网络
- swarm_net
volumes:
# 将宿主机上的文件挂载到容器内
- type: "bind"
source: /etc/localtime
target: /etc/localtime
deploy:
# 实例数量
replicas: 1
# 更新选项
update_config:
# 每次更新多少个容器
parallelism: 1
# 间隔时间
delay: 10s
# 启动错误时,重新启动
restart_policy:
condition: on-failure
resources:
limits:
# CPU限制
cpus: ''0.5''
# 内存限制
memory: 256M
# 健康检查,启动后,当这个命令执行没问题,才会任何这个服务启动成功
healthcheck:
# 命令
test: ["CMD", "curl", "-f", "http://localhost:9001/info"]
# 间隔时间,安装应用的预计启动时间来设置。比如我们这个springcloud的应用,一般在1分钟半内预计启动完成
interval: 1m30s
timeout: 10s
# 重试次数
retries: 5
# 2、仓储服务
wms-service:
# 镜像地址
image: 192.168.99.100:5000/wms-service:1.0.0
# 容器名称
container_name: wms-service
# 端口不对外开放
env_file:
# 加载环境变量
- ./service.env
networks:
# 加入集群网络
- swarm_net
volumes:
# 将宿主机上的文件挂载到容器内
- type: "bind"
source: /etc/localtime
target: /etc/localtime
deploy:
# 实例数量
replicas: 1
# 更新选项
update_config:
# 每次更新多少个容器
parallelism: 1
# 间隔时间
delay: 10s
# 启动错误时,重新启动
restart_policy:
condition: on-failure
resources:
limits:
# CPU限制
cpus: ''0.5''
# 内存限制
memory: 256M
# 健康检查,启动后,当这个命令执行没问题,才会任何这个服务启动成功
healthcheck:
# 命令
test: ["CMD", "curl", "-f", "http://localhost:9002/info"]
# 间隔时间,安装应用的预计启动时间来设置。比如我们这个springcloud的应用,一般在1分钟半内预计启动完成
interval: 1m30s
timeout: 10s
# 重试次数
retries: 5
# 3、短信服务
sms-service:
# 镜像地址
image: 192.168.99.100:5000/sms-service:1.0.0
# 容器名称
container_name: sms-service
# 端口不对外开放
env_file:
# 加载环境变量
- ./service.env
networks:
# 加入集群网络
- swarm_net
volumes:
# 将宿主机上的文件挂载到容器内
- type: "bind"
source: /etc/localtime
target: /etc/localtime
deploy:
# 实例数量
replicas: 1
# 更新选项
update_config:
# 每次更新多少个容器
parallelism: 1
# 间隔时间
delay: 10s
# 启动错误时,重新启动
restart_policy:
condition: on-failure
resources:
limits:
# CPU限制
cpus: ''0.5''
# 内存限制
memory: 256M
# 健康检查,启动后,当这个命令执行没问题,才会任何这个服务启动成功
healthcheck:
# 命令
test: ["CMD", "curl", "-f", "http://localhost:9005/info"]
# 间隔时间,安装应用的预计启动时间来设置。比如我们这个springcloud的应用,一般在1分钟半内预计启动完成
interval: 1m30s
timeout: 10s
# 重试次数
retries: 5
# 4、邮件服务
mail-service:
# 镜像地址
image: 192.168.99.100:5000/mail-service:1.0.0
# 容器名称
container_name: mail-service
# 端口不对外开放
env_file:
# 加载环境变量
- ./service.env
networks:
# 加入集群网络
- swarm_net
volumes:
# 将宿主机上的文件挂载到容器内
- type: "bind"
source: /etc/localtime
target: /etc/localtime
deploy:
# 实例数量
replicas: 1
# 更新选项
update_config:
# 每次更新多少个容器
parallelism: 1
# 间隔时间
delay: 10s
# 启动错误时,重新启动
restart_policy:
condition: on-failure
resources:
limits:
# CPU限制
cpus: ''0.5''
# 内存限制
memory: 256M
# 健康检查,启动后,当这个命令执行没问题,才会任何这个服务启动成功
healthcheck:
# 命令
test: ["CMD", "curl", "-f", "http://localhost:9003/info"]
# 间隔时间,安装应用的预计启动时间来设置。比如我们这个springcloud的应用,一般在1分钟半内预计启动完成
interval: 1m30s
timeout: 10s
# 重试次数
retries: 5
networks:
swarm_net:
external: true
Docker下的Spring Cloud三部曲之二:细说Spring Cloud开发
本文是《Docker下的Spring Cloud三部曲》系列的第二篇,详细讲解上一篇实例中用到的eureka、provider、consumer等三个应用的开发过程;
原文地址:http://blog.csdn.net/boling_cavalry/article/details/79134497
环境信息
回顾一下实战环境,如下图:
源码地址
上图的eureka、provider、consumer是三个spring boot的web工程,源码可以在GitHub下载,地址和链接信息如下表所示:
名称 | 链接 | 备注 |
---|---|---|
项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
这个git项目中有多个工程,本次实战的工程是springcloudscaledemo,如下图红框所示:
如何将spring boot工程构建成docker镜像
如果您想了解如何将spring boot工程构建docker镜像,欢迎访问以下三篇实战文章:
- 《maven构建docker镜像三部曲之一:准备环境》;
- 《maven构建docker镜像三部曲之二:编码和构建镜像》;
- 《maven构建docker镜像三部曲之三:推送到远程仓库(内网和阿里云)》;
本次实战用到的知识点主要集中在上面的第二部;
开发环境
本次实战开发环境的具体信息如下:
- 操作系统:Ubuntu16;
- Docker版本:17.03.2-ce;
- JDK:1.8.0_151;
- maven:3.3.3;
接下来我们依次开发eureka、provider、consumer等三个应用;
eureka-server应用的pom.xml
新建一个名为 eureka-server的spring boot应用,pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>eureka-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--新增的docker maven插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<!--docker镜像相关的配置信息-->
<configuration>
<!--镜像名,这里用工程名-->
<imageName>bolingcavalry/${project.artifactId}</imageName>
<!--TAG,这里用工程版本号-->
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<!--镜像的FROM,使用java官方镜像-->
<baseImage>java:8u111-jdk</baseImage>
<!--该镜像的容器启动后,直接运行spring boot工程-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!--构建镜像的配置信息-->
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
pom.xml中的几个关键点如下:
- spring cloud的版本是Edgware.SR1;
- 添加spring-cloud-starter-eureka-server的依赖;
- 添加spring-cloud-dependencies的依赖(pom的形式);
- 添加插件docker-maven-plugin,用于将当前工程制作成本地docker镜像;
eureka-server应用的源码
eureka-server应用只有一个java文件,内容如下:
package com.bolingcavalry.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
注意要添加@EnableEurekaServer注解;
eureka-server的配置信息
配置信息application.properties的内容如下:
server.port=8080
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
构建eureka-server应用的docker镜像
- 在pom.xml文件所在目录下,执行如下命令可以构建docker镜像:
mvn clean package -U -DskipTests docker:build
- 构建成功后,执行命令docker images可见新构建的镜像,如下:
ubuntu@VM-129-56-ubuntu:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bolingcavalry/eureka-server 0.0.1-SNAPSHOT 80663220a5f5 35 hours ago 683 MB
bolingcavalry/eureka-server latest 80663220a5f5 35 hours ago 683 MB
eureka-server的镜像OK后,我们接下来构建provide的镜像;
provider应用的pom.xml
新建一个名为service-provider的spring boot应用,pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId>
<artifactId>service-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-provider</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--新增的docker maven插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<!--docker镜像相关的配置信息-->
<configuration>
<!--镜像名,这里用工程名-->
<imageName>bolingcavalry/${project.artifactId}</imageName>
<!--TAG,这里用工程版本号-->
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<!--镜像的FROM,使用java官方镜像-->
<baseImage>java:8u111-jdk</baseImage>
<!--该镜像的容器启动后,直接运行spring boot工程-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!--构建镜像的配置信息-->
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
provider应用的源码
- 入口类ServiceProviderApplication的源码如下:
package com.bolingcavalry.serviceprovider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceProviderApplication.class, args);
}
}
注意要添加@EnableDiscoveryClient注解;
- 只有一个controller类UserController ,对外提供http服务:
@RestController
public class UserController {
@RequestMapping(value = "/getuserinfo/{id}", method = RequestMethod.GET)
public String getUserInfo(@PathVariable String id){
return String.format("user[%s]", id);
}
@RequestMapping(value = "/getuserinfo", method = RequestMethod.GET)
public String getUserInfoWithRequestParam(@RequestParam("id") String id, @RequestParam("name") String name){
return String.format("user [%s], id [%s], from server [%s]", name, id, getIPAddr());
}
/**
* 获取本机IP地址
* @return
*/
private static String getIPAddr(){
String hostAddress = null;
try{
InetAddress address = InetAddress.getLocalHost();
hostAddress = address.getHostAddress();
}catch (UnknownHostException e){
e.printStackTrace();
}
return hostAddress;
}
}
上面的controller提供两个http服务,getUserInfoWithRequestParam服务会返回应用所在机器的IP地址;
provider的配置信息
provider的配置信息存放在application.yml文件中,内容如下:
server:
port: 8080
spring:
application:
name: microservice-provider-user
eureka:
client:
serviceUrl:
defaultZone: http://eurekahost:8080/eureka/
instance:
prefer-ip-address: true
注意上面配置的注册中心地址为http://eurekahost:8080/eureka/,eurekahost在docker-compose中会作为link参数对应eureka server;
构建provider应用的docker镜像
- 在pom.xml文件所在目录下,执行如下命令可以构建docker镜像:
mvn clean package -U -DskipTests docker:build
- 构建成功后,执行命令docker images可见新构建的镜像,如下:
ubuntu@VM-129-56-ubuntu:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bolingcavalry/eureka-server 0.0.1-SNAPSHOT 80663220a5f5 35 hours ago 683 MB
bolingcavalry/eureka-server latest 80663220a5f5 35 hours ago 683 MB
bolingcavalry/service-provider 0.0.1-SNAPSHOT a02f307bc1a9 22 hours ago 683 MB
bolingcavalry/service-provider latest a02f307bc1a9 22 hours ago 683 MB
provider已经OK,接下来是consumer工程;
consumer应用的pom.xml
新建一个名为service-consumer的spring boot应用,pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId>
<artifactId>service-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--新增的docker maven插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<!--docker镜像相关的配置信息-->
<configuration>
<!--镜像名,这里用工程名-->
<imageName>bolingcavalry/${project.artifactId}</imageName>
<!--TAG,这里用工程版本号-->
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<!--镜像的FROM,使用java官方镜像-->
<baseImage>java:8u111-jdk</baseImage>
<!--该镜像的容器启动后,直接运行spring boot工程-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!--构建镜像的配置信息-->
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
和前面两个应用相比,这里要引入spring-cloud-starter-feign;
consumer的源码
- 入口类ServiceConsumerApplication 源码如下:
package com.bolingcavalry.serviceconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class ServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceConsumerApplication.class, args);
}
}
注意要增加@EnableDiscoveryClient和@SpringBootApplication这两个注解;
- 增加一个带注解@FeignClient的接口,用于在spring cloud环境中声明远程调用信息:
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
@RequestMapping(value = "/getuserinfo", method = RequestMethod.GET)
String getUserInfoWithRequestParam(@RequestParam("id") String id, @RequestParam("name") String name);
}
- 增加一个controller类UserFacadeController,为浏览器访问提供http服务,并且在响应请求的时候会通过UserFeignClient接口的实现远程调用provider应用的服务:
@RestController
public class UserFacadeController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/user/{id}/{name}")
public String getUserInfo(@PathVariable("id") final String id, @PathVariable("name") final String name) {
return "1. ---" + userFeignClient.getUserInfoWithRequestParam(id, name);
}
}
consumer的配置信息
provider的配置信息存放在application.yml文件中,内容如下:
server:
port: 8080
spring:
application:
name: service-consumer
eureka:
client:
serviceUrl:
defaultZone: http://eurekahost:8080/eureka/
instance:
prefer-ip-address: true
注意上面配置的注册中心地址为http://eurekahost:8080/eureka/,eurekahost在docker-compose中会作为link参数对应eureka server;
构建provider应用的docker镜像
- 在pom.xml文件所在目录下,执行如下命令可以构建docker镜像:
mvn clean package -U -DskipTests docker:build
- 构建成功后,执行命令docker images可见新构建的镜像,如下:
ubuntu@VM-129-56-ubuntu:~$docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bolingcavalry/service-provider 0.0.1-SNAPSHOT a02f307bc1a9 47 hours ago 683 MB
bolingcavalry/service-provider latest a02f307bc1a9 47 hours ago 683 MB
bolingcavalry/service-consumer 0.0.1-SNAPSHOT ae6b37b99754 2 days ago 683 MB
bolingcavalry/service-consumer latest ae6b37b99754 2 days ago 683 MB
bolingcavalry/eureka-server 0.0.1-SNAPSHOT 80663220a5f5 2 days ago 683 MB
bolingcavalry/eureka-server latest 80663220a5f5 2 days ago 683 MB
至此,本次实战所需的所有镜像都制作完毕,相关的demo工程的开发过程我们也一起过了一遍,上一章中的实战您已经可以独立做出来了,接下来的实战中,我们一起来尝试服务横向扩容;
欢迎关注我的公众号:程序员欣宸
本文同步分享在 博客“程序员欣宸”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
docker初体验:Docker部署SpringCloud项目eureka-server
Docker部署SpringCloud项目eureka-server
1 创建eureka-server工程
创建父工程cloud-demo,其pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
<groupId>top.flygrk.ishare</groupId>
<artifactId>cloud-demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>cloud-eureka-server</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建cloud-eureka-server模块,其格式如下:
pom.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud-demo</artifactId>
<groupId>top.flygrk.ishare</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-eureka-server</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<finalName>eureka-server</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- tag::plugin[] -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>/test/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<!-- end::plugin[] -->
</plugins>
</build>
</project>
2 eureka-server工程打包
使用maven对cloud-eureka-server模块打包,结果如下:
3 上传eureka-server.jar到服务器
上传eureka-server.jar到服务器路径/app/eureka-server:
4 编写Dockerfile文件
编写Dockerfile内容如下:
FROM java:8
VOLUME /tmp
ADD eureka-server.jar app.jar
EXPOSE 8761
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
5 打包eureka-server镜像
在/app/eureka-server目录下,执行如下命令进行docker镜像打包:
docker build -t eureka_v1.0.0 .
6 查看docker镜像
查看系统上的docker镜像,使用docker images
命令:
7 运行eurake镜像
使用下面的命令启动eureka镜像:
docker run -d --name eureka-server -p 8761:8761 c4bfd23fe99d
8 查看docker镜像运行情况
使用docker ps
查看docker镜像运行情况:
docker ps -a
8 查看docker eureka-server日志
使用下面的命令查看eureka-server日志:
docker logs --since 2019-12-18T09:50:15 eureka-server
感谢您的观看,如有宝贵意见,烦请及时提出,谢谢。欢迎关注微信公众号:源码湾~
关于docker封装Spring Cloud(单机版)和docker封装应用的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Docker 部署Spring Boot、Spring Cloud构建的jar包、Docker 集群部署 SpringCloud 应用、Docker下的Spring Cloud三部曲之二:细说Spring Cloud开发、docker初体验:Docker部署SpringCloud项目eureka-server的相关信息,请在本站寻找。
本文标签: