Docker部署SpringBoot应用

标签: 无 分类: 未分类 创建时间:2021-07-02 12:58:08 更新时间:2024-11-23 02:04:25

1.前言

一直以来都是直接使用的阿里云部署了Spring Cloud应用程序,但是实际上,部分的微服务总是被系统莫名其妙的杀死,于是就总会使程序莫名其妙的无法运行,为此,我编写了定时检查任务的脚本,如果发现某一个进程死掉了,就立马启动起来,同时我还使用了Nginx的负载均衡功能,弄了多台虚拟机进行程序的部署,但是最后还是不理想,为什么嗯?因为其中的三台虚拟机是在一个服务器上的HyperV上创建出来的,其实只要是这台服务器挂掉了,那么这个集群也就挂掉了,没办法,条件有限啊,怎么办呢?我尝试使用了Docker的方式进行部署单应用,这样可能即便另一个集群坏掉了,可以快速的启动这个备用的节点。
当然,上面的都是废话,因为进程被杀死,测试不充分就上线的问题,我已经被老板骂过很多次了,虽然不是我的问题,但是他就认为是我的问题,导致我莫名的气愤,拿人钱财,替人消灾,那有什么办法呢?言归正传好了。

2.目标

这次的目标,主要包括:

  • 创建docker镜像
  • 安装openjdk13
  • 安装nginx
  • 安装redis
  • 上传打包后的springboot程序和vue前端代码
  • 运行前后端分离的项目
  • 打包整个系统到docker镜像中
  • 在其他系统中运行这个镜像

3.安装启动CentOS

docker的命令主要包括两大类,一类是容器操作,一类是镜像操作。

  • 容器生命周期管理:run,start/stop/restart,kill,rm,pause/unpause,create,exec
  • 容器操作:ps,inspect,top,attach,events,logs,wait,export,port
  • 容器rootfs命令:commit,cp,diff
  • 镜像仓库:login,pull,push,search
  • 本地镜像管理:images,rmi,tag,build,history,save,load,import
  • info|version:info,version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
## 拉取最新版centos
docker pull centos:latest
## 查看images
docker images -a
## 运行Centos
## -d: 后台运行容器,并返回容器ID;
## -i: 以交互模式运行容器,通常与 -t 同时使用;
## --name="springboot": 为容器指定一个名称;
docker run -itd --name springboot centos:latest

## 指定端口映射,将容器的7000端口映射到主机的9000端口
docker run -p 9000:7000 -p 6000:7001 -itd --name springboot_nginx springboot:nginx

## 为了使用systemctl,需要添加privileged参数
docker run -itd --privileged --name springboot centos:latest /usr/sbin/init

## mysql
docker run -itd --privileged -p 3306:3306 --name mysql centos:latest /usr/sbin/init

## 查看所有容器
docker ps -a

## 进入容器
#docker exec :在运行的容器中执行命令
# -d :分离模式: 在后台运行
# -i :即使没有附加也保持STDIN(标准输入) 打开,以交互模式运行容器,通常与 -t 同时使用;
# -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
docker exec -it <容器名称或者是容器id> /bin/bash

这里我就索性把容器的名称定位springboot吧

参考文章:
1.Docker启动一个Centos镜像 docker attach 进入到容器
2.Docker run 命令参数及使用 这里是英文解释,看着有点别扭
3.Docker run 命令 这里的中文解释,就舒服多了
4.docker常规操作——启动、停止、重启容器实例
5.docker run 和 start 的区别 docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start 即可。docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start);docker start的作用是,重新启动已存在的镜像。也就是说,如果使用这个命令,我们必须事先知道这个容器的ID,或者这个容器的名字,我们可以使用docker ps找到这个容器的信息。
6.Docker删除容器与镜像 删除所有停止的容器:docker container prune;
7.docker常规操作——删除容器实例、删除镜像 docker rm 容器ID或容器名;docker rmi 镜像ID或镜像名
8.docer run 、docker attach 与 docker exec的区别 docker run;创建和启动一个新的容器实例,操作对象是镜像,选项较多,如果你要创建和启动一个容器,只能用run;docker exec: 在已运行的容器中,执行命令,操作对象是容器,如果你要进入已运行的容器,并且执行命令,用exec;docker attach: 同样操作的是已运行的容器,可以将本机标准输入(键盘输入)输到容器中,也可以将容器的输出显示在本机的屏幕上,如果你想查看容器运行过程中产生的标准输入输出,用attach,但是需要注意的是,如果从这个stdin中exit,会导致容器的停止。
9.添加和修改docker容器端口映射的方法 方法一:修改此容器的hostconfig.json文件中的映射端口;方法二:使用宿主机的iptable转发端口
10.Docker-端口映射
11.docker容器添加对外映射端口 方式一:将现有的容器打包成镜像,然后在使用新的镜像运行容器时重新指定要映射的端口;方式二:修改要端口映射的容器的配置文件;
12.docker:一个container映射多个端口到Host

4.安装JDK

新建了CentOS容器,并启动之后,首先要做的就是要进行文件拷贝,我这里就以安装jdk13为例,描述文件拷贝和安装jdk的方法。在windows10下,为了将下载的openjdk13的软件包拷贝到容器中,需要先停止容器,然后使用docker cp命令进行拷贝,然后再启动容器。

1
2
3
4
5
6
7
8
9
10
11
## 停止容器
docker stop springboot
## 进行文件拷贝,将当前目录下(我直接在windows的下载文件夹下)的文件,拷贝到springboot容器的/cloud目录下
docker cp .\openjdk-13_linux-x64_bin.tar.gz springboot:/cloud
## 启动容器
docker start springboot
## 重启
docker restart springboot

## 再次连接容器
docker exec -it springboot /bin/bash

接下来的就是配置java环境变量了

1
2
3
4
5
6
7
8
9
10
## 编辑/etc/profile文件
vi /etc/profile
## 添加如下内容
export JAVA_HOME=/usr/local/java/jdk-13
export PATH=$JAVA_HOME/bin:$PATH
## 重新加载配置文件
source /etc/profile

## 检查java版本
java -version

6.安装Maven

下载Maven,并复制到容器中,然后编辑profile文件,安装Maven。

1
2
3
4
5
6
7
## 编辑profile文件
vi /etc/profile
## 添加
export MAVEN_HOME=/usr/local/maven-3.8.1
export PATH=$MAVEN_HOME/bin:$PATH
## 重新加载配置文件
source /etc/profile

5.安装nginx

可以使用yum安装,也可以使用源码安装,我选择了源码安装Nginx安装配置

1
2
3
4
## 安装仓库
yum install epel-release
## 安装nginx
yum install nginx

6.安装redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 安装epel源
yum install epel-release
## 这一步用不用,我觉得都可以
yum update
## 安装redis
yum install redis

## 启动redis
# systemctl start redis

## 编辑配置文件
vi /etc/redis.conf
## 修改daemonize为yes,实现后台启动
daemonize yes
## 启动redis
redis-server /etc/redis.conf
参考文章:
1.centos7安装redis
2.Docker 安装 Redis
3.redis-server 后台运行 修改配置文件,增加 daemonize yes

7.安装nacos

因为我的springboot使用到了springcloud,并且使用了阿里的Nacos作为注册中心,所以需要安装nacos,在官网下载二进制包,然后上传到容器中,进行配置文件的修改后,就可以启动了。当然也可以编写 /lib/systemd/system/nacos.service 文件,使用systemctl进行管理,设置开机启动等。

1
2
3
4
5
6
7
8
9
10
## 上传nacos安装包到容器中
cd /usr/local/nacos/bin
## 修改启动脚本
vi /usr/local/nacos/bin/startup.sh

## 在 [ ! -e "$JAVA_HOME/bin/java" ] && unset JAVA_HOME 脚本后面添加本机的jdk目录
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/java/jdk-13

## 单机启动
sh startup.sh -m standalone

因为nacos运行,会产生大量的日志文件,比如access日志,但是我们又不需要,所以需要关闭。日志排名最多的几个文件:

  • 1.naming-server
  • 2.naming-raft
  • 3.config-memory
  • 4.config-server
  • 5.config-client-request
  • 6.config-trace

(1) 编辑nacos/config/application.properties文件,将accesslog日志关闭

1
server.tomcat.accesslog.enabled=false

(2) 修改nacos/config/nacos-logback.xml文件,把其中的INFO和DEBUG级别,都改为ERROR

1
2
3
4
<logger name="com.alibaba.nacos.cmdb.main" additivity="false">
<level value="INFO"/>
<appender-ref ref="cmdb-main"/>
</logger>

(3) 修改客户端日志级别
这个其实是在使用nacos的客户端进行配置的,也就是在开发的时候的代码中进行配置,根据个人情况进行。

1
2
3
4
5
6
7
logging:
level:
com:
alibaba:
nacos:
client:
naming: error

8.保存对容器的修改

当对容器进行修改之后,如果需要保存容器为镜像,保存为镜像之后,就可以重新进行run命令,运行一个新的容器,而不用丢失原有的修改内容了。

1
2
3
4
5
6
7
8
## -a :提交的镜像作者;
## -c :使用Dockerfile指令来创建镜像;
## -m :提交时的说明文字;
## -p :在commit时,将容器暂停
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

## 将容器a404c6c174a2 保存为新的镜像,并添加提交人信息和说明信息
docker commit -a "bibichuan.com" -m "my apache" a404c6c174a2 mymysql:v1
参考文章:
1.docker保存对容器的修改 docker commit
2.Docker(七) - commit 将容器保存为镜像 docker commit [选项] [容器ID或容器名] [仓库名:标签]
3.Docker commit 命令

9.保存镜像为文件

创建了容器之后,安装了各种的软件和程序,保存为镜像之后,需要拷贝到另外的机器运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## 导出容器,到当前目录
docker export springboot -o springboot.tar

## 导入容器为镜像,import后面的-
docker import .\springboot.tar springboot

## linux下可以使用 < 进行导入
docker import - springboot < springboot.tar
docker export springboot > springboot.tar

## linux导出
docker save [image] > file.tar
## linux导入
docker load < file.tar
## window导出
docker save [image] -o file.tar
## window导入
docker load -i file.tar
参考文章:
1.docker 拷贝镜像文件
2.导出docker镜像tar再次导入后启动报错 简单介绍下docker导出和导入镜像,打包镜像的时候有两种,一是把容器打包成镜像,二则是把镜像打包,这两种打包形式的主要区别在于通过docker save打包镜像可以保存历史记录,而通过docker export则会丢失历史信息。镜像导入命令是需要配对,docker export 和 docker import, docker save 和 docker load。
3.docker保存镜像报错:Cowardly refusing to save to a terminal. Use the -o flag or redirect.
4.导出和导入
5.Docker - 实现本地镜像的导出、导入(export、import、save、load) 两种方案的差别:文件大小不同、是否可以对镜像重命名、是否可以同时将多个镜像打包到一个文件中、是否包含镜像历史、应用场景不同

10.部署微服务

我部署微服务的时候,都是在阿里云上直接部署的,我越是开发微服务,越是觉得非常的不合适,因为微服务包含的东西太多了,每一个应用程序可能都需要一个jar,那么部署的时候就会非常的困难,这个时候怎么办呢?

参考文章:
1.【原创】微服务为什么一定要用docker 你说虚拟机消耗资源多?绝大部分公司的服务器资源利用率应该都不到 50%,大量的CPU、内存、本地磁盘都是常年浪费的,所以 虚拟机 的额外开销不过是浪费了原本就在浪费的资源罢了。所以笔者认为,对于传统应用来说,使用和不使用Docker可能并不能直接给企业带来好处,相反使用中遇到了问题肯定会给企业带来麻烦,对于传统企业来说,不要盲目跟风,VM虚拟机其实够用了!。
2.关于容器、微服务、docker 的十大问题
3.Docker 部署 SpringCloud 微服务(docker-compose 编排微服务高可用案例)
4.十分钟学会用docker部署微服务
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。