xylz,imxylz

关注后端架构、中间件、分布式和并发编程

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  111 随笔 :: 10 文章 :: 2679 评论 :: 0 Trackbacks

Inside in Jetty 8.x 模块化

Inside in Jetty 8.x带有一个默认的test环境。我们从这个默认的环境入手。

首先,来分析下start.ini里面的配置,这个配置决定启动了哪些模块。

$ grep -v "#" start.ini|grep -v "^$"
OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,annotations
etc/jetty.xml
etc/jetty-annotations.xml
etc/jetty-deploy.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml

利用上节学到的只是,我们先来分析下用到了那些模块。

java -jar start.jar --list-options

查找Server,jsp,jmx,resources,websocket,ext,plus,annotations这些对应的模块有:

GLOBAL option (Appended Entries) (*)
-------------------------------------------------------------
 0:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-util-8.1.2.v20120308.jar
 1:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-io-8.1.2.v20120308.jar
Option [Server] (Aggregate)
-------------------------------------------------------------
 0:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-xml-8.1.2.v20120308.jar
 1:  3.0.0.v201112011016 | ${jetty.home}/lib/servlet-api-3.0.jar
 2:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-http-8.1.2.v20120308.jar
 3:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-continuation-8.1.2.v20120308.jar
 4:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-server-8.1.2.v20120308.jar
 5:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-security-8.1.2.v20120308.jar
 6:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-servlet-8.1.2.v20120308.jar
 7:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-webapp-8.1.2.v20120308.jar
 8:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-deploy-8.1.2.v20120308.jar
 9:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-servlets-8.1.2.v20120308.jar
Option [jsp]
-------------------------------------------------------------
 0:  2.2.0.v201108011116 | ${jetty.home}/lib/jsp/com.sun.el-2.2.0.v201108011116.jar
 1:  2.2.0.v201108011116 | ${jetty.home}/lib/jsp/javax.el-2.2.0.v201108011116.jar
 2:  1.2.0.v201105211821 | ${jetty.home}/lib/jsp/javax.servlet.jsp.jstl-1.2.0.v201105211821.jar
 3:  2.2.0.v201112011158 | ${jetty.home}/lib/jsp/javax.servlet.jsp-2.2.0.v201112011158.jar
 4:  2.2.2.v201112011158 | ${jetty.home}/lib/jsp/org.apache.jasper.glassfish-2.2.2.v201112011158.jar
 5:  1.2.0.v201112081803 | ${jetty.home}/lib/jsp/org.apache.taglibs.standard.glassfish-1.2.0.v201112081803.jar
 6: 3.7.0.M20110909-1335 | ${jetty.home}/lib/jsp/org.eclipse.jdt.core-3.7.1.jar
Option [jmx]
-------------------------------------------------------------
 0:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-jmx-8.1.2.v20120308.jar
Option [resources]
-------------------------------------------------------------
 0:                (dir) | ${jetty.home}/resources
Option [websocket]
-------------------------------------------------------------
 0:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-websocket-8.1.2.v20120308.jar
Option [ext]
-------------------------------------------------------------
Empty option, no classpath entries active.
Option [plus]
-------------------------------------------------------------
 0:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-jndi-8.1.2.v20120308.jar
 1:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-plus-8.1.2.v20120308.jar
 2:  1.1.0.v201105071233 | ${jetty.home}/lib/jndi/javax.activation-1.1.0.v201105071233.jar
 3:  1.4.1.v201005082020 | ${jetty.home}/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
Option [annotations]
-------------------------------------------------------------
 0:      8.1.2.v20120308 | ${jetty.home}/lib/jetty-annotations-8.1.2.v20120308.jar
 1:  1.1.0.v201108011116 | ${jetty.home}/lib/annotations/javax.annotation-1.1.0.v201108011116.jar
 2:  3.1.0.v200803061910 | ${jetty.home}/lib/annotations/org.objectweb.asm-3.1.0.v200803061910.jar

从上一节中我们知道,这些模块相当于将那些组件加入classpath中,jetty在启动时也会装载这些模块。

$java -jar start.jar --dry-run|awk '{print $4}'|sed 's/:/\n/g'
/opt/apps/jetty8/lib/jetty-xml-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/servlet-api-3.0.jar
/opt/apps/jetty8/lib/jetty-http-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-continuation-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-server-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-security-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-servlet-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-webapp-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-deploy-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-servlets-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-annotations-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/annotations/javax.annotation-1.1.0.v201108011116.jar
/opt/apps/jetty8/lib/annotations/org.objectweb.asm-3.1.0.v200803061910.jar
/opt/apps/jetty8/lib/jetty-jmx-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jsp/com.sun.el-2.2.0.v201108011116.jar
/opt/apps/jetty8/lib/jsp/javax.el-2.2.0.v201108011116.jar
/opt/apps/jetty8/lib/jsp/javax.servlet.jsp.jstl-1.2.0.v201105211821.jar
/opt/apps/jetty8/lib/jsp/javax.servlet.jsp-2.2.0.v201112011158.jar
/opt/apps/jetty8/lib/jsp/org.apache.jasper.glassfish-2.2.2.v201112011158.jar
/opt/apps/jetty8/lib/jsp/org.apache.taglibs.standard.glassfish-1.2.0.v201112081803.jar
/opt/apps/jetty8/lib/jsp/org.eclipse.jdt.core-3.7.1.jar
/opt/apps/jetty8/lib/jetty-jndi-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-plus-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jndi/javax.activation-1.1.0.v201105071233.jar
/opt/apps/jetty8/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
/opt/apps/jetty8/resources
/opt/apps/jetty8/lib/jetty-websocket-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-util-8.1.2.v20120308.jar
/opt/apps/jetty8/lib/jetty-io-8.1.2.v20120308.jar

在总结下,不同的OPTION决定了启动不同的模块(也就是不同的组件和classpath)。另外,对于start.config里面的不同的OPTION可能有相同的模块依赖。

默认的test.war启动了如下模块:

  • Server: 一个标准的servlet容器
  • jsp: jsp模块
  • jmx: jmx支持
  • resources: 允许从${jetty.home}/resources中读取类资源(实际上是配置log4j.properties)
  • websocket: 支持websocket的例子
  • ext: 由于${jetty.home}/lib/ext目录为空,实际上什么都做。其实此特性是为了装载自定义的组件依赖。
  • plus: 一些扩展支持,从上面classpath中猜测,应该是jndi、java认证以及java mail的组件。
  • annotations: java注解以及字节码的支持。

test.war配置

再来看看加载jetty配置。 test.war模块默认加载了6个配置组件。

etc/jetty.xml
etc/jetty-annotations.xml
etc/jetty-deploy.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml

Inside in Jetty.xml

默认的jetty.xml负责配置设置服务器的参数,包括绑定的地址、线程池大小以及一些默认的处理器(Handler)等。

<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <Set name="ThreadPool">
      <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
        <Set name="minThreads">10</Set>
        <Set name="maxThreads">200</Set>
        <Set name="detailedDump">false</Set>
      </New>
    </Set>
    <Call name="addConnector">
      <Arg>
          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <Set name="host"><Property name="Inside in Jetty.host" /></Set>
            <Set name="port"><Property name="Inside in Jetty.port" default="8080"/></Set>
            <Set name="maxIdleTime">300000</Set>
            <Set name="Acceptors">2</Set>
            <Set name="statsOn">false</Set>
            <Set name="confidentialPort">8443</Set>
    <Set name="lowResourcesConnections">20000</Set>
    <Set name="lowResourcesMaxIdleTime">5000</Set>
          </New>
      </Arg>
    </Call>
    <Set name="handler">
      <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <Set name="handlers">
         <Array type="org.eclipse.jetty.server.Handler">
           <Item>
             <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
           </Item>
           <Item>
             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
           </Item>
         </Array>
        </Set>
      </New>
    </Set>
    <Set name="stopAtShutdown">true</Set>
    <Set name="sendServerVersion">true</Set>
    <Set name="sendDateHeader">true</Set>
    <Set name="gracefulShutdown">1000</Set>
    <Set name="dumpAfterStart">false</Set>
    <Set name="dumpBeforeStop">false</Set>
</Configure>

可以看出默认的线程池大小是最小线程10个,最大线程200个。绑定在所有网卡的8080端口。其它配置以后再分析。

Inside in Jetty-annotation.xml

Inside in Jetty-annotation.xml配置应该是描述支持哪些注解配置方式。

    <Call name="setAttribute">
      <Arg>org.eclipse.jetty.webapp.configuration</Arg>
      <Arg>
          <Array type="java.lang.String">
               <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
               <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
               <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
               <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
               <Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
               <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
          </Array>
      </Arg>
    </Call>

Inside in Jetty-deploy.xml

Inside in Jetty-deploy.xml配置web发布方式。

    <Call name="addBean">
      <Arg>
        <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
          <Set name="contexts">
            <Ref id="Contexts" />
          </Set>
          <Call name="setContextAttribute">
            <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
            <Arg>.*/servlet-api-[^/]*\.jar$</Arg>
          </Call>          
        </New>
      </Arg>
    </Call>

事实上这里没有定义要发布的目录或者应用位置,因此jetty-deploy依赖于jetty-contexts.xml或者jetty-webapps.xml。

Inside in Jetty-webapps.xml

Inside in Jetty-webapps.xml定义要发布的内容,通常是要发布应用或者应用的定义。默认是存放于${jetty.home}/webapps下的应用以及${jetty.home}/contexts下的xml定义。

    <Ref id="DeploymentManager">
          <Call id="webappprovider" name="addAppProvider">
            <Arg>
              <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
                <Set name="monitoredDirName"><Property name="Inside in Jetty.home" default="." />/webapps</Set>
                <Set name="defaultsDescriptor"><Property name="Inside in Jetty.home" default="."/>/etc/webdefault.xml</Set>
                <Set name="scanInterval">1</Set>
                <Set name="contextXmlDir"><Property name="Inside in Jetty.home" default="." />/contexts</Set>
<Set name="extractWars">true</Set>
              </New>
            </Arg>
          </Call>
    </Ref>

Inside in Jetty-contexts.xml

Inside in Jetty-contexts.xml定义一些预置规则。类似于一些拦截器。例如可以讲某些URI rewrite或者静态资源cache配置等。

这会自动扫描${jetty.home}/contexts下面的xml配置。

    <Ref id="DeploymentManager">
      <Call name="addAppProvider">
        <Arg>
          <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
            <Set name="monitoredDirName"><Property name="Inside in Jetty.home" default="." />/contexts</Set>
            <Set name="scanInterval">1</Set>
          </New>
        </Arg>
      </Call>
    </Ref>

Inside in Jetty-testrealm.xml

Inside in Jetty-testrealm.xml用于test.war的特定配置,用于配置一些认证信息。

    <Call name="addBean">
      <Arg>
        <New class="org.eclipse.jetty.security.HashLoginService">
          <Set name="name">Test Realm</Set>
          <Set name="config"><Property name="Inside in Jetty.home" default="."/>/etc/realm.properties</Set>
          <Set name="refreshInterval">0</Set>
        </New>
      </Arg>
    </Call>

test.xml

事实上这么模块的配置都是在<Configure id="Server" class="org.eclipse.jetty.server.Server">节点配置下。 因此可以合并成一个大的xml。这样做的好处是在一个xml包含所有配置,方便灵活定义。当然,坏处就是复用率低。

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <Set name="ThreadPool">
      <!-- Default queued blocking threadpool -->
      <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
        <Set name="minThreads">10</Set>
        <Set name="maxThreads">200</Set>
        <Set name="detailedDump">false</Set>
      </New>
    </Set>
    <Call name="addConnector">
      <Arg>
          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <Set name="host"><Property name="Inside in Jetty.host" /></Set>
            <Set name="port"><Property name="Inside in Jetty.port" default="8080"/></Set>
            <Set name="maxIdleTime">300000</Set>
            <Set name="Acceptors">2</Set>
            <Set name="statsOn">false</Set>
            <Set name="confidentialPort">8443</Set>
    <Set name="lowResourcesConnections">20000</Set>
    <Set name="lowResourcesMaxIdleTime">5000</Set>
          </New>
      </Arg>
    </Call>
    <Set name="handler">
      <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <Set name="handlers">
         <Array type="org.eclipse.jetty.server.Handler">
           <Item>
             <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
           </Item>
           <Item>
             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
           </Item>
         </Array>
        </Set>
      </New>
    </Set>
    <Set name="stopAtShutdown">true</Set>
    <Set name="sendServerVersion">true</Set>
    <Set name="sendDateHeader">true</Set>
    <Set name="gracefulShutdown">1000</Set>
    <Set name="dumpAfterStart">false</Set>
    <Set name="dumpBeforeStop">false</Set>
    <Call name="setAttribute">
      <Arg>org.eclipse.jetty.webapp.configuration</Arg>
      <Arg>
          <Array type="java.lang.String">
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
          </Array>
      </Arg>
    </Call>
    <Call name="addBean">
      <Arg>
        <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
          <Set name="contexts">
            <Ref id="Contexts" />
          </Set>
          <Call name="setContextAttribute">
            <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
            <Arg>.*/servlet-api-[^/]*\.jar$</Arg>
          </Call>
        </New>
      </Arg>
    </Call>
    <Ref id="DeploymentManager">
          <Call id="webappprovider" name="addAppProvider">
            <Arg>
              <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
                <Set name="monitoredDirName"><Property name="Inside in Jetty.home" default="." />/webapps</Set>
                <Set name="defaultsDescriptor"><Property name="Inside in Jetty.home" default="."/>/etc/webdefault.xml</Set>
                <Set name="scanInterval">1</Set>
                <Set name="contextXmlDir"><Property name="Inside in Jetty.home" default="." />/contexts</Set>
<Set name="extractWars">true</Set>
              </New>
            </Arg>
          </Call>
    </Ref>
<Ref id="DeploymentManager">
  <Call name="addAppProvider">
<Arg>
  <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
<Set name="monitoredDirName"><Property name="Inside in Jetty.home" default="." />/contexts</Set>
<Set name="scanInterval">1</Set>
  </New>
</Arg>
  </Call>
</Ref>
<Call name="addBean">
  <Arg>
<New class="org.eclipse.jetty.security.HashLoginService">
  <Set name="name">Test Realm</Set>
  <Set name="config"><Property name="Inside in Jetty.home" default="."/>/etc/realm.properties</Set>
  <Set name="refreshInterval">0</Set>
</New>
  </Arg>
</Call>
</Configure>

我们将test.xml放入etc目录下面。这是保持start.ini文件不存在,也就是不使用start.ini里面的配置。

手动运行它。

java -jar start.jar OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,annotations etc/test.xml

这时候的启动就和默认启动是一样的了。

这时候就可以访问了。

Inside in Jetty Statistics

这一部分,我们利用学习到的只是来部署一个Jetty统计模块。

修改设置

将连接计数参数打开:

    <Call name="addConnector">
      <Arg>
          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <Set name="host"><Property name="Inside in Jetty.host" /></Set>
            <Set name="port"><Property name="Inside in Jetty.port" default="8080"/></Set>
            <Set name="maxIdleTime">300000</Set>
            <Set name="Acceptors">2</Set>
            <Set name="statsOn">true</Set><!-- modify this -->
          </New>
      </Arg>
    </Call>

设置servlet

为了不影响默认的test.war环境,我们增加一个最简单的WAR环境。

根据前面学到的知识,只需要将war环境放到webapps目录下即可。可以是一个war包,也可以是一个以.war结尾的目录。

$tree webapps/demo.war/
webapps/demo.war/
`-- WEB-INF
    |-- Inside in Jetty-web.xml
    `-- web.xml
1 directory, 2 files
$cat webapps/demo.war/WEB-INF/jetty-web.xml 
<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/demo</Set>
</Configure>
$cat webapps/demo.war/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 
   xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   metadata-complete="false"
   version="3.0"> 
  <display-name>static demo</display-name>
  <servlet>
    <servlet-name>statistic</servlet-name>
    <servlet-class>org.eclipse.jetty.servlet.StatisticsServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>restrictToLocalhost</param-name><param-value>false</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>statistic</servlet-name>
    <url-pattern>/statistic/*</url-pattern>
  </servlet-mapping>
</web-app>

说明几点:

  • 为了不和test.war的contextPath混淆,这里强制修改为/demo。
  • 增加一个jetty内置的统计servlet(org.eclipse.jetty.servlet.StatisticsServlet)
  • 将servlet的参数restrictToLocalhost修改为false,否则默认情况下只能通过本机访问,不能远程访问

运行demo

保持test.war不变增加一个统计配置。

$java -jar start.jar etc/jetty-stats.xml

执行效果

使用浏览器访问

http://127.0.0.1:8080/demo/statistic/

效果如下:

统计结果包含6个部分:

  1. 统计结果收集时间
  2. 请求数详情(当前请求数、最大请求数、总共请求数、请求时间等)
  3. 请求分发详情(和请求数不同的是,这是jetty内部分发请求的数量,包括forward/include等)
  4. 响应状态详情(1xx/2xx/3xx/4xx/5xx以及总共发送的字节数)
  5. 连接数详情 (当前连接数、最大连接数、连接持续时间等)
  6. 内存状况(堆内存和非堆内存使用状况,非堆内存通常也称永久代内存)

小结

Inside in Jetty 8.x已经将各个模块拆分非常详细了。每一个模块的命名都非常有规律。通常从名称上就能够猜测出模块的作用。

部分模块可能还需要对应的配置。${jetty.home}/etc下面有大量的配置,这些零散的配置拆分是为了可复用。 如果一个jetty要想启动多个java进程,那么只需要指定不同的配置即可。甚至为了方便定制化,可能为每一个java进程创建一个完整的jetty.xml配置,而不需要${jetty.home}/etc下面的配置。



©2009-2014 IMXYLZ |求贤若渴
posted on 2012-04-12 09:39 imxylz 阅读(4765) 评论(3)  编辑  收藏 所属分类: Jetty

评论

# re: [深入浅出Jetty 05] Jetty 模块化 2012-04-12 12:18 20G高压锅炉管
这个挺有道理的啊  回复  更多评论
  

# re: [深入浅出Jetty 05] Jetty 模块化 2012-04-17 16:39 秦焜
写的明白易懂  回复  更多评论
  

# re: [深入浅出Jetty 05] Jetty 模块化[未登录] 2012-06-04 01:26 白菜
demo本机无法运行成功  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航:
 

©2009-2014 IMXYLZ