如何远程部署应用到Tomcat

前几天有人在群里提了个问题:

怎么样通过程序向Tomcat内部署应用?

工作比较忙,也没细问具体的使用场景,提供了一种使用JMX接口的思路。后来提问者说不太了解JMX,网上搜了一些看了看,比较蒙。

本次不打算详细描述JMX怎么使用,而是梳理下可供Tomcat远程部署应用的几种方式,方便有类似需求的朋友。

说到应用部署,熟悉Tomcat的都知道,他默认包含了一个manager应用,功能不少,其中就包含应用部署,不论是目录部署,还是文件部署。

一开始写公众号的时候介绍过一点manager应用:深入Tomcat的Manager

这里注意对于manager应用的使用,默认做了访问限制,只能在本机访问,所以如果你想远程使用manager部署应用到目标服务器,需要在content.xml中做修改,可以参考前面的一篇旧文:为什么你的Manager登录不成功?

配置之后就和本地使用manager一样,部署功能直接使用即可,不再赘述。这里我们来说下使用接口的形式远程部署。

在manager应用内,我们页面上看到的,一般称为HTML接口,还有一个text接口,可以根据在URL中指定的command和参数,执行相应的动作。

格式类似这样:

http://{host}:{port}/manager/text/{command}?{parameters}

host和port换成你的目标主机和端口,command代表你执行的操作,parameter是命令对应需要的参数。

支持的命令很多,如下图是managerServlet里部分代码截图

当然这里面没截取我们要说的deploy命令,这个命令我们单独说一下。对应我们前面说的要部署应用,在url类似这样:

http://localhost:8080/manager/text/deploy?path=/hello&war=d:/abc.war

这里指定应用在磁盘上存放路径,以及应用名称,即可进行应用部署。

部署结果类似这样:

OK - Deployed application at context path /hello

这里也支持应用的多版本部署,只需要在参数中增加version即可。

我们通过源码来看下,这种部署形式背后是如何实现的。

我们来看红框标注的三个地方,是整个部署逻辑的重点。

  1. 首先将应用添加到service内,代表已注册的服务。后面再部署的时候都会先检查,不在此列表内的才被允许。

  2. 将远程的应用包拷贝到本地目录内。

  3. 触发部署的逻辑,真正进行部署。

我们主要注意一下,第一步和第三步,其实都是通过JMX接口来进行的。例如check方法的内容是这样的:

这里的mBeanServer就是JMX里所有MBean对象注册的服务点,连接到MBeanServer上之后,后面的逻辑和反射有些类似,指定ObjectName,再指定方法名和参数即可。

我们这里的ObjectName是"Catalina:host=locahost,type=Deployer"。

调用check之后,最终会调用到HostConfig类的check方法,从而触发部署流程,进行应用的部署。完整的部署过程请参考前面的文章:

如何在Tomcat中部署应用的多个版本

WEB应用是怎么被部署的?

Tomcat集群应用部署功能实现分析

所以,如果你想自己造个轮子来实现远程部署的时候,也可以参考这种使用JMX的方式。

另一种方式

之前介绍过IDE内Tomcat工作方式时描述过IDEA里在向Tomcat部署应用时是怎么样通过JMX进行的(你一定不知道IDE里的Tomcat是怎么工作的!)。

在IDEA里,向tomcat部署一个应用,启动时,其实并不会在本地的tomcat中找到该应用的目录,或者实际运行的目录下有该应用。仔细观察发现,IDEA是通过Tomcat的MBean,动态的向tomcat增加了一个Context,即一个应用。这样直接指定了应用的路径,访问路径等

例如下面的调用链:

TCP Connection(2)-127.0.0.1@1379 daemon, prio=5, in group 'RMI Runtime', status: 'RUNNING'
at org.springframework.web.context.ContextLoaderListener.<init>(ContextLoaderListener.java:98)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1585)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:463)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:413)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
at java.lang.Thread.run(Thread.java:745)

也就是根据实际路径path,docBase这些构造一个StandardContext,并添加到Host中,对外提供服务。

以上,是几种通过JMX可以动态远程部署的方式,供参考。当然如果想用更直接一些的方式,在代码里控制应用的copy,然后控制Tomcat进程自动重启,也可以啦。

马上到新年了,提前祝各位朋友新年快乐,2017心想事成,万事如意!

2017愿我们都能更上一层楼。

常见问题中增加了一些内容,在公众号会话窗口选择常见问题菜单了解。

关注Tomcat那些事儿,发现更多精彩文章!了解各种常见问题背后的原理与答案。深入源码,分析细节,内容原创,欢迎关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值