众所周知tomcat有三种运行模式:bio、nio、apr模式。这三种模式在理论上是bio性能最差,apr性能最好,但是也有文章表明在相同的环境不同情况并发下apr模式不一定比bio更好,但是这不属于本文讨论内容,至于模式的选择还是要根据自己项目情况来定,本文主要介绍在docker中运行spring boot(内嵌tomcat)时如何开启APR模式。
首先介绍下这三种模式的区别:
BIO模式:tomcat使用传统的Java I/O,是基于JAVA的HTTP/1.1的连接器,性能较差,tomcat 7及以下版本默认采用该模式,比较适用于连接数目小且比较固定的架构
NIO模式:是一个基于缓冲区并能提供非阻塞I/O操作的JAVA API,Java SE 1.4之后出现的,比BIO的并发性能要好,适用于连接数目多并且连接比较短的轻操作架构
APR模式:全称是Apache Portable Runtime/Apace 可移植运行库,是Apache HTTP服务器的支持库。Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,大大的提高了对静态文件的处理性能,是tomcat上运行高并发应用的首选模式,需要在操作系统中安装第三方类库
介绍下项目情况,我们项目采用的是spring boot 1.5.4、内嵌tomcat版本号为8.5.15,通过源码分析我们可以看到在spring boot中tomcat默认采用nio模式
根据上面介绍我们可以看到tomcat在bio和nio模式之间切换比较简单,我们只需更改tomcat connector的连接模式即可。但是要想采用apr模式,不仅要进行connector连接模式的更改,还需要在OS中安装相关类库,包括:apr、apr-util、tomcat-native。在普通系统中安装这些类库网络上都有相关文章介绍,一般不是什么难事。但是我们现在要在docker中去安装这些类库可能就需要大费周章了:一、docker中的系统一般只包含最基本的系统类库和命令,绝大部分都是没有的;二、安装apr相关软件一般都需要进行源码安装,而docker所包含的系统中基本没有gcc等相关类库,要大费周章去装很多东西,且最后基本上很难实现(笔者就跳了好多坑,最后也没有成功安装)。
现在我们来分析下spring boot+docker实现内嵌tomcat apr模式部署的思路:一、保证spring boot可以以apr模式运行于内嵌tomcat;二、docker中能成功安装apr相关组件。有思路了那就开始尝试,我分析了源码并结合了网络资料,在本机中装上apr相关组件(本机安装就不再介绍了),并在spring boot项目中的某Java Config中加入以下配置,启动成功,说明spring boot开启apr模式没问题,继续进行第二步!
我们项目原本采用的docker基础镜像为”java:8”,docker中操作系统为debian。首先考虑采用apt-get install的方式安装,但一直报错“Unable to locate package apr”,从网上找了很多方式都无法解决,估计是缺东西太多。然后我就准备用源码安装,将下载好的安装包拷贝上来(通过数据卷映射宿主机磁盘的方式),但是安装过程中缺包太多,根本就无法进行,只好放弃了。“java:8”镜像不行,那是否可以换个镜像呢?马上使用docker search apr命令进行搜索,只有一个buglife/tomcat-apr比较符合,但也不是要找的,因为我要采用内嵌的方式,在镜像中多一个外部tomcat也是累赘(从精简镜像用途考虑)。这些方式都行不通,那么是否可以找一个最精简的系统来自己安装呢?debian不行,我不喜欢它,我们服务器一般都采用centos,那就使用centos吧。找了一下,决定采用“centos:7.2.1511”。将镜像pull下来,通过docker run -it centos:7.2.1511命令进去看一下是否符合要求。进去之后首先使用yum、vi等命令试了下发现都可以用,那就它了!
选择好镜像之后,通过docker的交互式模式进入镜像进行安装尝试。首先使用yum upgrade进行版本的升级,然后试着以yum的模式安装apr、apr-util、apr-devel都没问题,那就只剩tomcat-native了,也采用yum命令安装发现没有相关类库。那我继续采用源码安装吧,没有gcc,又走到了要安装gcc的老路了,要崩溃了!这时我忽然想到默认的yum源中没有tomcat-native,其他源有可能提供啊,于是就去百度常用的yum源,找到了一个阿里的源。于是更改/etc/yum.conf源文件,然后再去yum install tomcat-native就可以顺利安装了!
环境安装好了,但是工程可以运行吗?我把打包好的工程拷贝进来进行启动,OK,一切正常!那就可以编写Dockerfile文件了。
将Dockerfile和重新编写好的yum.conf文件放在同一个空的文件夹下,执行docker build -t [镜像名:版本号] . 命令打成一个新的镜像,然后推到远程镜像库(我们采用阿里的镜像库),在原镜像文件中以此镜像做为基础镜像文件即可。部署到服务器,运行完全没问题!如需了解采用阿里云+docker来部署spring cloud,请阅读我的另一篇文章《Spring Cloud与Docker的完美结合,运维可以不用拜菩萨啦》
如需获取更多精彩内容或者技术探讨,请扫码关注本人公众号!爱生活,爱代码,代码也是码,我是爱码三疯!