jetty学习笔记(一)

2018.6.9 jetty学习笔记(一)

什么是jetty?

简单来讲jetty就是一个开源HTTP服务器和Servlet引擎,它可以为JSP和Servlet提供运行时环境。比如Java web应用最常用的Servlet容器和Tomcat。由于其轻量、灵活的特性,jetty也被应用于一些知名产品中,例如ActiveMQ、maven、spark、gooleAppEngine、Eclipse、Hadoop等。

为什么使用jetty?

  • 异步的Servlet,支持更高的并发量

  • w模块化的设计,更灵活,更容易定制,也意味着更高的资源利用率

  • 在面对大量长连接的业务场景下,jetty默认采用的NIO模型是更好的选择

  • 将jetty嵌入到应用中,使一个普通应用可以快速支持HTTP服务

jetty的基本架构



jetty学习笔记(一)与tomcat的对比

  • jetty比较容易贴合第三方框架,比如你可以直接用Spring配置一个jetty服务器

  • 直接将jetty作为提供HTTP服务的组件,嵌入到应用中

  • jetty是面向Handler的架构,而tomcat是面向容器的架构

  • jetty默认采用NIO技术,而tomcat默认是BIO

  • jetty高度模块化,可以很灵活的管理拓展组件,而tomcat对其他组件的管理则相对困难

jetty的项目结构

jetty学习笔记(一)

jetty的hello world相关命令

cd JETTY_HOME/demo-base //进入jetty根目录

java -jar jetty.jar //启动一个java应用

Jetty.sh start //使用shell脚本启动jetty

需要注意的是:当我们进入到解压后的jetty文件后,如果直接在根目录中启动终端,输入java -jar start.jar的话启动的是根目录下的webapps,而此时的webapps只有一个.TXT格式的文件,这时候如果在网址输入localhost:8080的话会给出一个404页面。所以这种启动方式是不可以的。那么正确的启动方式是怎样的呢?我们进入到根目录下的demo-base文件夹中,发现这个文件夹下面也有一个webapps文件夹,进入这个文件夹会发现目录结构与tomcat中webapps的目录结构有些类似,那么此时在终端输入java -jar start.jar。则能正确的启动jetty。如下图所示。

jetty学习笔记(一)

我们可以发现,如果把demo-base下的webapps中的内容拷贝到根目录下的webapps文件夹中,那么jetty的启动方式就更简单了。

jetty的常用配置

  • Start.ini —服务启动配置项

  • etc/xxx.xml —服务相关配置

  • modules/xxx.mod —模块相关配置

相关命令行代码

1.ls -a :查看所有文件名称(包括隐藏文件)

2.ls -al :查看所有文件详细信息

3.java -jar ../start.jar —help:输出帮助信息 ,在某些地方-h就可以在,但是jetty需要用-help

4.java -jar ../start.jar —help jetty.port:8099 : 更改jetty的端口号为8099,说明有限级是从最外层开始的,可以在启动的时候指定一些配置信息。

jetty.xml文件

jetty通过利用配置文件,帮助我们对对象进行管理。

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- =============================================================== -->
<!-- Documentation of this file format can be found at:              -->
<!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax        -->
<!--                                                                 -->
<!-- Additional configuration files are available in $JETTY_HOME/etc -->
<!-- and can be mixed in. See start.ini file for the default         -->
<!-- configuration files.                                            -->
<!--                                                                 -->
<!-- For a description of the configuration mechanism, see the       -->
<!-- output of:                                                      -->
<!--   java -jar start.jar -?                                        -->
<!-- =============================================================== -->

<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server"           -->
<!-- Other configuration files may also configure the "Server"       -->
<!-- ID, in which case they are adding configuration to the same     -->
<!-- instance.  If other configuration have a different ID, they     -->
<!-- will create and configure another instance of Jetty.            -->
<!-- Consult the javadoc of o.e.j.server.Server for all              -->
<!-- configuration that may be set here.                             -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <!-- =========================================================== -->
    <!-- Configure the Server Thread Pool.                           -->
    <!-- The server holds a common thread pool which is used by      -->
    <!-- default as the executor used by all connectors and servlet  -->
    <!-- dispatches.                                                 -->
    <!--                                                             -->
    <!-- Configuring a fixed thread pool is vital to controlling the -->
    <!-- maximal memory footprint of the server and is a key tuning  -->
    <!-- parameter for tuning.  In an application that rarely blocks -->
    <!-- then maximal threads may be close to the number of 5*CPUs.  -->
    <!-- In an application that frequently blocks, then maximal      -->
    <!-- threads should be set as high as possible given the memory  -->
    <!-- available.                                                  -->
    <!--                                                             -->
    <!-- Consult the javadoc of o.e.j.util.thread.QueuedThreadPool   -->
    <!-- for all configuration that may be set here.                 -->
    <!-- =========================================================== -->
    <!-- uncomment to change type of threadpool
    <Arg name="threadpool"><New id="threadpool" class="org.eclipse.jetty.util.thread.QueuedThreadPool"/></Arg>
    -->
    <!-- 
这个方法有可能是通过得到ThreadPool这个方法,然后这个方法里面具有一定的参数,通过参数来对方法进行配置。Property就代表参数。完成线程池的封装。

-->
    <Get name="ThreadPool">
      <Set name="minThreads" type="int"><Property name="jetty.threadPool.minThreads" deprecated="threads.min" default="10"/></Set>
      <Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
      <Set name="idleTimeout" type="int"><Property name="jetty.threadPool.idleTimeout" deprecated="threads.timeout" default="60000"/></Set>
      <Set name="detailedDump">false</Set>
    </Get>

    <!-- =========================================================== -->
    <!-- Add shared Scheduler instance                               -->
    <!-- =========================================================== -->
    <Call name="addBean">
      <Arg>
        <New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler"/>
      </Arg>
    </Call>

    <!-- =========================================================== -->
    <!-- Http Configuration.                                         -->
    <!-- This is a common configuration instance used by all         -->
    <!-- connectors that can carry HTTP semantics (HTTP, HTTPS, etc.)-->
    <!-- It configures the non wire protocol aspects of the HTTP     -->
    <!-- semantic.                                                   -->
    <!--                                                             -->
    <!-- This configuration is only defined here and is used by      -->
    <!-- reference from other XML files such as jetty-http.xml,      -->
    <!-- jetty-https.xml and other configuration files which         -->
    <!-- instantiate the connectors.                                 -->
    <!--                                                             -->
    <!-- Consult the javadoc of o.e.j.server.HttpConfiguration       -->
    <!-- for all configuration that may be set here.                 -->
    <!-- =========================================================== -->
    <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
      <Set name="secureScheme"><Property name="jetty.httpConfig.secureScheme" default="https" /></Set>
      <Set name="securePort"><Property name="jetty.httpConfig.securePort" deprecated="jetty.secure.port" default="8443" /></Set>
      <Set name="outputBufferSize"><Property name="jetty.httpConfig.outputBufferSize" deprecated="jetty.output.buffer.size" default="32768" /></Set>
      <Set name="outputAggregationSize"><Property name="jetty.httpConfig.outputAggregationSize" deprecated="jetty.output.aggregation.size" default="8192" /></Set>
      <Set name="requestHeaderSize"><Property name="jetty.httpConfig.requestHeaderSize" deprecated="jetty.request.header.size" default="8192" /></Set>
      <Set name="responseHeaderSize"><Property name="jetty.httpConfig.responseHeaderSize" deprecated="jetty.response.header.size" default="8192" /></Set>
      <Set name="sendServerVersion"><Property name="jetty.httpConfig.sendServerVersion" deprecated="jetty.send.server.version" default="true" /></Set>
      <Set name="sendDateHeader"><Property name="jetty.httpConfig.sendDateHeader" deprecated="jetty.send.date.header" default="false" /></Set>
      <Set name="headerCacheSize"><Property name="jetty.httpConfig.headerCacheSize" default="512" /></Set>
      <Set name="delayDispatchUntilContent"><Property name="jetty.httpConfig.delayDispatchUntilContent" deprecated="jetty.delayDispatchUntilContent" default="true"/></Set>
      <Set name="maxErrorDispatches"><Property name="jetty.httpConfig.maxErrorDispatches" default="10"/></Set>
      <Set name="blockingTimeout"><Property name="jetty.httpConfig.blockingTimeout" default="-1"/></Set>
      <Set name="persistentConnectionsEnabled"><Property name="jetty.httpConfig.persistentConnectionsEnabled" default="true"/></Set>
    </New>

    <!-- =========================================================== -->
    <!-- Set the default handler structure for the Server            -->
    <!-- A handler collection is used to pass received requests to   -->
    <!-- both the ContextHandlerCollection, which selects the next   -->
    <!-- handler by context path and virtual host, and the           -->
    <!-- DefaultHandler, which handles any requests not handled by   -->
    <!-- the context handlers.                                       -->
    <!-- Other handlers may be added to the "Handlers" collection,   -->
    <!-- for example the jetty-requestlog.xml file adds the          -->
    <!-- RequestLogHandler after the default handler                 -->
    <!-- =========================================================== -->
    <!--
    存储的是初始化数据链,当加载之后,这里面的处理器也会被加载进去。如HandlerCollection、ContextHandlerCollection、DefaultHandler
-->
    <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>

    <!-- =========================================================== -->
    <!-- extra server options                                        -->
    <!-- =========================================================== -->
    <Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
    <Set name="stopTimeout"><Property name="jetty.server.stopTimeout" default="5000"/></Set>
    <Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
    <Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>

</Configure>

jetty-help.xml文件


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- Configure the Jetty Server instance with an ID "Server"       -->
<!-- by adding a HTTP connector.                                   -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

  <!-- =========================================================== -->
  <!-- Add a HTTP Connector.                                       -->
  <!-- Configure an o.e.j.server.ServerConnector with a single     -->
  <!-- HttpConnectionFactory instance using the common httpConfig  -->
  <!-- instance defined in jetty.xml                               -->
  <!--                                                             -->
  <!-- Consult the javadoc of o.e.j.server.ServerConnector and     -->
  <!-- o.e.j.server.HttpConnectionFactory for all configuration    -->
  <!-- that may be set here.                                       -->
  <!-- =========================================================== -->
     <!--
      Call代表调用方法,Arg相当于一个参数,这个参数调用一个对象,但是这个对象没有,就new一个对象,那么new的对象就是org.eclipse.jetty.server.ServerConnector这个对象。这个对象下面的Arg代表这个对象的一些参数,而这些参数可以通过下面的Set方法进行构造,Ref和Spring中的Ref一样,代表引用。和<Configure id="Server" class="org.eclipse.jetty.server.Server">一样。
      --> 
      
  <Call name="addConnector">
    <Arg>
      <New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="acceptors" type="int"><Property name="jetty.http.acceptors" deprecated="http.acceptors" default="-1"/></Arg>
        <Arg name="selectors" type="int"><Property name="jetty.http.selectors" deprecated="http.selectors" default="-1"/></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config"><Ref refid="httpConfig" /></Arg>
                <Arg name="compliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"><Arg><Property name="jetty.http.compliance" default="RFC7230"/></Arg></Call></Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="host"><Property name="jetty.http.host" deprecated="jetty.host" /></Set>
        <Set name="port"><Property name="jetty.http.port" deprecated="jetty.port" default="8080" /></Set>
        <Set name="idleTimeout"><Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/></Set>
        <Set name="soLingerTime"><Property name="jetty.http.soLingerTime" deprecated="http.soLingerTime" default="-1"/></Set>
        <Set name="acceptorPriorityDelta"><Property name="jetty.http.acceptorPriorityDelta" deprecated="http.acceptorPriorityDelta" default="0"/></Set>
        <Set name="acceptQueueSize"><Property name="jetty.http.acceptQueueSize" deprecated="http.acceptQueueSize" default="0"/></Set>
      </New>
    </Arg>
  </Call>

</Configure>

总结:在我们执行命令的时候输入的参数,这时候属于第一层参数,然后到项目里面(demo-base), 看项目里面,这时候属于第二层,如果命令行没有执行,但是项目里面有。就相当于读项目里面的配置。如果项目里面没有,那么再找模块里面的。如果模块里面没有就要到jetty-http.xml读取default值(默认值)。

模块相关配置—JVM.mod

具体到哪一个模块进行配置


[ini-template]
## JVM Configuration
## If JVM args are include in an ini file then --exec is needed
## to start a new JVM from start.jar with the extra args.
##
## If you wish to avoid an extra JVM running, place JVM args
## on the normal command line and do not use --exec
# --exec
# -Xmx2000m
# -Xmn512m
# -XX:+UseConcMarkSweepGC
# -XX:ParallelCMSThreads=2
# -XX:+CMSClassUnloadingEnabled
# -XX:+UseCMSCompactAtFullCollection
# -XX:CMSInitiatingOccupancyFraction=80
# -verbose:gc
# -XX:+PrintGCDateStamps
# -XX:+PrintGCTimeStamps
# -XX:+PrintGCDetails
# -XX:+PrintTenuringDistribution
# -XX:+PrintCommandLineFlags
# -XX:+DisableExplicitGC

模块相关配置—http.mod

​ 也就是说在初始化模块的时候需要读取哪些信息,比如端口号,在前面start.ini中读取不到的话就得去http.mod中的信息,如果这个读取不到就通过etc下面的http.xml进行读取。所以初始化配置信息是有一定顺序的,一般修改模块信息的时候不会在下面的文件中直接修改,而是最多是把这些模块复制一下,然后用demo-base的start.d下面的.ini文件进行相关修改。


#
# Jetty HTTP Connector
#

[depend]
server

[xml]
etc/jetty-http.xml

[ini-template]
### HTTP Connector Configuration

## Connector host/address to bind to
# jetty.http.host=0.0.0.0

## Connector port to listen on
# jetty.http.port=8080

## Connector idle timeout in milliseconds
# jetty.http.idleTimeout=30000

## Connector socket linger time in seconds (-1 to disable)
# jetty.http.soLingerTime=-1

## Number of acceptors (-1 picks default based on number of cores)
# jetty.http.acceptors=-1

## Number of selectors (-1 picks default based on number of cores)
# jetty.http.selectors=-1

## ServerSocketChannel backlog (0 picks platform default)
# jetty.http.acceptorQueueSize=0

## Thread priority delta to give to acceptor threads
# jetty.http.acceptorPriorityDelta=0

## HTTP Compliance: RFC7230, RFC2616, LEGACY
# jetty.http.compliance=RFC7230
单体应用架构

程序员本想做百分之一的改动,但是却需要百分之九十九的改动来配合它,显然是不合理的。

jetty学习笔记(一)

微服务架构

同样是一个应用,但是把这个应用拆分成不同的服务,需要哪个服务就修改哪个服务,其他的服务不需要全部迎合当前修改服务的改变,避免了不必要的修改。

jetty学习笔记(一)

jetty的微服务架构是如何体现的

进入demo-base这个文件夹,在终端输入命令java -jar ../start.jar —help 终端会输出一些信息,找到Module Management如下所示:

jetty学习笔记(一)

这些信息包括

List-modules :用来查看所有的ini文件是否使用属性启用哪些模块,如果使用了会在这里看到。在终端输入java -jar ../start.jar --list-modules 会查看到这些module的信息。这些内容都是应用依赖的所有的模块,描述信息的。

如何禁用websocket

在demo-base中的start.ini文件中,把module-socket注释掉(本行最前面加上#)。

禁用后再次输入java -jar ../start.jar --list-modules 就会发现输出信息的最下方的websocket消失了。