概述
静态部署
在jetty安装目录下存在一个名为webapps的目录,你可以存放web应用程序或者war文件.Jetty服务启动时会扫描webapps目录下面的文件,如果识别为web应用程序,那么就启动它。上下文路径就是文件夹的名称或者war文件的名称。(文件夹或战的名称是root,对应的上下文路径为“/”)
此类部署方式之所以被称为静态部署 ,是因为在服务器启动完成后便不在扫描webapps目录变动情况了,换句话说,在服务启动完成后,再在webapps部署新的web应用,不会及时生效,需等到服务器重启后才能被识别。
顺便提醒下,虽然这里叫静态部署,但是网络应用里面的JSP被修好后,还是会被动态重编译。
动态部署
在jetty安装目录下存在一个名为contexts的目录,在这个目录里面是用来放置动态部署的配置文件的,配置文件是xml文件,使用的语法和第4章介绍的Jetty xml配置语法相同。(配置文件语法统一,这也是jetty设计优秀之处)jetty启动服务时,会开启一个线程每隔一段时间扫描上下文目录下的xml配置文件,然后更加配置文件的内容来部署一个web应用。当服务器启动后的任意时刻,你在contexts下新增一个配置文件,jetty就会动态地启动这个web应用,同理,删除一个已存在的配置文件,jetty就会关闭相应的web应用。你也可以修改一下配置文件的最后修改时间,来达到重启web应用的功能。
此类部署方式就是所谓的动态部署了。
需要提醒的是,通常情况下你会认为部署一个网应用程序,那么这个网应用一定是符合Servlet规范的,不然jetty为什么会叫servlet容器呢!但是Jetty的设计哲学没有强迫你非得这样做,Jetty允许你发布一个支持上下文功能,但不支持的Servlet的应用。
如,在码头自带的示例中,上下文目录下有一个文件javadoc.xml,内容如下:
<?xml version =“1.0”encoding =“ISO-8859-1”?>
<!DOCTYPE配置PUBLIC“ - // Mort Bay Consulting // DTD配置// EN”“http://jetty.mortbay.org/configure.dtd”>
<! -
为javadoc配置自定义上下文。
此上下文仅包含具有默认servlet的ServletHandler
提供静态html文件和图像。
- >
<Configure class =“org.mortbay.jetty.handler.ContextHandler”>
<Call class =“org.mortbay.log.Log”name =“debug”> <Arg>配置javadoc.xml </ Arg> </ Call>
<Set name =“contextPath”> / javadoc </ Set>
<Set name =“resourceBase”> <SystemProperty name =“jetty.home”default =“。”/> / javadoc / </ Set>
<Set name =“handler”>
<New class =“org.mortbay.jetty.handler.ResourceHandler”>
<Set name =“welcomeFiles”>
<Array type =“String”>
的<item>的index.html </项目>
<Item> contents.html </ Item> <! - 未生成javadoc的索引 - >
</阵列>
</设定>
<Set name =“cacheControl”> max-age = 3600,public </ Set>
</新>
</设定>
</配置>
webapps目录和环境目录
这两个目录的位置一定必须在jetty安装目录下面么?它们的名字必须如此么?
根据前面不断宣称的Jetty的灵活性,答案肯定是否定的。目录的名称和位置只是jetty.xml文件中的默认配置,如果你愿意都可以修改。
该配置文件启动了一个java文档的网络服务,文档的静态文件被放在$ jetty_home / javadoc目录下,访问地址是http://127.0.0.1:8080/javadoc。
现在看不懂这个文件也不要紧,后续内容会设计,这里只是用来展示下Jetty的灵活性。
Jetty实现上下文功能的基本原理
在默认的服务配置文件的jetty.xml中有如下一段配置:
<! - ============================================== ============= - >
<! - 设置处理程序 - >
<! - ============================================== ============= - >
<Set name =“handler”>
<! - HandlerCollection中每一个Handler都会被按顺序执行 - >
<New id =“Handlers”class =“org.mortbay.jetty.handler.HandlerCollection”>
<Set name =“handlers”>
<Array type =“org.mortbay.jetty.Handler”>
的<item>
<! - ContextHandler的集合 - >
<New id =“Contexts”class =“org.mortbay.jetty.handler.ContextHandlerCollection”/>
</项目>
的<item>
<! - DefaultHandler如果前一Handler没有处理request的话就会执行它。用来输出提示信息或者输出网站图标 - >
<New id =“DefaultHandler”class =“org.mortbay.jetty.handler.DefaultHandler”/>
</项目>
<! - 请求日志记录器 - >
的<item>
<New id =“RequestLog”class =“org.mortbay.jetty.handler.RequestLogHandler”/>
</项目>
</阵列>
</设定>
</新>
</设定>
通过这段默认配置,为码头的服务器对象设置了一组处理程序对象,结构如下图:
Server对象将接收到的HTTP请求转发到HandlerCollection对象,再由HandlerCollection对象将HTTP请求按顺序转发给内部所有的Handler对象,即被HandlerCollection包含的对象都有机会去处理每一个请求。
让我们看一段HandlerCollection的核心代码,来验证上面的说法:
for(int i = 0; i <_handlers.length; i ++)
{
尝试
{
_handlers [i] .handle(目标,请求,响应,调度);
}
catch(IOException e)
{
扔掉;
}
catch(RuntimeException e)
{
扔掉;
}
catch(例外e)
{
if(mex == null)
mex = new MultiException();
mex.add(E);
}
}
现在来主要看本节的主角ContextHandlerCollection,通过
<新的ID = “上下文” 类= “org.mortbay.jetty.handler.ContextHandlerCollection”/>来配置,从上图中看出它也是一个集合,集合就意味着可以容纳其他处理程序,再从类名可以看出该集合只能容纳的ContextHandler类以及它的子类。新标签的ID属性被设置为“上下文”,由第4章的内容可知ContextHandlerCollection对象会以键为“上下文”保存起来,可以使用参考文献标签可以再次引用该对象,如何引用在下面的篇章会介绍。
ContextHandlerCollection的作用是什么?其作用是将接收到的请求分发给正确的ContextHandler来处理,分发的依据就是ContextHandler的上下文路径。
静态部署的原理和配置文件
先看一段的jetty.xml中的配置片段:
<! - ============================================== ============= - >
<! - 配置webapp部署程序。 - >
<! - webapp部署者将部署发现的标准Web应用程序 - >
<! - 在启动时的目录中,无需额外的 - >
<! - 配置文件。它不支持热部署或 - >
<! - 非标准上下文(参见上面的ContextDeployer)。 - >
<! - - >
<! - 此部署程序配置为从 - >部署Web应用程序
<! - $ JETTY_HOME / webapps目录 - >
<! - - >
<! - 通常只需要使用一种类型的部署者。 - >
<! - - >
<! - ============================================== ============= - >
<Call name =“addLifeCycle”>
<精氨酸>
<New class =“org.mortbay.jetty.deployer.WebAppDeployer”>
<Set name =“contexts”> <Ref id =“Contexts”/> </ Set>
<Set name =“webAppDir”> <SystemProperty name =“jetty.home”default =“。”/> / webapps </ Set>
<Set name =“parentLoaderPriority”> false </ Set>
<Set name =“extract”> true </ Set>
<Set name =“allowDuplicates”> false </ Set>
<Set name =“defaultsDescriptor”> <SystemProperty name =“jetty.home”default =“。”/> / etc / webdefault.xml </ Set>
</新>
</精氨酸>
</通话>
等价的Java代码是:
WebAppDeployer webAppDeployer = new WebAppDeployer();
webAppDeployer.setContexts(env.get(“ Contexts ”));
webAppDeployer.setWebAppDir(System.getProperty(“jetty.home”,“。”)+“/ webapps” );
webAppDeployer.setParentLoaderPriority(假);
webAppDeployer.setExtract(真);
webAppDeployer.setAllowDuplicates(假);
webAppDeployer.setDefaultsDescriptor(System.getProperty(“jetty.home”,“。”)+“/ etc / webdefault.xml” );
server .addLifeCycle(webAppDeployer);
其实Jetty就是用WebAppDeployer对象来完成静态部署的任务的。上一节中我们说过ContextHandlerCollection对象会以密钥为“Contexts”保存起来,WebAppDeployer.setContexts(env.get(“ Contexts ”));方法将ContextHandlerCollection对象的引用设置给了webAppDeployer对象,在服务器启动过程中WebAppDeployer将默认实例化一些的ContextHandler的子类WebappContext的实例,并添加到ContextHandlerCollection对象中去。大致的过程就是这样的,细节问题接下来会讨论。
WebAppDeployer类的工作内容
当服务器启动时,WebAppDeployer扫描指定的WebAppDir目录(默认配置为System.getProperty(“jetty.home”,“。”)+“/ webapps”,及jetty安装目录下的webapps目录,可以修改)。在WebAppDir目录中发现的文件夹或者.war文件或者.jar文件,每个文件夹或文件都会被看作是一个的web应用程序,实例化一个WebAppContext对象,并将该对象添加到ContextHandlerCollection对象中去。
WebAppContext代表一个支持Servlet标准的应用程序。
动态部署的原理和配置
动态部署的原理和静态部署基本原理差不多,都是向ContextHandlerCollection对象中增加ContextHandler的实例对象。
先看一段的jetty.xml的配置:
<! - ============================================== ============= - >
<! - 配置上下文部署者 - >
<! - 上下文部署者将部署 - >中描述的上下文
<! - 在目录中发现的配置文件。 - >
<! - 可以扫描配置目录以进行热 - >
<! - 在配置的scanInterval上部署。 - >
<! - - >
<! - 此部署程序配置为部署配置的上下文 - >
<! - 在$ JETTY_HOME / contexts目录中 - >
<! - - >
<! - ============================================== ============= - >
<Call name =“addLifeCycle”>
<精氨酸>
<New class =“org.mortbay.jetty.deployer.ContextDeployer”>
<Set name =“contexts”> <Ref id =“Contexts”/> </ Set>
<Set name =“configurationDir”> <SystemProperty name =“jetty.home”default =“。”/> / contexts </ Set>
<Set name =“scanInterval”> 5 </ Set>
</新>
</精氨酸>
</通话>
等价的Java的代码是:
ContextDeployer contextDeployer = new ContextDeployer();
contextDeployer.setContexts(env.get(“Contexts”) ); contextDeployer.setConfigurationDir(System.getProperty(“jetty.home”,“。”)+“/ contexts” );
contextDeployer.setScanInterval(5 ); //扫描间隔时间
server .addLifeCycle(contextDeployer);
可以看出码头正是利用ContextDeployer类来实现动态部署的功能。
ContextDeployer的工作内容
当服务器启动时,ContextDeployer扫描$ jetty_home / contexts目录下面的所有xml文件,根据xml文件的配置内容,实例化相应的ContextHandler或其子类实现(WebappContext)对象,并将该对象添加到ContextHandlerCollection对象中去。
ContextDeployer的方法setScanInterval会设置一个扫描间隔时间,单位为秒。服务器启动完成后,会有一个后台线程以scanInterval为间隔,不断扫描configurationDir指定的目录,如果发现xml文件的新增,删除,修改会相应的执行对应ContextHandler对象的部署,移除,重新部署等工作。
Contexts目录下面的配置文件是怎样的?使用的是Jetty xml配置的语法。先看一个文件示例:
$ JettyHome /环境/的test.xml文件
<Configure class =“org.mortbay.jetty.webapp.WebAppContext”>
<! - 设定上下文路径 - >
<Set name =“contextPath”> / test </ Set>
<! - 设定的网络应用程序的战争文件位置 - >
<Set name =“war”> <SystemProperty name =“jetty.home”default =“。”/> / webapps / test </ Set>
<! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
<! - 其他可选的配置属性 - >
<! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
<Set name =“extractWAR”> false </ Set>
<Set name =“copyWebDir”> false </ Set>
<Set name =“defaultsDescriptor”> <SystemProperty name =“jetty.home”default =“。”/> / etc / webdefault.xml </ Set>
<! - 虚拟主机
<Set name =“virtualHosts”>
<Array type =“String”>
的<item> www.myVirtualDomain.com </项目>
的<item>本地主机</项目>
的<item> 127.0.0.1 </项目>
</阵列>
</设定>
- >
<! - 禁用cookie
<Get name =“sessionHandler”>
<Get name =“sessionManager”>
<Set name =“usingCookies”type =“boolean”> false </ Set>
</ GET>
</ GET>
- >
</配置>
类ContextDeployer是如何使用这个配置的呢?看下ContextDeployer中的一段核心代码:
XmlConfiguration xmlConfiguration = new XmlConfiguration(resource.getURL());
...
ContextHandler context = (ContextHandler) xmlConfiguration.configure();
第四章中介绍过XmlConfiguration类,相信你也知道它的用途了。$ JettyHome / contexts / test.xml文件中配置标签的属性class =“org.mortbay.jetty.webapp.WebAppContext”指明了最终需要实例化的类,这个类必须是ContextHandler本身或其子类,否则就会抛出异常。
在text.xml文件中我们可以对当前测试应用程序设定更多的特性,比如虚拟主机,是否启用会话功能等等,详细可以参考WebAppContext类的API文档。
jetty-web.xml配置文件
在动态部署的方式下,我们可以对WebAppContext对象进行详细设置,但是在静态部署时却不可以。而且把和web应用程序功能相关的配置放在contexts目录下的一个配置文件中,对部署人员也是一个挑战,很容易混乱。
Jetty为了解决这个问题,运行我们在WEB-INF目录下面放入一个名为jetty-web.xml的文件(文件名还可以为jetty6- web.xml或者web-jetty.xml),这个配置文件的语法同样也是jetty xml configuration语法,其中配置标签的类属性是org.mortbay.jetty.webapp.WebAppContext。
一个码头-web.xml中的示例:
<?xml version =“1.0”encoding =“ISO-8859-1”?>
<!DOCTYPE配置PUBLIC“ - // Mort Bay Consulting // DTD配置// EN”“http://jetty.mortbay.org/configure.dtd”>
<! -
这是特定于jetty的Web应用程序配置文件。开始时
在Web应用程序中,查找WEB-INF / web-jetty.xml文件,如果找到,则进行处理
作为org.mortbay.xml.XmlConfiguration文件并应用于
org.mortbay.jetty.servlet.WebApplicationContext objet
- >
<Configure class =“org.mortbay.jetty.webapp.WebAppContext”>
<Call class =“org.mortbay.log.Log”name =“debug”> <Arg>执行jetty-web.xml </ Arg> </ Call>
<! - <Set name =“contextPath”> / mycontext </ Set> - >
</配置>
在这个配置文件中你可以对已经实例化的WebAppContext对象进行操作。
Jetty服务在启动一个WebAppContext应用程序时,WebAppContext类会在当前应用的WEB-INF目录下面搜索jetty- web.xml的配置文件,如果发现了类似文件,就调用XmlConfiguration类对WebAppContext的实例对象进行配置。
核心代码:
JettyWebXmlConfiguration.java
XmlConfiguration jetty_config = new XmlConfiguration(jetty.getURL());
jetty_config.configure(getWebAppContext());
jetty_config.configure(getWebAppContext());
其中getWebAppContext()方法的作用是取得当前启动的WebAppContext对象。
在上下文目录下的配置文件中可以做的事情,在码头-web.xml文件文件中一样可以做到。
同样即使我们使用静态部署的方式部署一个WebAppContext的应用程序,一样可以通过在WEB-INF目录下加入jetty-web.xml文件来控制WebAppContext对象的行为和属性。
webdefault.xml文件
在ContextDeployer和WebAppDeployer两个类的实例化配置中我们都可以看到一个名为defaultsDescriptor的属性配置,默认情况下都指向了$ jetty_home / etc / webdefault.xml文件。当然你可以不配置这个属性,默认会指向jetty.jar文件中的org / mortbay / jetty / webapp / webdefault.xml文件,不过为了修改方便我们还是使用etc / webdefault.xml文件。
webdefault.xml作用是什么?相信你在tomcat中也见过这种类似配置文件,作用就是为WebAppContext类型的应用程序提供一个默认的配置,其语法就是Servlet规范中定义的web.xml文件的语法。
webdefault.xml主要定义了一些组件如:
- DefaultServlet:服务静态文件
- JspServlet:服务jsp页面
其余定义了常用的配置,比如默认Session过期时间,welcome- file-list等等。
接下来的章节会介绍DefaultServlet和JspServlet的配置。
DefaultServlet配置
在webdefault.xml定义了DefaultServlet对象,DefaultServlet有很多可选的配置。
参数名 | 可选值 | 默认值 | 作用 |
acceptRanges | 真或假 | 真正 | 服务器是否支持静态文件下载的断点续传功能。 真支持,虚不支持。 |
dirAllowed | 真或假 | 真正 | 如果访问的地址指向一个目录,且目录下不存在一个webcome文件的情况下,是否显示该目录列表内容.true显示,false不显示。 注意:在生产环境下,建议设置为false,避免泄露不必要的详细。 |
welcomeServlets | 真或假 | 假 | 一般情况下welcome- file-list指定的是具体存在文件,当文件不存在时要么显示403错误,要文显示目录列表内容.webcomeServlets的作用是,当欢迎文件不存在是否把请求地址映射到响应的Servlet上执行.true映射,false不映射。 默认情况下是不映射的,除非你想将一个某个Servlet路径作为一个webcome-file-list的一员时,可以将该设置为true。 |
redirectWelcome | 真或假 | 假 | 请求发送给welcome文件路径的方式.true使用重定向方式,false使用转发方式。 |
gzip的 | 真或假 | 假 | |
resoureBase | |||
relativeResourceBase | |||
useFileMappedBuffer | 真或假 | ||
cacheControl | |||
maxCacheSize | |||
maxCachedFileSize | |||
maxCachedFiles | |||
cacheType | “nio”,“bio”或“both” |
5.8 JSP配置
<! - ============================================== ====================== - >
<! - JSP Servlet - >
<! - 这是来自jakarta项目的jasper JSP servlet - >
<! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
<! - JSP页面编译器和执行servlet,它是机制 - >
<! - Glassfish用于支持JSP页面。传统上,这个servlet - >
<! - 映射到URL patterh“* .jsp”。这个servlet支持 - >
<! - 以下初始化参数(默认值为square - >
<! - 括号): - >
<! - - >
<! - checkInterval如果开发为false且重新加载为true,则为 - >
<! - 启用后台编译。checkInterval - >
<! - 是检查之间的时间(以秒为单位) - >
<! - 如果需要重新编译JSP页面。[300] - >
<! - - >
<! - 编译器哪个编译器Ant应该用来编译JSP - >
<! - 页面。有关更多信息,请参阅Ant文档 - >
<! - 信息。[javac] - >
<! - - >
<! - classdebuginfo是否应使用 - >编译类文件
<! - 调试信息?[true] - >
<! - - >
<! - classpath编译时我应该使用什么类路径 - >
<! - 生成的servlets?[动态创建 - >
<! - 基于当前的Web应用程序] - >
<! - 设置为?使容器明确设置 - >
<! - 此参数。 - >
<! - - >
<! - development Jasper在开发模式中使用(将检查 - >
<! - 对每次访问进行JSP修改)?[true] - >
<! - - >
<! - enablePooling确定标记处理程序池是否为 - >
<! - enabled [true] - >
<! - - >
<! - fork Tell Ant来编译JSP页面的编译,以便 - >
<! - 一个单独的JVM用于JSP页面编译 - >
<! - 来自一个Tomcat正在运行。[true] - >
<! - - >
<! - ieClassId要发送到Internet的class-id值 - >
<! - 使用<jsp:plugin>标签时的资源管理器。 - >
<! - [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] - >
<! - - >
<! - javaEncoding用于生成java的Java文件编码 - >
<! - 源文件。[UTF-8] - >
<! - - >
<! - keepgenerated我们应该保留生成的Java源代码 - >
<! - 为每个页面而不是删除它?[true] - >
<! - - >
<! - logVerbosityLevel要生成的详细消息的级别 - >
<! - 由这个servlet。提高水平会导致 - >
<! - 生成更多消息。有效值为 - >
<! - 致命,错误,警告,信息和调查。 - >
<! - [警告] - >
<! - - >
<! - mappedfile我们应该用一个 - >生成静态内容
<! - 每个输入行的print语句,以方便 - >
<! - 调试?[false] - >
<! - - >
<! - - >
<! - 重新加载Jasper应该检查修改后的JSP吗?[true] - >
<! - - >
<! - suppressSmap应该为JSR45生成SMAP信息 - >
<! - 调试被抑制?[false] - >
<! - - >
<! - dumpSmap JSR45调试的SMAP信息应该是 - >
<! - 转储到文件?[false] - >
<! - 如果suppressSmap为真,则为False - >
<! - - >
<! - scratchdir当 - >时我们应该使用什么临时目录
<! - 编译JSP页面?[默认工作目录 - >
<! - 对于当前的Web应用程序] - >
<! - - >
<! - tagpoolMaxSize最大标记处理程序池大小[5] - >
<! - - >
<! - xpoweredBy确定X-Powered-By响应 - >
<! - 标头由生成的servlet [false] - >添加
<! - - >
<! - 如果您希望使用Jikes编译JSP页面: - >
<! - 将init参数“compiler”设置为“jikes”。定义 - >
<! - 启动Jetty时的属性“-Dbuild.compiler.emacs = true” - >
<! - 使Jikes以与 - >兼容的格式发出错误消息
<! - 贾斯珀。 - >
<! - 如果您收到错误报告,jikes无法使用UTF-8编码, - >
<! - 尝试将init参数“javaEncoding”设置为“ISO-8859-1”。 - >
以上参考:http://aoyouzi.iteye.com/blog/2095098
(重点)真正的部署方式
jetty8部署web应用需要将war包部署到${JETTY_HOME}/webapps下,然后将context的相关配置放到${JETTY_HOME}/contexts下,然后启动即可。
jetty9将war包和context配置的xml都放到了${JETTY_HOME}/webapps下了,比如你有一个myapp.war,将其放到webapps下之后,需要新建一个myapp.xml的文件
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/myapp</Set>
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/myapp.war</Set>
</Configure>
启动jetty,然后在浏览器就能访问localhost:8080/myapp了。
补:学习官方文档发现jetty9部署规则如下:
部署web应用
web应用部署在webapps文件夹,支持热部署,支持标准的WAR文件和Jetty配置文件,并遵循下面的约定:
1)如果文件夹example/被部署,且包含一个WEB-INF/子文件夹,则它作为标准web应用部署,否则它作为静态目录上下文部署。上下文路径是/example(即: http://localhost:8080/example/ ),但如果文件夹名是ROOT(大小写敏感),则上下文路径是/。如果文件夹名以“.d”结束,则被忽略(但可以通过直接配置来使用)。
2)文件example.war被作为标准web应用部署,上下文路径为/example(即: http://localhost:8080/example/ )。如果文件名是ROOT(大小写敏感),则上下文路径为/。如果example.war和example/同时存在,则WAR被部署。
3)一个XML文件example.xml被部署,配置通过XML文件定义,配置必须包含上下文路径。如果example.xml和example.war存在,仅XML被部署。
如果你有一个标准的web应用,你能通过拷贝它到webapps文件夹来热部署它到Jetty。
详细补充介绍
(7)部署项目bossms
web应用部署在webapps文件夹,支持热部署,支持标准的WAR文件和Jetty配置文件,并遵循下面的约定:
1)如果文件夹example/被部署,且包含一个WEB-INF/子文件夹,则它作为标准web应用部署,否则它作为静态目录上下文部署。上下文路径是/example(即:http://localhost:8080/example/),但如果文件夹名是ROOT(大小写敏感),则上下文路径是/。如果文件夹名以“.d”结束,则被忽略(但可以通过直接配置来使用)。
2)文件example.war被作为标准web应用部署,上下文路径为/example(即:http://localhost:8080/example/)。如果文件名是ROOT(大小写敏感),则上下文路径为/。如果example.war和example/同时存在,则WAR被部署。
3)一个XML文件example.xml被部署,配置通过XML文件定义,配置必须包含上下文路径。如果example.xml和example.war存在,仅XML被部署。
如果你有一个标准的web应用,你能通过拷贝它到webapps文件夹来热部署它到Jetty。
备注:标准WAR文件或者WAR文件解压缩文件夹需要有WEB-INF/web.xml文件,否则作为静态目录上下文部署。
当部署spring boot的项目时,由于可能没有web.xml文件,会作为静态目录上下文部署,而不是web项目。解决办法:为 jetty 实例加入模块:jsp。 命令:java -jar /home/apps/jetty/start.jar --add-to-start=jsp。 如果把spring boot项目部署在$JETTY_HOME/webapps下,在$JETTY_HOME 下启动jetty,因为此时jetty实例默认拥有jsp模块,所以不会出现上面的当作静态文件目录部署的问题,而是作为web项目部署。
将项目bossms放在$JETTY_BASE/webapps目录下,更名为ROOT,假设http端口是80,则bossms访问地址:http://ip/
如果不更名,则访问地址:http://ip/bossms
参考:
2016-03-16 12:03:07
1. 简单有效的方式
把要部署的工程(war包、工程目录或者xml描述文件)放到${JETTY_HOME}的webapps目录下即可;
需要注意的是: > jetty会对webapps目录下的几乎所有war包、目录、xml文件(有一些例外,如隐藏文件和.d结尾的目录等会被忽略)进行自动部署。 > 如果war包、目录和xml文件同名,则部署的顺序为xml文件 > war包 > 目录 。比如,webapps目录下有:rank.war,rank目录以及rank.xml,其中rank目录为rank.war解压后的目录,rank.xml中引用的是rank.war包或者rank目录,则此时,仅有xml文件被部署,这里成立的前提是同名,如果不同名,但它们是同一个工程,则会导致工程被重复部署,切记!(关于重复部署,参考前一篇博文:Jetty9避免重复部署)
我建议的做法是:将war包或解压后的目录放在webapps目录下,或者将xml描述文件放在webapps目录下,将war包或目录放在单独的目录里。
2. 配置context path
默认,jetty将webapps目录下的工程名作为context path,如果工程名称为ROOT,则context path为/;比如,将rank.war(或rank目录)放在webapps目录下,则context path为/rank,如果将rank.war重命名为ROOT.war,则context path为/;
如果通过文件名来配置context path无法满足要求,则可以通过xml文件来配置,如将rank.xml放在webapps目录下,添加如下内容:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"><Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war">/opt/www/ugc-base/webapps/RankByElasticSearch-1.0.war</Set></Configure>
contextPath配置context path,war指定工程war包或目录的路径;
3. jetty启动/停止
建议通过${JETTY_HOME}下bin/jetty.sh脚本来启动/停止jetty,如:
$ bin/jetty start
$ bin/jetty stop
当然,也可以通过start.jar来启动,如:
$ java -jar start.jar
如果希望通过start.jar停止,则在启动的时候需要指定STOP.PORT和STOP.KEY两个参数,且启动和停止时,两个参数的值必须匹配,如:
$ java -jar start.jar STOP.PORT=8181 STOP.KEY=ugcKey
$ java -jar start.jar STOP.PORT=8181 STOP.KEY=ugcKey --stop
所以,一般通过bin/jetty.sh控制jetty的运行,使用start.jar查看jetty的配置和状态。
4. 配置jetty环境变量和jvm参数
通过bin/jetty.sh来控制jetty的运行,所以编辑bin/jetty.sh文件,可以配置的变量主要有:
JAVA: 设置java命令的绝对路径,即jdk的bin目录下的java命令的路径,如果没设置,则从PATH环境变量中查找;JAVA_OPTIONS:设置jvm参数;JETTY_HOME:jetty的安装目录,如果没有设置,则从调用该脚本的上下文环境中猜测;JETTY_BASE:jetty的base目录,即当前工程使用的jetty环境的根目录,如果没有设置,则与JETTY_HOME相同;JETTY_RUN:配置保存jetty pid文件的路径,如果没有配置,根据以下顺序查找第一个可用目录:/var/run, /usr/var/run, JETTY_BASE, /tmp;JETTY_PID:pid文件路径,默认为:$JETTY_RUN/$NAME.pid(NAME变量表示启动jetty时,去掉扩展名的脚本名称);JETTY_ARGS:jetty参数,如配置端口号等:JETTY_ARGS=8080 jetty.spdy.port=8443JETTY_USER:配置启动用户,如以nkcoder用户启动:JETTY_USER=nkcoder
注意:以上这些变量,虽然在jetty的运行环境下都具有默认值,但是在设置时,这些参数还是空的,即不能互相引用,比如,没有显式配置JETTY_BASE,直接配置JETTY_RUN=JETTY_BASE,则此时JETTY_RUN使用的还是默认值,因为JETTY_BASE此时为空。
这里提供一个简单的配置供参考:
JETTY_HOME=/usr/local/jetty9.1JETTY_BASE=$JETTY_HOME
JETTY_RUN=$JETTY_BASE
JETTY_USER=www
JETTY_ARGS=jetty.port=8989JAVA=/usr/local/jdk7/bin/java
JAVA_OPTIONS="-Xloggc:/opt/logs/vrsRank/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=50 -XX:PermSize=256m -XX:MaxPermSize=256m -Xss256k -server -Xms4G -Xmx4G -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=18787 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/logs/vrsRank/oom.log"
5. 查看jetty配置
通过start.jar查看帮助和配置:
$ java -jar start.jar --help
主要的查看配置的参数有:
--list-config: 查看启动jetty使用的配置:java环境,jetty环境,JVM参数,属性,服务器classpath,服务器的xml配置等;--list-modules: 查看系统使用的模块--list-classpath: 查看系统使用的classpath--version:查看版本信息--module=<model-name>:临时启用一个模块
6. 一台机器上同时部署多个jetty
以在一台服务器上同时部署两个工程为例,需要两份jetty和一份jdk。和单独部署的唯一区别就是,只要确保pid和port是不同的即可。
第一种方式:修改jetty.sh脚本的名称,因为pid文件的名称就是脚本的名称,如:
工程1使用jetty1,将bin/jetty.sh重命名为bin/jetty1.sh,同时修改其配置如下(注意不用配置JETTY_RUN变量):
JETTY_HOME=/usr/local/jetty1
JETTY_BASE=$JETTY_HOME
JETTY_USER=www
JETTY_ARGS=jetty.port=8181JAVA=/usr/local/jdk7/bin/java
JAVA_OPTIONS="-Xloggc:/opt/logs/ugcRank/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
工程2使用jetty2,将bin/jetty.sh重命名为bin/jetty2.sh,并修改配置:
JETTY_HOME=/usr/local/jetty2
JETTY_BASE=$JETTY_HOME
JETTY_USER=www
JETTY_ARGS=jetty.port=8282JAVA=/usr/local/jdk7/bin/java
JAVA_OPTIONS="-Xloggc:/opt/logs/vrsRank/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
此时,两个jetty的pid均位于默认的目录下,即/var/run,路径分别为/var/run/jetty1.pid,/var/run/jetty2.pid。
第二种方式:修改pid文件保存的目录,该目录由JETTY_RUN配置,默认都在/var/run下,如:
工程1使用jetty1,修改bin/jetty.sh如下:
JETTY_HOME=/usr/local/jetty1
JETTY_BASE=$JETTY_HOME
JETTY_RUN=$JETTY_BASE
JETTY_USER=www
JETTY_ARGS=jetty.port=8181JAVA=/usr/local/jdk7/bin/java
JAVA_OPTIONS="-Xloggc:/opt/logs/ugcRank/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
工程2使用jetty2,修改bin/jetty.sh如下:
JETTY_HOME=/usr/local/jetty1
JETTY_BASE=$JETTY_HOME
JETTY_RUN=$JETTY_BASE
JETTY_USER=www
JETTY_ARGS=jetty.port=8181JAVA=/usr/local/jdk7/bin/java
JAVA_OPTIONS="-Xloggc:/opt/logs/ugcRank/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
此时,pid文件位于各自jetty的安装目录下,虽然都为jetty.pid,但是互不影响。
7. 将jetty配置为系统服务
首先,将bin/jetty.sh拷贝到/etc/init.d中:
$ cp bin/jetty.sh /etc/init.d/jetty
然后,新建文件/etc/default/jetty,在其中设置环境变量JETTY_HOME:
$ vim /etc/default/jetty
JETTY_HOME=/usr/local/jetty9.1
启动和停止:
$ service jetty start
$ service jetty stop
说明:bin/jetty.sh默认将/etc/default/{pid}作为其配置文件,此时pid名称即为jetty,所以/etc/default/jetty会作为jetty的配置文件,可以在其中配置JETTY_HOME, JAVA, JAVA_OPTIONS等环境变量。
注意,jetty的服务是默认会占用系统内存的,也就是说,如果你要热部署(不停应用的状态下),系统内存的占用也会越来越高,必须停掉服务,这样才会释放内存,然后替换:掉工程,然后重新启动服务
转自【IT精英团】:http://www.itnpc.com/news/web/145189730834348.html
参考:
Jetty9避免重复部署
YouSharp 2014-05-22 605 阅读
部署
jetty是一个轻量级的web容器,部署简单,同时高度可定制化。由于刚接触,对其约定和配置不太熟练,在自动部署时,跳过一次重复部署的坑,这里简要说明一下,希望给同样打算在项目中使用jetty9的朋友一个参考。
默认情况下,jetty会对根目录(也可以配置jetty.base)下webapps/目录下的内容实现自动部署,部署的规则如下:
- 隐藏文件(.开头)和.d结尾的目录被忽略;
- CVS目录如”CVS”和”CVSROOT”被忽略;
- 任何war包都会被自动部署;
- 任何xml描述文件被认为是可部署的;
- 任何目录都被认为是可部署的;
- 同名的war包和目录同时存在,目录不被部署,仅war包部署,且认为war包引用该目录;
- 同名的war包和xml文件同时存在,war包不被部署,仅xml文件描述符被部署,且认为该xml文件引用该war包;
- 同名的目录和xml文件同时存在,目录不被部署,xml文件被部署,且认为xml文件引用该目录;
关于更详细的说明,请参考官方文档的这里。我主要提醒的是:在webapps目录中,如果存在同名的目录、war包和xml文件,它们会被当做同一个工程,部署的优先级是xml文件>war包>目录
。一定要注意同名,如果不同名,在webapps下存在一个war包,同时存在一个引用该war包的xml文件,则会导致重复部署,这就是我跳的坑。
部署时,推荐的做法是,将xml描述文件放到自动部署的webapps目录下,里面定义war包的路径、上下文路径、是否解压、临时目录、日志文件等,然后将war包放在自定义的固定目录下,项目更新,只需要备份和替换war包,重启jetty即可。
参考: 1. Deployment Architecture
最后
以上就是妩媚学姐为你收集整理的静态部署和动态部署 静态部署 动态部署 webapps目录和环境目录 Jetty实现上下文功能的基本原理静态部署的原理和配置文件WebAppDeployer类的工作内容 ContextDeployer的工作内容 DefaultServlet配置(重点)真正的部署方式补:学习官方文档发现jetty9部署规则如下:详细补充介绍(7)部署项目bossmsJetty9避免重复部署的全部内容,希望文章能够帮你解决静态部署和动态部署 静态部署 动态部署 webapps目录和环境目录 Jetty实现上下文功能的基本原理静态部署的原理和配置文件WebAppDeployer类的工作内容 ContextDeployer的工作内容 DefaultServlet配置(重点)真正的部署方式补:学习官方文档发现jetty9部署规则如下:详细补充介绍(7)部署项目bossmsJetty9避免重复部署所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复