《Docker+SpringBoot+Mybatis+thymeleaf 的 Java 博客系统开源啦》
《Java 开源博客 My-Blog 之 docker 容器组件化修改》
My Blog 项目已经开源了两个多月,也收获了不少 star,在这里谢谢各位朋友的建议及帮助。由于个人原因,这个开源项目最初的定位其实是一个 docker 技术与 springboot 框架整合的 Java 博客系统实战项目,而且是一个容器技术的练手项目,技术的偏重也更多的在容器技术及容器编排上。
虽然上个版本做了一些改动,将 docker 踢出主目录,原因也是为了照顾其他关注和想要使用 My Blog 的朋友能够很快的上手项目,但是 docker 容器技术依然是这个项目不可缺少的一部分,从项目创建那一刻即是如此,今后也是如此,只不过为了项目更友好而做了一些改动使其不会强耦合于项目中。
从项目开源至今,大大小小的问题已经发现且解决了不少,但是直到近期才完全修复掉的一个大问题就是 mysql 容器重复初始化导致原数据被抹去的 bug。
熟悉这个项目的朋友应该知道,项目初期为了让 mysql 容器可以自动初始化数据花了多少精力,但是这个一直让我觉得很完美的改动却有一个非常致命的缺陷,一旦数据容器 mysql 挂掉了或者需要重启,原先的数据就都没了,即使只是重启也会抹去原先的数据,这个就很尴尬了,我原以为最坚硬的盔甲却成了最柔弱的软肋,这件事真的让我低迷了很久。
一开始并没有发现这个问题,而是在项目运行一段时间之后,某一天由于服务器资源问题 (服务器配置差) 需要重启,进而导致 myblog 容器和 mysql 容器也得重启,但是在重启后发现原来添加的博客数据及留言数据消失了!
取而代之的是 schema.sql 中的几条初始化数据,当时也认真确认是否存在错误操作导致了数据被清空,结果就是一切流程都正常,过程中并没有误操,这个问题也只有在重启时会出现,这是流程设计的问题而且是一个十分致命的问题,如果不解决,将是这个项目最大的一个污点。
- FROM mysql: 5.7 ENV MYSQL_DATABASE test ENV MYSQL_ALLOW_EMPTY_PASSWORD yes COPY setup.sh / mysql / setup.sh COPY schema.sql / mysql / schema.sql COPY privileges.sql / mysql / privileges.sql
- #设置容器启动时执行的命令CMD["bash", "/mysql/setup.sh"]
以上为 mysql 容器的 Dockerfile 文件,文件中定义了容器的启动语句是执行 setup.sh 脚本文件,即 mysql 容器每次启动都会执行 setup.sh,包括第一次启动及此后的重启,而每次执行 setup.sh 都会重新初始化数据,这里的数据初始化包括什么呢?查看 docker-extension/mysql 目录下的文件可知,此过程会删除原来的数据库,重新插入初始化数据库中的数据及数据库的用户权限,再次目瞪狗呆。
一开始并没有意识到严重性,因此也并没有投入特别多的精力在这个问题上,而是把重点更多的放在其他 bug 的修复上,但是随着自己博客数据的增多,及使用此项目的朋友渐渐增多,有一天我忽然有种重压在心头的感觉,对于技术人员来说,web 应用发生数据丢失这种事情实在是一件头痛的事,有过这种经历的人都会抗拒类似事件的出现,试想一下,运行良好的网站由于重启,导致数据全部丢失了,这种事情谁受得了,而且还是用了 My Blog 项目,是可忍孰不可忍!
虽然知道严重性,也无法容忍这个 bug 继续存在于项目中,但是却一直找不到合适的解决办法,容器启动过程中,能够修改的也就是 shell 语句了,而原来的语句是直接执行,并没有判断是否已经存在 tale 数据库,因此会导致覆盖问题,新的 setup.sh 文件中一定要解决数据库是否存在的判断问题。
一开始是根本没思路,通过一点点的动手实践,整个思路也渐渐清晰,通过 shell 脚本执行 mysql 命令,并根据得到的输出判断是否已经存在项目数据库,如果已经存在,就不再进行初始化,而是不进行任何操作即可,如果不存在,即第一次启动 mysql 容器,则进行数据初始化操作。
主要问题有:
虽然现在很简单的就将问题整理出来,但是在实际操作过程中却是困难重重,上面所罗列的任何一个问题处理不掉,修复工作都无法继续进行,经过一次又一次的调试失败,最终找到了能够执行且可以用来判断数据库的 sql 语句,终于解决掉了这个 bug,卡着进度最久的就是这个步骤,在 shell 脚本中始终无法处理 mysql 服务器返回的信息,接下去的判断逻辑根本无法执行。
如图,在执行'mysql> use tale;'sql 命令时,每次都有此错误返回,虽然是预想中的返回,如果针对此错误返回值即可正确的判断是否已存在 tale 数据库,但是 shell 在执行到此语句时,收到此错误信息就直接退出进程了,因此根本无法继续进行。
针对 shell 操作字符串的一些问题,也单独整理了两篇笔记,可以在我的博客目录中看到,这里就不在贴链接了。
虽然只有这么一个段落,但是前前后后有两周的时间都在考虑及实践如何修复这个问题,setup.sh 文件也如上图中 local history 一样,一次又一次的修改。问题终于解决了,该如何形容心情呢?暴露出的最大弱点修复了,皆大欢喜,如释重负,活在梦里...
新版本的 mysql 容器:
第一次启动的日志输出
重启时的日志输出
如图所示,最终得到了想要的结果,重启时可以正确的判断容器中的 mysql 服务器中是否已经存在 tale 数据库,如果已经存在则不再重新初始化数据,修复了这个较为严重的 bug。
问题修复之后,紧接着也就更新了阿里云容器仓库中的镜像,因为原镜像的版本较低依然存在此问题。
- #标记本地镜像,将其归入阿里云镜像仓库docker tag dockerextension_mysql registry.cn - hangzhou.aliyuncs.com / 13 / myblog: mysql
- #登录阿里云容器仓库docker login...
- #上传镜像至容器仓库docker push registry.cn - hangzhou.aliyuncs.com / 13 / myblog: mysql
上传成功,最新版的 mysql 镜像已经不存在那个严重的 bug 了。
永远不要把你今天可以做的事留到明天做。拖延是偷光阴的贼。抓住他吧!
有问题,还是要解决的,不管你想着拖多久,该解决的还是要去解决。
这是一篇 bug 修复的复盘文章,也是一篇工作笔记,如果是第一次了解该项目,相信你即使看完后也是一脸懵逼,这是十分正常的,如果你想继续了解该项目可以查看整个系列文章 Java 开源博客 My-Blog(SpringBoot+Docker) 系列文章, 也可以到我的 GitHub 仓库或者开源中国代码仓库中查看源码及详细的部署过程和使用文档。
首发于我的私人博客, 编辑于 2017 年 7 月 25 日凌晨 00:46。
来源: http://www.cnblogs.com/han-1034683568/p/7231895.html