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的基本架构
与tomcat的对比
jetty比较容易贴合第三方框架,比如你可以直接用Spring配置一个jetty服务器
直接将jetty作为提供HTTP服务的组件,嵌入到应用中
jetty是面向Handler的架构,而tomcat是面向容器的架构
jetty默认采用NIO技术,而tomcat默认是BIO
jetty高度模块化,可以很灵活的管理拓展组件,而tomcat对其他组件的管理则相对困难
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。如下图所示。
我们可以发现,如果把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通过利用配置文件,帮助我们对对象进行管理。
<!-- =============================================================== -->
<!-- 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的微服务架构是如何体现的
进入demo-base这个文件夹,在终端输入命令java -jar ../start.jar —help 终端会输出一些信息,找到Module Management如下所示:
这些信息包括
List-modules :用来查看所有的ini文件是否使用属性启用哪些模块,如果使用了会在这里看到。在终端输入java -jar ../start.jar --list-modules 会查看到这些module的信息。这些内容都是应用依赖的所有的模块,描述信息的。
如何禁用websocket
在demo-base中的start.ini文件中,把module-socket注释掉(本行最前面加上#)。
禁用后再次输入java -jar ../start.jar --list-modules 就会发现输出信息的最下方的websocket消失了。