Docker快速验证tomcat单机多实例方案

[TOC]

概述

主要讲的是解决问题的思路。当然也附带了尽可能详细的步骤,感兴趣的童鞋可以一步一步跟着来实践一把。因为运维职业的缘故,基本上是把事故当故事来写了,希望能够喜欢。

缘起

至少10年了,没在一线玩过Tomcat了,这次客户现场就来了一场遭遇战。虽然客户说了他来搭建,但是项目进度不等人,还是自己动手吧。当然了,新服务器是要走流程申请的,只能在现有服务器想办法。犹记得当年解决Tomcat部署这些都是小菜,没想到在苛刻的商业环境中,处处是坑,步步有雷。不过,咱干过开发也干过运维,这点儿动手的事情,还不至于发邮件请救兵不是。干!

服务器在内网,有瘦终端可以访问。MacBook只能访问外网,一边查资料,一边比对着在内网做,效果不好,老是担心现有环境给整趴了:开发测试那边就没得玩了。干过开发的都知道,服务器从来都是直接上root账号。干过运维的人都知道,永远别碰root。╮(╯▽╰)╭哎,职业病,还是小心谨慎地好。

只能调整了方法:先在MacBook上搭建单机多实例,验证通过之后,再去内网服务器动手。本来计划20~30分钟搞完的事,最终花了小半天时间验证了方案,在内网实施的时候,又遇到苛刻的环境限制,逐步排雷,最终搞定。客户满意,项目进度开心。

思路

根据实际环境,判断问题解决方向:单机多实例;放弃内网危险的尝试:不能快速有效解决,且账号权限太大;选择外网验证方案后再进内网实施。很多时候,选择大于努力。

我们先简化问题

写个验证文件打包成war包。为啥不使用现有代码。一是因为现有war包在内网,二是因为太复杂,除了问题不能排除是代码自身的问题还是我们的部署方式有问题,或者是内外网网络环境的问题,亦或是RPWT。

对于验证方案,排查问题时,尽量简化,抛却一切外在的东西,只验证核心。方案验证通过,再引入实际war包验证。这和面向对象编程的指导思想是一致的:通过抽象来提炼最核心的东西,每次聚焦一个地方,不要全面出击。人,毕竟精力有限。

至于为什么用tomcat7,没什么,客户这儿只允许这个版本。

先放出整理后方案

2017.8.8Update:

已commit到docker hub,心急的童鞋自行

docker pull aninputforce/tomcat7-ins

最终方案

这个不是诊断问题的思路,是最终解决完问题后的,对整体方案的梳理,这样的顺序才整洁,有基础时间紧的童鞋直接看这个就足够了。有时间的童鞋可以看看正文,贯穿了分析问题解决问题的思路。

# 简化问题:建模先--宿主机编辑 -> jdk7打war包 -> tomcat默认配置 -> 单机单实例 -> 单机双实例

├── # docker搭建jdk7初始环境:用来打包验证用的war包

│ ├── docker search jdk7

│ ├── docker pull codenvy/jdk7

│ ├── docker run --name jjj codenvy/jdk7 /bin/bash

│ ├── java -version && mkdir ~/web && ls ~/ && exit # 镜像容器环境工作正常,创建工作目录,退出

│ ├── mkdir ~/prms001 ~/prms002 # 宿主机

│ ├── # 编辑prms001/index.htm,编辑prms002/index.htm

│ ├── docker cp prms001 jjj:/home/user/web && docker cp prms002 jjj:/home/user/web

│ ├── docker exec -it jjj /bin/bash # 进入容器

│ ├── sudo chown -R user:user prms001 prms002 改变属组

│ ├── cd ~/web/prms001 && jar -cvf prms001.war ./* && ls -la

│ ├── cd ~/web/prms002 && jar -cvf prms002.war ./* && ls -la && exit

│ ├── docker cp jjj:/home/user/web/prms001/prms001.war ~/.

│ ├── docker cp jjj:/home/user/web/prms002/prms002.war ~/.

│ └── docker rm jjj # 退出容器,jdk7容器使命结束

├── # docker搭建tomcat7初始环境:用来推演单机多实例

│ ├── # docker拉取tomcat7镜像

│ ├── # 启动名为www的tomcat容器

│ │ ├── ./startup.sh # 启动web服务

│ │ ├── curl localhost:8080 # 访问正常

│ │ ├── ./shutdown.sh # 停止web服务

│ │ └── # 搭建第一个实例

│ │ ├── mkdir tom-ins001

│ │ ├── mv work tom-ins001/ && mv conf/ tom-ins001/ mv logs/ tom-ins001/

│ │ ├── mv temp/ tom-ins001/ && mv webapps/ tom-ins001/

│ │ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/

│ │ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

│ │ ├── curl localhost:8080 # 访问正常

│ │ └── exit && docker commit www mytomcat:latest && docker rm www # 容器www使命结束

│ └── docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash # 启动新容器

│ ├── # 启动第一个实例

│ │ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/

│ │ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

│ │ └── curl localhost:8080 # 访问正常

│ └── # 搭建并启动第二个实例

│ ├── cp -r tom-ins001/ tom-ins002

│ ├── # 编辑tom-ins002/conf/server.xml的3个端口,规避和实例1冲突,

│ │ ├── Server port="8001"、 Connector port="80" protocol="HTTP/1.1"

│ │ ├── Connector port="8002" protocol="AJP/1.3"

│ │ ├── docker cp www:/usr/local/tomcat/conf/server.xml .

│ │ ├── vi server.xml

│ │ └── docker cp ./server.xml www:/usr/local/tomcat/conf/

│ └── # 启动新容器 启动实例2

│ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins002/

│ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

│ ├── curl localhost:80 # 访问正常

│ ├── exit && docker commit web mytomcat:latest

│ └── docker rm web # 容器web使命结束

└── # 展示单机双实例:

├── # 配置实例2根目录运行

│ ├── docker run --name web -d -it -p 8080:8080 -p 80:80 mytomcat /bin/bash # 启动新容器

│ ├── docker exec -it web /bin/bash

│ ├── cd /usr/local/tomcat/tom-ins002/webapps && tar cvf rootbak.tar ./ROOT/*

│ ├── cd ROOT && rm -rf * # 清空ROOT目录

│ ├── mkdir /usr/local/tomcat/myapps && exit # 创建实例2war包存放目录,退出容器

├── # 部署实例1、实例2的war包,启动验证

│ ├── # 编辑ROOT.xml,配置实例2的war包解到 /usr/local/tomcat/tom-ins002/ROOT 目录

│ ├── docker cp ~/ROOT.xml web:/usr/local/tomcat/tom-ins002/conf/Catalina/localhost

│ ├── docker cp ~/prms002.war web:/usr/local/tomcat/myapps

│ └── docker cp ~/prms001.war web:/usr/local/tomcat/tom-ins001/webapps

├── docker exec -it web /bin/bash

│ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins001/

│ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

│ ├── curl localhost:8080 # 访问正常:Hello from Tomcat instance 001

│ ├── export CATALINA_BASE=$CATALINA_HOME/tom-ins002/

│ ├── sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

│ └── curl localhost # 访问正常:Hello from Tomcat instance 002

└── # 宿主机验证

├── curl localhost:8080 # 访问正常:Hello from Tomcat instance 001

├── curl localhost # 访问正常:Hello from Tomcat instance 002

└── exit && docker commit web mytomcat:latest # 退出,提交容器变动到镜像,验证通过;

以下开始讲故事:

外网验证方案

换做十年前,要学习Java,光搭建个环境,就能耗尽新人90%的热情。放弃内网尝试,转由外网先验证方案,我也是经过略微的思想斗争的,不过转念一想,有Docker神器,也就淡定了。

开始之前,先列一下客户的要求

部署新实例作为UAT测试环境,但是新服务器还没有

根目录啊,别带上Project路径了

端口用80吧,你们开发测试还用8080

需求分析

在内网的一番碰墙,也不是没有一点儿成果,至少理顺了方向:

方案的方向是单机多实例

Server部署在根目录

别让用户敲端口访问了

开始,进行tomcat单机多实例方案的推演。

至于docker环境搭建,请参考官方文档。我的另一篇笔记里附有链接:Docker的第一次亲密接触

上Docker搭建第一个实例

准备拉取镜像

docker pull tomcat:7.0

启动并运行tomcat

容器名www,端口8080:

ChinaDreams:work-diary kangcunhua$ docker run --name www -it -p 8080:8080 tomcat:7.0 /bin/bash

root@4b8f58d2cd64:/usr/local/tomcat# cd bin

root@4b8f58d2cd64:/usr/local/tomcat/bin# java -version

java version "1.7.0_131"

OpenJDK Runtime Environment (IcedTea 2.6.9) (7u131-2.6.9-2~deb8u1)

OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)

root@4b8f58d2cd64:/usr/local/tomcat/bin# ./startup.sh

root@4b8f58d2cd64:/usr/local/tomcat/bin# ps -ef | grep java

root@4b8f58d2cd64:/usr/local/tomcat/logs# tail -f catalina.out

root@4b8f58d2cd64:/usr/local/tomcat/logs# curl localhost:8080

搭建第一个实例

root@4b8f58d2cd64:/usr/local/tomcat# mkdir tom-ins001

root@4b8f58d2cd64:/usr/local/tomcat# ls

LICENSE RELEASE-NOTES bin include logs native-jni-lib tom-ins001 work

NOTICE RUNNING.txt conf lib myapps temp webapps

root@4b8f58d2cd64:/usr/local/tomcat# mv work tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat# mv conf/ tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat# mv logs/ tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat# mv temp/ tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat# mv webapps/ tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat# ls

LICENSE NOTICE RELEASE-NOTES RUNNING.txt bin include lib myapps native-jni-lib tom-ins001

root@4b8f58d2cd64:/usr/local/tomcat# cd tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# ls

conf logs temp webapps work

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# echo $CATALINA_HOME

/usr/local/tomcat

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# export CATALINA_BASE=$CATALINA_HOME/tom-ins001/

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# ps -ef | grep java

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# tail -f catalina.out

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# curl localhost:8080

提交变动到镜像备份

root@4b8f58d2cd64:/usr/local/tomcat/tom-ins001# exit

ChinaDreams:~ kangcunhua$ docker commit www mytomcat:latest

搭建第二个实例

启动新容器,并启动第一个实例

基于刚提交生成的镜像,新启一个容器。启动实例1,验证正常

ChinaDreams:~ kangcunhua$ docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash

root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# export CATALINA_BASE=$CATALINA_HOME/tom-ins001

root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# ps -ef | grep java

root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# tail -f catalina.out

root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# curl localhost:8080

生成第二个实例目录

root@c8cc5f309d18:/usr/local/tomcat# cp -r tom-ins001/ tom-ins002

root@c8cc5f309d18:/usr/local/tomcat# ls

LICENSE NOTICE RELEASE-NOTES RUNNING.txt bin include lib myapps native-jni-lib tom-ins001 tom-ins002

root@c8cc5f309d18:/usr/local/tomcat# cd tom-ins002

root@c8cc5f309d18:/usr/local/tomcat/tom-ins002# ls

conf logs temp webapps work

root@c8cc5f309d18:/usr/local/tomcat/tom-ins002# cd ..

root@c8cc5f309d18:/usr/local/tomcat# cd tom-ins001/

root@c8cc5f309d18:/usr/local/tomcat/tom-ins001# ls

conf logs temp webapps work

编辑server.xml

主要是修改三处端口,避免和实例1端口冲突。

Server port="8001"

Connector port="80" protocol="HTTP/1.1"

Connector port="8002" protocol="AJP/1.3"

connectionTimeout="20000"

redirectPort="8443" />

编辑ROOT.xml

作用是指定一个不在webapps目录的war包,部署时自动解压到webapps\ROOT目录。

cp到tomcat容器web中查看

ChinaDreams:~ kangcunhua$ docker cp ~/ROOT.xml www:/usr/local/tomcat/tom-ins002/conf/Catalina/localhost

ChinaDreams:~ kangcunhua$ docker exec -it www /bin/bash

root@4b8f58d2cd64:/usr/local/tomcat# cd conf/Catalina/localhost/

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# ls

ROOT.xml

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# more ROOT.xml

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# pwd

/usr/local/tomcat/conf/Catalina/localhost

文件属主不对,改

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# ls -al

total 12

drwxr-xr-x 2 root root 4096 Jul 31 05:58 .

drwxr-xr-x 3 root root 4096 Jul 31 04:23 ..

-rw-r--r-- 1 502 dialout 111 Jul 31 05:56 ROOT.xml

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# chown root:root ROOT.xml

root@4b8f58d2cd64:/usr/local/tomcat/conf/Catalina/localhost# ls -la

total 12

drwxr-xr-x 2 root root 4096 Jul 31 05:58 .

drwxr-xr-x 3 root root 4096 Jul 31 04:23 ..

-rw-r--r-- 1 root root 111 Jul 31 05:56 ROOT.xml

打个war部署包

打war包报错

在tomcat容器中,发现jar命令找不到。

root@4b8f58d2cd64:/usr/local/tomcat/webapps/examples# jar -cvf prms.war ./*

bash: jar: command not found

构建jdk7环境

本地没有java环境。果断上docker构建一个

ChinaDreams:~ kangcunhua$ docker search jdk7

ChinaDreams:~ kangcunhua$ docker pull codenvy/jdk7

ChinaDreams:~ kangcunhua$ docker run --name jjj -it codenvy/jdk7 /bin/bash

user@b040d98042c0:/$ java -version

user@b040d98042c0:/$ jar

user@b040d98042c0:/$ mkdir ~/web && ls ~/ && exit 创建工作目录,退出

宿主机编辑代码cp到容器中打jar包

ChinaDreams:~ kangcunhua$ mkdir ~/prms001 ~/prms002

ChinaDreams:~ kangcunhua$ vi ~/prms001/index.html

ChinaDreams:~ kangcunhua$ vi ~/prms002/index.html

ChinaDreams:~ kangcunhua$ docker cp prms001 jjj:/home/user/web && docker cp prms002 jjj:/home/user/web

ChinaDreams:~ kangcunhua$ docker exec -it jjj /bin/bash 进入容器

user@b040d98042c0:~/web$ sudo chown -R user:user prms001 prms002 改变属组

user@b040d98042c0:~/web$ cd ~/web/prms001 && jar -cvf prms001.war ./* && ls -la

user@b040d98042c0:~/web$ cd ~/web/prms002 && jar -cvf prms002.war ./* && ls -la && exit

ChinaDreams:~ kangcunhua$ docker cp jjj:/home/user/web/prms001/prms001.war ~/.

ChinaDreams:~ kangcunhua$ docker cp jjj:/home/user/web/prms001/prms002.war ~/.

ChinaDreams:~ kangcunhua$ docker rm jjj 退出容器,jdk7容器使命结束

vi ~/prms001/index.html

Tomcat instance 1

Hello from Tomcat instance 1

vi ~/prms002/index.html

Tomcat instance 2

Hello from Tomcat instance 2

启动实例1、实例2

回到tomcat容器

root@c8cc5f309d18:/usr/local/tomcat# export CATALINA_BASE=$CATALINA_HOME/tom-ins001

root@c8cc5f309d18:/usr/local/tomcat# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

root@c8cc5f309d18:/usr/local/tomcat# curl localhost:8080 访问正常

root@c8cc5f309d18:/usr/local/tomcat# export CATALINA_BASE=$CATALINA_HOME/tom-ins002/

root@c8cc5f309d18:/usr/local/tomcat# sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

root@c8cc5f309d18:/usr/local/tomcat# curl localhost:80 访问正常

激动人心的时刻

提交镜像和删除旧容器web

docker commit web mytomcat:latest && docker rm web

基于最新镜像,启动新容器命名为web

docker run --name web -it -p 8080:8080 -p 80:80 mytomcat /bin/bash

宿主机访问

http://localhost 访问正常:Hello from Tomcat instance 001.

http://localhost:8080 访问正常:Hello from Tomcat instance 002.

单机多实例方案本地通过

方案补充

启动命令

export CATALINA_BASE=$CATALINA_HOME/tom-ins001 && sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

export CATALINA_BASE=$CATALINA_HOME/tom-ins002 && sh $CATALINA_HOME/bin/startup.sh -Dcatalina.base

停止命令

export CATALINA_BASE=$CATALINA_HOME/tom-ins001 && sh $CATALINA_HOME/bin/shutdown.sh -Dcatalina.base

export CATALINA_BASE=$CATALINA_HOME/tom-ins002 && sh $CATALINA_HOME/bin/shutdown.sh -Dcatalina.base

排错命令

ps -ef | grep java

kill -9 xxx tomcat实例进程号

tail -f $CATALINA_HOME/tom-ins001/logs/catalina.out

tail -f $CATALINA_HOME/tom-ins002/logs/catalina.out

curl localhost:8080/prms001/

curl localhost

目录结构参考

保留了最关键的要素:

.

├── bin

├── lib

├── myapps

│   └── prms002.war

├── tom-ins001

│   ├── conf

│   │   └── server.xml

│   ├── logs

│   │   └── catalina.out

│   ├── webapps

│   │   ├── prms001

│   │   └── prms001.war

│   └── work

└── tom-ins002

├── conf

│   ├── Catalina

│   │   └── localhost

│   │   └── ROOT.xml

│   └── server.xml

├── logs

├── temp

├── webapps

│   └── ROOT

│      ├── META-INF

│      │   └── MANIFEST.MF

│      └── index.htm

└── work

提交到docker hub

update:2017.8.8

ChinaDreams:work-diary kangcunhua$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

mytomcat latest 3f6c6cce5355 7 days ago 370MB

ChinaDreams:work-diary kangcunhua$ docker tag 3f6c6cce5355 aninputforce/tomcat7-ins:latest

ChinaDreams:work-diary kangcunhua$ docker push aninputforce/tomcat7-ins

ChinaDreams:work-diary kangcunhua$ docker push aninputforce/tomcat7-ins:1.0

ChinaDreams:work-diary kangcunhua$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

mytomcat latest 3f6c6cce5355 7 days ago 370MB

aninputforce/tomcat7-ins 1.0 3f6c6cce5355 7 days ago 370MB

aninputforce/tomcat7-ins latest 3f6c6cce5355 7 days ago 370MB

进内网玩:残酷的商业环境

一切都很顺利,直到碰上访问80端口。。。。

顺利

搭建实例1

备份后,搭建实例1,确保原始应用能正常;

搭建实例2

停止实例1,保证实例2默认也能运行;

根目录部署实例2

编辑server.xml,ROOT.xml,清空ROOT目录,新建myapps目录,拷贝war包进去;

curl http://localhost web server上访问正常。

坑:Suse访问80端口

实例2需要使用80端口。受阻。

坑+:没有任何限制。我们需要客户的信息,但是不能全信。就像这次请教客户说的“我们对端口没有任何限制”。不要盲目相信客户说的,要相信科学排查。

依稀记得架构师课程PC大神讲过,linux默认只有root用户才能访问80端口。当时我一直有个疑问,那我们web server需要用到80端口是怎么解决的?我记得请教过PC老师,可惜当时课程紧,虽然听的云里雾里的,也没好意思多追问,更没线下自己实践。直到这次在客户现场栽了跟头。

开发测试环境,我们倒是有root账号,但是我们web server总不能用root部署吧,太不专业了。在Reboot校友群中厚着脸皮请教了各位童鞋,很快get了解决方案:将所有80端口的访问,转发到8081即可;8081就是我们可以配置的tomcat实例2的访问端口,这个是普通用户有权限的。

修订IPtables策略,转发80端口请求

刚检查防火墙时,看到80端口是放开的。部署机上可以访问,局域网打不开:将所有针对80端口的访问,转发到8081。

[root@tomcat7conf]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8081

使用8081端口

修改了tomins-002的server.xml,仍是部署机上可以访问,局域网打不开;

检查防火墙

配置上8081端口,重启防火墙生效,部署机访问正常,局域网打开正常

找到FW_SERVICES_EXT_TCP,加上8081端口

[root@tomcat7conf]# vi /etc/sysconfig/SuSEfirewall2

[root@tomcat7conf]# rcSuSEfirewall2 restart

切换到tomcat用户,重启tomcat,局域网访问正常。

坑:成熟平台也有硬编码

发现系统首页这个链接,虽然配置的是"#",但是一点击就回到project的路径。经查找文件,发现是在开发平台的两个js文件中,写了硬编码。应该是平台自动生成代码时用了硬编码,改之。

坑:成熟产品也不是没有Bug

发现只要是配置了根目录访问,统一认证就报错。去掉统一认证接入就能正常访问。反馈给客户,协调解决;

悬了两天,未能有任何反馈,追着逼急了,唯一答案就是:成熟产品,我们不要先去怀疑统一认证平台。

我这个暴脾气,马上和工程师排查。单步跟一下,发现是提交到统一认证时,我们要传过去一个参数ssotarget,这个ssotarget是通过认证后,浏览器要打开的首页,context-path不为空时,url正常,context-path为null,即我们部署到根目录时,ssotarget只能得到个"/"。检查统一认证接入逻辑,发现是使用了平台提供的filter,反编译,单步跟踪,发现ssotarget来自homepage的赋值。捏着鼻子看源码,果然代码逻辑有问题,伪算法如下:

String ccontext_path=request.getContextPath(); // 得到web 服务上下文

String urlt = requerst.getRequestURL(); // 得到请求的完整网址

String cwebhost = urlt.substring(0, urlt.IndexOf (context-path)); // 得到http://hostname:端口

homepage = webhost + context_path + "/"; // 拼出web server的应用首页地址

改之

String context_path = request.getContextPath();

String homepage = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

尝试,自己改了源码之后重新打jar包,commit svn,jenkins编译部署后发现没起作用。想起来使用的是maven,所有jar包都来自平台的私有仓库,这。。。

换种思路,写个java类继承一下,结果一看对应逻辑所在function,private的,往上再看class,finall的,一万只神兽啊!!!

要啥面向对象,简单粗暴,源码照抄,修订了后命名为MySsoFilter.java,在工程配置文件替换上我们写的filter,svn commit,jenkins立即构建部署,世间从此安静。

参考和感谢

参考清单

感谢

感谢项目组的小伙伴们,辛苦努力排查缺陷,撰写了新的filter;

感谢Reboot的同学群,关键时刻,是请教你们给指出了方向;

感谢Reboot的架构师课程和运维自动化课程,前者使我开阔了眼界,后者让我收获了docker神器

docker tomcat 多开 实例_Docker快速验证tomcat单机多实例方案相关推荐

  1. Docker快速验证tomcat单机多实例方案

    为什么80%的码农都做不了架构师?>>>    Docker快速验证tomcat单机多实例方案 [TOC] 概述 主要讲的是解决问题的思路.当然也附带了尽可能详细的步骤,感兴趣的童鞋 ...

  2. Docker 快速验证 HTML 导出 PDF 高效方案

    需求分析 项目中用到了 Echarts,想要把图文混排,当然包括 echarts 生成的 Canvas 图也导出 PDF. 设计和实现时,分析了 POI.iText.freemaker.world 的 ...

  3. docker镜像指定安装源_Docker快速安装以及换镜像源

    不得不说 docker的火爆程度已经达到的地步, 由于国外docker搭建太慢,国外的安装文档也很全面,这里就不在详述,详情可以点击这里: 正主:Docker 官方镜像加速:http://www.do ...

  4. 3个快速验证产品想法的实例

    这3个案例来自<The 7 Day Startup>这本书,我之前分享了这本书的精炼内容要点:<The 7 Day Startup>7天构建一个赚钱产品,其中我觉得3个案例非常 ...

  5. 怎么看tomcat连接的哪个mysql_如何验证tomcat和mysql连接成功呢

    匿名用户 1级 2009-01-09 回答 Java WEB编程tomcat验证连接数据库mysql测试: 1.将mysql的jdbc驱动程序放到tomcat的lib中:mysql_connect_j ...

  6. mac 启动mysql多实例_实践:mysql单机多实例部署(mac)

    背景:在自己电脑搭建或测试分布式服务框架时,经常会用多个数据库实例模拟多个环境的情况,因此我把搭建多实例mysql的过程记录下来,方便互相学习和沟通. 1.搭建环境 1) mac 电脑,版本 10.1 ...

  7. mysql5.7单机多实例_Mysql 5.7.21单机多实例安装

    下载MySQL 5.7 二制包 [root@MySQL ~]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.21-linu ...

  8. mysql多实例主从_window 下 mysql 单机多实例以及主从同步

    主MySQL my.ini 配置 # mysql server 的唯一id server_id = 3306 log-bin=log # 需要同步的数据库 binlog-do-db=faner # 不 ...

  9. RabbitMQ集群(单机多实例部署)

    RabbitMQ集群(单机多实例部署) 一.单机多实例部署 单机版安装地址:RabbitMQ3.8.4安装和配置 在单机版基础上 ,也就是一台Linux虚拟机上启动多个RabbitMQ实例,部署集群. ...

  10. docker tomcat 多开 实例_Docker zabbix-agent 监控 docker tomcat 多实例

    目录 监控方案概述 我们使用 zabbix-agent 的方式来监控 多个 tomcat 8.5.51 ,由于我们需要监控的是 Docker 容器里的 Tomcat ,而 zabbix 官方模板并不支 ...

最新文章

  1. 100w个整数中,每个数各不相同,且都小于100w,问如何快速的排序
  2. Siri:开启智能语音营销时代
  3. MySQL数据库基础(三)数据的导入导出、管理表记录、匹配条件
  4. 如何用socket构建一个简单的Web Server
  5. pomelo中的next
  6. Linux运维系统工程师与java基础学习系列-6
  7. emui与华为鸿蒙关系,华为王成录谈鸿蒙和EMUI的关系
  8. 盗贼之海3月22服务器维护,盗贼之海3月29日更新公告_3月29日更新了什么_52pk单机游戏...
  9. C语言多项式乘法模拟,急!!!!c语言:求n次多项式的加法和乘法
  10. 重构现有代码:Refactoring
  11. ES6新特性_Promise封装Ajax请求---JavaScript_ECMAScript_ES6-ES11新特性工作笔记026
  12. SpringBoot之idea快捷键
  13. 捷宇高拍仪XY530 网页集成总结
  14. 贪心宝贝话说上回讲到海东集团面临内外交困,公司的元老也只剩下XHD夫妇二人了。显然,作为多年拼搏的商人,XHD不会坐以待毙的。 一天,当他正在苦思冥想解困良策的时候,突然想到了自己的传家宝,那是公司成
  15. Unity LOD-Level of Detail(多层次细节)用法教程
  16. 小米air2se耳机只有一边有声音怎么办_几款两百元以内的耳机使用体验
  17. 2020滑铁卢大学计算机科学学费,官宣!2020加拿大高校学费与涨幅~
  18. 洛谷 P3939 数颜色(主席树)
  19. 想想也有五年多了(胡紫薇博客)
  20. RAID卡及其管理工具

热门文章

  1. 美国的人民币汇率谋略
  2. Cts框架解析(19)-设备状态的分类以及恢复模式的分类
  3. Cesium 多边形(polygon)extrudedHeight 和 height 的区别
  4. ubuntu中用gimp 将psd文件分解
  5. hdu 5455 Fang Fang
  6. 软件测试p1是什么级别,软件测试工程师岗位等级-20210729101938.doc-原创力文档
  7. Axure 下载教程
  8. mysql联合索引原理
  9. 分享200个App移动端模板
  10. android 图片 灰色,Android实现制作灰色图片