Jetty 源码分析
jettyhttpclient实现分析
背景谈到http client,可能大多数想到就是apache的那个http client 或者jdk自带的urlconnection,也许有人会考虑使用netty,无论如何,jetty的高性能实现总归是让人感到好奇,接下来我们一探究竟样例我们结合样例代码具体分析l 初始化l 运行代码分为两段l 初始化:设置httpclientl 运行:实例化ContentExchange,定义callback,本例定义了两个常用的callback:onResponseComplete 和 onExpire 更多的callbac可参考官方文档/Jetty/Tutorial/HttpClientl APP在调用httpClient.send(exchange);后不会象往常一样等待返回而是立即返回, 如果有结果或者超时会通过上面的callback通知到APP httpclient的原理及实现1 )httpclient的模型lSelectConnector: 作为一个connection管理器,封装了selector和connection lHttpDestination:一个host的抽象一个HttpClient会连接到多个HttpDestination lHttpExchange:一次http请求的封装,一个HttpDestination会有多个HttpExchange以及多个AsyncHttpConnection lAsyncHttpConnection:HttpClient对某个HttpDestination的一个网络连接,底层包含一个对应的socket, 可复用来完成多次请求, 如果空闲太久会被废弃lSelectChannelEndPoint:socket的封装,AsyncHttpConnection和SelectChannelEndPoint一一对应, 但AsyncHttpConnection承载了更多的东西lHttpGenerator:生成http request,在jetty server中负责生成http response lHttpParser: 解析http response, 在jetty server中负责解析http request lThreadPool: 线程池,httpclient需要使用线程池配合完成无阻塞IO,这个会在后面的httpclient整体架构分析中详述l Timeout:一个已时间排序的链表结构,链表中存储需要过期执行的task,这个会在后面流程分析详述2)httpclient的整体架构http client 分为3组线程配合完成lselector线程组:数目可设置,默认为1,从_change队列中获取socket注册并扫描操作系统级别的网络事件, 通常是socket 可读, 可写的信息,一旦发现有socket可读写,会将相关socket任务丢入_jobs队列供worker线程执行l worker线程组:数目根据并发的情况决定,从_jobs队列获取任务,如果任务阻塞会丢入_changes队列异步等待通知再干活l tick线程:数目1个,专门用于监控超时的请求以及空闲太久的连接l 所有的线程都来自线程池,所以线程池最小为3,否则无法work 3)典型的场景分析模拟一次请求3.1 )httpclient初始化l1-2设置两个超时链表,一个是超时请求链表,一个是超时连接链表l3 启动httpbuffer l4 启动线程池l5 启动SelectConnector,此时会启动selector线程任务l6 启动tick线程任务3.2)jetty http client runtime3.2.1)httpClient.send(exchange)到底干了什么l1-2正如样例代码所示,APP设置HttpExchange,然后httpclient的send方法l2.1-2.2 httpclient根据httpexchange获取对应http destination,并调用其send方法l2.2.1 将次请求加入请求超时链表l2.2.2 -2.2.3 获取空闲连接,如果没有,则产生一个新的连接,并调用select进行注册,否则直接使用该连接, 并将此连接丢入 _jobs队列让worker线程完成 请求l 此时客户端就这样无阻塞的完成了3.2.2)select线程如何参与这个场景l1-3 selector线程从_change队列获取到新的socket, 开始实例化SelectChannelEndPoint l4 通知http desination连接完成,于是http detination将次连接丢入连接超时链表l 5-6 将此连接/请求丢入_jobs队列供worker线程使用3.2.3)worker线程又如何参与这个场景lworker线程从队列中获取任务l1.1 通过此连接发送请求,请求内容http generator产生l1.2 一发完请求立即通过http parser读取响应,如果服务器够快,通常会读到响应l1.3 如果服务器不能及时响应,那么调用SelectChannelEndPoint的updateKey。
activiti源码分析(一)设计模式
activiti源码分析(⼀)设计模式 对activiti有基本了解的朋友都知道,activiti暴露了七个接⼝来提供⼯作流的相关服务,这些接⼝具体是如何实现的呢?查看源码发现其实现的形式⼤体如下: public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {public ProcessInstance startProcessInstanceByKey(String processDefinitionKey) {return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, null, null));}public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey) {return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, businessKey, null));}...} service中的⼤部分⽅法都是通过调⽤commandExecutor.execute()完成的,然⽽点进去看则会发现什么都没有:public class CommandExecutorImpl implements CommandExecutor {private final CommandConfig defaultConfig;private final CommandInterceptor first;public CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {this.defaultConfig = defaultConfig;this.first = first;}public CommandInterceptor getFirst() {return first;}@Overridepublic CommandConfig getDefaultConfig() {return defaultConfig;}@Overridepublic <T> T execute(Command<T> command) {return execute(defaultConfig, command);}@Overridepublic <T> T execute(CommandConfig config, Command<T> command) {return first.execute(config, command);}} 看到这⾥就会发现并不能看出这条语句究竟做了什么,那么究竟是如何提供服务的呢?其实activiti中⼤部分操作都是基于设计模式中的命令模式完成的(这⾥还使⽤了职责链模式,构造了命令拦截器链,⽤于在命令真正被执⾏之前做⼀系列操作)。
SpringBoot内置Tomcat启动原理源码分析
SpringBoot内置Tomcat启动原理源码分析1、获取SpringBoot内置Tomcat⾃动配置类: 在SpringBoot项⽬中引⼊spring-boot-starter-web依赖,就默认使⽤Tomcat容器,该依赖中引⼊spring-boot-starter-tomcat、spring-webmvc,就引⼊了tomtcat核⼼依赖和springMvc相关jar包,这样就间接地引⼊了tomcat。
在执⾏SpringBoot项⽬启动类的main()⽅法,启动SpringBoot项⽬的过程中会加载各个jar包下META-INF/spring.factories的⽂件,在该⽂件中包含着⾃动配置的⼦路径,在refresh()⽅法中的invokeBeanFactoryPostProcessors()中⾸先会对启动类上的 @SpringBootApplication 注解进⾏解析,最终调⽤ AutoConfigurationImportSelector类中的 getAutoConfigurationEntry() 加载 META-INF/spring.factories ⽂件中的⾃动配置类,得到⾃动配置类的全路径,其中 org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration 为tomcat⾃动配置类。
具体加载流程见:protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata);// 1、得到META-INF/spring.factories⽂件中配置的所有⾃动配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 移除重复的配置类configurations = removeDuplicates(configurations);// 获取需要排除的⾃动配置类,eg:注解属性中的exculde的配置类Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 检查需要被排除的配置类,因为有些不是⾃动配置类,需要抛异常checkExcludedClasses(configurations, exclusions);// 移除需要排除的配置类configurations.removeAll(exclusions);// 根据 META-INF/spring-autoconfigure-metadata.properties 中配置的规则过虑掉⼀部分配置类(根据@ConditionalOnXXX注解进⾏过滤)configurations = getConfigurationClassFilter().filter(configurations);// 获取符合条件的配置类后,触发 AutoConfigurationImportEvent 事件fireAutoConfigurationImportEvents(configurations, exclusions);// 将符合条件和需要排除的配置类封装进 AutoConfigurationEntry 对象中返回return new AutoConfigurationEntry(configurations, exclusions);}2、ServletWebServerFactoryAutoConfiguration - tomcat⾃动配置类分析3、创建tomcat⼯⼚@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)static class EmbeddedTomcat {@BeanTomcatServletWebServerFactory tomcatServletWebServerFactory(ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,ObjectProvider<TomcatContextCustomizer> contextCustomizers,ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {// 创建⽣产tomcat的⼯⼚TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().collect(Collectors.toList()));factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().collect(Collectors.toList()));factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList()));return factory;}} 4、创建tomcat容器 在SpringBoot启动过程中会调⽤ AbstractApplicationContext.refresh() ⽅法,在该⽅法会调⽤onRefresh()⽅法,这个⽅法是个模板⽅法,最终会交给⼦类实现,在使⽤内置tomcat的SpringBoot项⽬中,最终会调⽤ ServletWebServerApplicationContext 实现(AbstractApplicationContext是GenericWebApplicationContext,ServletWebServerApplicationContext 是GenericWebApplicationContext),最终调⽤ServletWebServerApplicationContext 的createWebServer()⽅法创建 webServer。
Jetty的基本架构
Jetty的基本架构Jetty 的基本架构Jetty 目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器,它有一个基本数据模型,这个数据模型就是Handler,所有可以被扩展的组件都可以作为一个Handler,添加到Server 中,Jetty 就是帮你管理这些Handler。
Jetty 的基本架构下图是 Jetty 的基本架构图,整个 Jetty 的核心组件由 Server 和Connector 两个组件构成,整个 Server 组件是基于 Handler 容器工作的,它类似与 Tomcat 的 Container 容器,Jetty 与 T omcat 的比较在后面详细介绍。
Jetty 中另外一个比不可少的组件是 Connector,它负责接受客户端的连接请求,并将请求分配给一个处理队列去执行。
图 1. Jetty 的基本架构Jetty 中还有一些可有可无的组件,我们可以在它上做扩展。
如JMX,我们可以定义一些 Mbean 把它加到 Server 中,当 Server 启动的时候,这些 Bean 就会一起工作。
图 2. Jetty 的主要组件的类图从上图可以看出整个Jetty 的核心是围绕着Server 类来构建,Server 类继承了Handler,关联了Connector 和Container。
Container 是管理 Mbean 的容器。
Jetty 的 Server 的扩展主要是实现一个个 Handler 并将 Handler 加到 Server 中,Server 中提供了调用这些 Handler 的访问规则。
整个 Jetty 的所有组件的生命周期管理是基于观察者模板设计,它和 Tomcat 的管理是类似的。
下面是 LifeCycle 的类关系图每个组件都会持有一个观察者(在这里是Listener 类,这个类通常对应到观察者模式中常用的Observer 角色,关于观察者模式可以参考《Tomcat系统架构与设计模式,第2部分:设计模式分析》一文中关于观察者模式的讲解)集合,当 start、fail 或 stop 等事件触发时,这些Listener 将会被调用,这是最简单的一种设计方式,相比Tomcat 的 LifeCycle 要简单的多。
jetty的工作原理以及与tomcat的比较
Jetty 的工作原理以及与Tomcat 的比较与Tomcat 的比较总结大概如下:tomcat适合处理少量但是业务非常繁忙的服务比如应用平台,jetty适合做大量而且可以上时间保存的连接服务,如web服务,jetty体积小只有几百k Tomcat 和Jetty 都是作为一个Servlet 引擎应用的比较广泛,可以将它们比作为中国与美国的关系,虽然Jetty 正常成长为一个优秀的Servlet 引擎,但是目前的Tomcat 的地位仍然难以撼动。
相比较来看,它们都有各自的优点与缺点。
Tomcat 经过长时间的发展,它已经广泛的被市场接受和认可,相对Jetty 来说Tomcat 还是比较稳定和成熟,尤其在企业级应用方面,Tomcat 仍然是第一选择。
但是随着Jetty 的发展,Jetty 的市场份额也在不断提高,至于原因就要归功与Jetty 的很多优点了,而这些优点也是因为Jetty 在技术上的优势体现出来的。
架构比较从架构上来说,显然Jetty 比Tomcat 更加简单,如果你对Tomcat 的架构还不是很了解的话,建议你先看一下《Tomcat系统架构与设计模式》这篇文章。
Jetty 的架构从前面的分析可知,它的所有组件都是基于Handler 来实现,当然它也支持JMX。
但是主要的功能扩展都可以用Handler 来实现。
可以说Jetty 是面向Handler 的架构,就像Spring 是面向Bean 的架构,iBATIS 是面向statement 一样,而Tomcat 是以多级容器构建起来的,它们的架构设计必然都有一个“元神”,所有以这个“元神“构建的其它组件都是肉身。
从设计模板角度来看Handler 的设计实际上就是一个责任链模式,接口类HandlerCollection 可以帮助开发者构建一个链,而另一个接口类ScopeHandler 可以帮助你控制这个链的访问顺序。
另外一个用到的设计模板就是观察者模式,用这个设计模式控制了整个Jetty 的生命周期,只要继承了LifeCycle 接口,你的对象就可以交给Jetty 来统一管理了。
《Jetty6_指南书》
前言和目录写在前面:使用jetty已经很久了,它是一个很出色的web容器和工具,特在此和大家分享jetty6的知识。
网络上有一些关于jetty的资料,但过去陈旧且不具有系统性,导致很多人误解jetty的功能,国外目前也没有关于jetty的书籍,所以那些搞翻译的人也没有翻译来源,故决定写一本关于jetty6 的书,以推广jetty在国内的使用。
记住jetty不仅仅是一个web容器!版权声明:这一系列章节只在javaeye的博客发表,谢绝任何组织和个人的转载或抄袭!本人保留所有权利!如侵犯本版权则需赔偿人民币5000000圆整,因为劳动是无价的,这算便宜的了!作者:陈汝烨由于这一些系列文章正在编写过程中,写好一章就发一章,难免有很多错误的地方,欢迎哥们指正!关键字: jetty是什么 jetty配置 jetty使用 jetty嵌入 jetty启动 jetty部署 jetty教程 jetty嵌入式 jetty第1章Jetty介绍1.1 Jetty功能介绍1.2 Jetty的特点1.3 jetty项目历史和现状1.4 jetty vs tomcat1.5 本章小结2.1 下载2.2 安装2.3 使用java命令启动2.3.1 快速启动2.3.2 停止服务2.3.3 start.jar深入探讨2.4我们可以学到什么2.5 Windows系统下启动和关闭控制2.6 Linux系统下启动和关闭控制2.6.1 系统变量的设置2.6.2 命令参数2.6.3 相关配置文件2.7本章小结3.1 构架概述3.2 Connector3.3 Handler3.4 Server 和ThreadPool3.5 目录结构第4章Jetty服务配置文件4.1 jetty.xml 示例剖析4.2 Jetty xml Configuration语法4.3 org.mortbay.xml.XmlConfiguration 第5章在Jetty中部署Web应用程序相关的配置文件静态部署动态热部署Servlet2.5 新特性第6章Handler详细本章相信介绍各种Handler的功能和用法第7章类加载器第8章Jetty ConnectorSSL的配置,和apache mod_proxy,ajp部署9虚拟主机讲解Jetty下虚拟主机的配置方法10管理服务器服务器日志管理,请求日志,实时状态,关闭服务器,JMX管理 linux 非root用户在80端口启动11配置JNDI介绍jndi如何使用、12会话与集群13性能优化线程池,内存大小配置,共享libGZIPOptimizing with Last-Modified and Cache-Control Optimizing Browser CachingOptimizing on High Load Serverslinux最大连接数配置linux下epull启用配置14异步Servlet,AJax,Comet15Embedding Jetty16 JEE服务器整合17 在开发环境中使用Jetty18 安全19 FAQJetty6 指南书 - 第一章 Jetty介绍文章分类:Java编程写在前面:使用jetty已经很久了,它是一个很出色的web容器和工具,特在此和大家分享jetty6的知识。
Jetspeed (开源Portal)系统及源代码分析
Jetspeed 系统及源代码分析技术研究四室2003-5-18目录JETSPEED 系统及源代码分析 (1)序言 (5)1.1简介 (7)1.2代码目录介绍 (8)1.3安装运行 (9)1.4配置文件 (10)1.4.1Properties文件 (10)1.4.2Xreg文件 (10)1.5主要概念 (12)1.5.1页面组件(modules) (12)1.5.2服务(service) (13)1.5.3模板(templates) (14)1.5.4对象关系模型(om) (14)1.5.5Portlet & Portal (14)1.6系统结构 (15)1.7P ORTAL S ERVLET及系统主要流程 (18)1.7.1初始化 (18)1.7.2RunData数据结构 (18)1.7.3处理请求 (20)1.7.4页面生成 (21)1.7.5事件处理流程 (25)1.7.6Session Validator处理流程 (26)1.8M ODULES (27)1.8.1Action (27)1.8.2Page (27)1.8.3Layout (27)1.8.4Screen (27)1.8.5Navigation (28)1.11J ETSPEED T AG L IB (31)1.12R EGISTRY (33)1.13P ORTAL &P ORTLET (36)1.14用户管理及访问控制 (38)1.15S ERVICES (39)1.15.1TurbineService (39)1.15.2AssemblerBrokerService (39)1.15.3GlobalCacheService (40)1.15.4CastorService (41)1.15.5ComponentService (42)1.15.6DB Service (43)1.15.7FactoryService (43)1.15.8FreeMarkerService (45)1.15.9IntakeService (46)1.15.10JspService (46)1.15.11LocalizationService (47)1.15.12LoggingService (47)1.15.13MimeTypeService (48)1.15.14NamingService (49)1.15.15PoolService (49)1.15.16ProfileService (50)1.15.17PsmlManagerService (50)1.15.18PullService (51)1.15.19ResourceService (51)1.15.20RegistryService (51)1.15.21RunDataService (51)1.15.22ScheduleService (54)1.15.23SecurityService (54)1.15.26UniqueIdService (56)1.15.27UploadService (56)1.15.28VelocityService (57)1.15.29WebMacroService (58)1.15.30XmlRpcService (59)1.15.31XSLTService (62)1.16自主化个性门户的实现 (63)1.16.1需要实现怎样一个自主化的个性门户 (63)1.16.2需要对Jetspeed的修改完善之处 (63)1.16.3考虑自己重新实现的可行性 (65)1.17附录 (66)1.17.1Turbine.init (66)1.17.2Turbine.doGet (67)1.17.3JetspeedSessionValidator (71)1.17.4DefaultPage.doBuilde (73)1.17.5JetspeedPanTag (74)1.17.6JetspeedToolkitService.getSet (75)1.17.7PortletSet.getContent (77)1.18后序 (79)序言随着Portal的应用越来越广泛,人们对Portal的由来与开发也变得越来越感兴趣。
天移系统源码
天移系统源码天移系统是一款基于Java平台开发的网络文件传输系统。
该系统能够快速地传输大量的文件,具有高效、安全、稳定等优点,受到广大用户的欢迎。
本文将对天移系统的源码进行分析,探究其优势和使用方法,为读者提供有指导意义的参考。
首先,我们来看一下天移系统的源码结构。
该系统的主要代码分为两个模块,分别是服务端和客户端。
服务端代码主要包括文件上传、下载、管理等功能,而客户端代码则负责与服务端进行通信,实现文件传输和控制等操作。
服务端主要由两个类组成,分别是FileServer和FileHandler。
FileServer是服务器的主类,负责启动服务端和与客户端建立连接。
而FileHandler则是服务端的核心处理类,负责具体的文件传输和管理操作。
在客户端代码中,主要有两个类,分别是FileClient和FileSender。
FileClient是客户端的主类,会向服务端发出请求并接收响应结果。
而FileSender则是文件传输的核心类,负责将文件分块并按顺序发送到服务端。
客户端还包括文件下载的功能,由文件下载类FileDownloader实现。
其次,天移系统的优势在于高效、安全、稳定等方面。
首先,该系统采用多线程方式实现,能够在传输大量文件时提高传输速度;其次,系统的设计考虑到了文件传输的安全性,加入了MD5校验码等机制,确保文件传输的完整性和准确性;最后,系统稳定性高,即使传输大量文件时也不会出现卡顿、崩溃等问题。
最后,我们还需要掌握天移系统的使用方法。
在使用之前,需要先启动服务端。
可以将服务端代码打包成jar包,然后在命令行中运行java -jar xxx.jar来启动。
服务端启动后,客户端就可以与其建立连接,在客户端中输入相应的命令来实现上传、下载等操作。
总之,天移系统是一款优秀的网络文件传输系统,其源码结构合理、优势明显、使用方便,可以满足大家在文件传输方面的需求。
读者们可以通过仔细阅读本文和相关资料,进一步掌握该系统的使用方法和开发技巧。
Jetty6架构分析
Jetty6架构概括:Jetty Server是由一组接受http连接的Connectors和一组处理来自连接的请求并响应的Handlers构组件就是简单的POJO,这种组件的配置可以通过多种技术实现:·在代码中实现,可以查看org.mortbay.jetty.example包中的例子。
·使用jetty.xml-xml格式的依赖注入风格。
·使用依赖注入框架:Spring或Xbean。
·使用Deployers:WebAppDeployer,ContextDeployer。
模式Jetty的实现遵循一些标准的模式,大部分的抽象概念通过接口捕获的,比如Connector,Handler,Buffer。
这些接口的通用处理通过抽象类来实现,比如:AbstractConnector,AbstractHandler和AbstractBuffer。
从JSR77的生命周期得到灵感,大部分的Jetty组件是通过LifeCycle接口呈现的,其抽象实现(AbstractLifeCycle)是大部分Jetty组件的基础。
Jetty提供了自己的简历在String,byte数组和nio缓冲之上的IObuffer的抽象。
这样得到更好的可移植性,并且也隐藏了一些nio层和它的高级特性的复杂性。
ConnectorsConnectors进行协议的处理:接受连接,分析请求,生成响应。
基于使用的协议,调度模型,io api 的不同,有多种可用的connector:·SocketConnector——用于繁忙的连接或是nio不可用的场合·BlockingChannelConnector——用于繁忙的连接,并且nio可用·SelectChannelConnector——用于大部分时间空闲的连接或者ajax请求的异步处理·SslSocketConnector——SSL,并且nio不可用·SslSelectChannelConnector——SSL,并且支持非阻塞的nio·AJPConnector——AJP协议支持,用于来自apache mod_jk or mod_proxy_ajp的连接HandlersHandler是用来处理接收到的请求的组件。
Jetty源码阅读笔记
setServersetServer 最终将本身对象保存到Server 的父类AbstractHandler 中。
Connector 构造Jetty Connector 用于接收客户端连接,我们可以添加多个Connector ,比如一个用于接收http 连接,一个接收https 连接,这样可以实现一个jetty 用于多个服务。
ServerConnector 构造器AbstractConnector 构造器public Server (@Name ("port")int port ) {this ((ThreadPool )null );ServerConnector connector =new ServerConnector (this ); connector .setPort (port );setConnectors (new Connector []{connector });}public ServerConnector (@Name ("server") Server server ) {this (server ,null ,null ,null ,‐1,‐1,new HttpConnectionFactory ()); }public ServerConnector (@Name ("server") Server server , @Name ("executor") Executor executor , @Name ("scheduler") Scheduler scheduler , @Name ("bufferPool") ByteBufferPool bufferPool , @Name ("acceptors") int acceptors , @Name ("selectors") int selectors ,@Name ("factories") ConnectionFactory ... factories ) {super (server ,executor ,scheduler ,bufferPool ,acceptors ,factories ); _manager = new ServerConnectorManager (getExecutor (), getScheduler (), selectors >0?selectors :Math .max (1,Math .min (4,Runtime .getRuntime ().availableProcessors ()/2))); addBean (_manager , true ); }ServerConnectorManager(_manager)初始化ServerConnectorManager 为ServerConnector 的内部类public AbstractConnector (Server server , Executor executor , Scheduler scheduler , ByteBufferPool pool , int acceptors ,ConnectionFactory ... factories ) {_server =server ;//默认使用Server 的线程池,也就是QueuedThreadPool_executor =executor !=null ?executor :_server .getThreadPool (); if (scheduler ==null )scheduler =_server .getBean (Scheduler .class ); //默认为空_scheduler =scheduler !=null ?scheduler :new ScheduledExecutorScheduler (); if (pool ==null )pool =_server .getBean (ByteBufferPool .class ); //默认为空_byteBufferPool = pool !=null ?pool :new ArrayByteBufferPool (); //Connector 也实现了Container 接口 addBean (_server ,false ); addBean (_executor ); if (executor ==null )unmanage (_executor ); // inherited from server addBean (_scheduler ); addBean (_byteBufferPool );for (ConnectionFactory factory :factories ) //mapaddConnectionFactory (factory );int cores = Runtime .getRuntime ().availableProcessors (); //‐1if (acceptors < 0)acceptors =Math .max (1, Math .min (4,cores /8)); if (acceptors > cores )LOG .warn ("Acceptors should be <= availableProcessors: " + this ); _acceptors = new Thread [acceptors ]; }设置handler源码(HandlerWrapper.setHandler)如下:可见,每一个handler 都保有Server 的引用。
Jetty源码分析(一)
Jetty源码分析(⼀)⼀、⽬的 1、了解jetty组成架构; 2、学习jetty启动过程; 3、学习请求访问过程; 4、学习jetty内各模块作⽤,学习各模块内部代码;⼆、jetty版本 本⽂所学习的jetty版本为:9.2.19.v20160908三、正⽂ 第⼀节,Server的架构图及相关类分析。
在jetty中,Server类是最核⼼的类,系统启动始于Server类,启动的同时注册了ShutdownHuk事件。
Server架构图如下: 由上图可见,在Jetty中,和Server关系最为紧密的类有Handler,LifeCycle和Container三个接⼝。
1、LifeCycle:是⼀个通⽤的组件。
实现这个接⼝的类必须实现这个接⼝定义的有关⽣命周期的⽅法。
主要包含以下⼏个和⽣命周期相关的⽅法,及由相关时间出发的监听器:public void start() throws Exception;public void stop() throws Exception;public boolean isRunning();public boolean isStarted();public boolean isStarting();public boolean isStopping();public boolean isStopped();public boolean isFailed();public void addLifeCycleListener(LifeCycle.Listener listener);public void removeLifeCycleListener(LifeCycle.Listener listener);/* ------------------------------------------------------------ *//** Listener.* A listener for Lifecycle events.*/public interface Listener extends EventListener{public void lifeCycleStarting(LifeCycle event);public void lifeCycleStarted(LifeCycle event);public void lifeCycleFailure(LifeCycle event,Throwable cause);public void lifeCycleStopping(LifeCycle event);public void lifeCycleStopped(LifeCycle event);} 2、Handler:Server的处理器,也是包含⽣命周期的逻辑,因此继承了LifeCycle接⼝。
Jetty源代码分析
彭瑞刚 2010/12/30
Jetty版本:7.1.5.v20100705 代码规模:包括单元测试类, 共77万行代 码, 总文件数:2800多个,算是一个比较 大的系统了。
包括测试工程,总共约有30多个工程。
1. 2. 3. 4. 5.
6.
7.
8.
9.
Main start.jar指定的启动类,Jetty启动的入口 XmlConfiguration 配置文件解析 Server类—核心控制类, 主要负责初始化及启动容器. Connector 负责连接的处理, 并调用Handler处理请求. ThreadPool Jetty自己的线程池, 后续的请求都是由其中的 某个线程调度执行. Acceptor 独立的Accept线程, 调用SelectManager类,实现请 求\读写事件的处理 SelectChannelEndPoint 由SelectorManager调度,是handlers 的起点,它负责调用HttpConnection. HttpConnection负责Http请求的具体处理,由他调用相关 的类执行HTTP解析,请求/响应数据的构造处理等. ContextHandlerCollection负责调用后续的handler链.
。
jetty.xml解析
jetty.xml解析我们知道jetty有⼀种启动⽅式是在jetty的根⽬录中运⾏命令⾏:java -jar start.jar,这个命令会调⽤apache的XmlConfiguration⼯具类作为启动类,这个类会默认读取/etc/jetty.xml⽂件,加载jetty启动所必须的配置。
接下来分段研究:<Configure id="Server" class="org.eclipse.jetty.server.Server">这段配置是整个配置⽂件的root元素,它其实是调⽤org.eclipse.jetty.server类的默认构造函数来创建⼀个server对象,对应源码:public Server(){this((ThreadPool)null);}创建了⼀个空的server,那么接下来就是为这个server设置各种对象及属性了。
继续看:<Set name="ThreadPool"><New class="org.eclipse.jetty.util.thread.QueuedThreadPool"><Set name="minThreads">100</Set><Set name="maxThreads">1000</Set><Set name="SpawnOrShrinkAt">2</Set></New></Set>这段配置是为当前server设置线程池,从xml元素也可以看出来它其实是调⽤server的SetThreadPool⽅法:server.setThreadPool(threadPool);然后new了⼀个org.eclipse.jetty.util.thread.QueuedThreadPool对象,并设置它的最⼩线程数、最⼤线程数以及最多有多少task可以暂时放到队列⾥待会执⾏,还有其他很多参数具体场景可能需要不同的配置。
Jetty服务配置文件
Jetty服务配置文件首先让我们回顾一下jetty的启动。
命令“ java -jar start.jaretc/jetty.xml” 中指定的文件 etc/jetty.xml 就是我们本章讨论的主要对象,我们称这种文件叫“服务配置文件”。
下文中有时候我们说jetty.xml配置文件并不是特指这个文件而是通指“服务配置文件”。
Jetty其实提供一个IOC/DI(反转控制和依赖注射)容器,jetty.xml配置文件就是这个容器的配置文件,和Jetty本身服务没有直接关系,你甚至可以独立使用该组件。
由次可见Jetty组件化设计发挥到了极致,组件之间也没有多少依赖性。
相信熟悉springframework的朋友都知道它是 IOC领域的佼佼者之一。
有趣的是虽然Jetty的IOC容器实现只是在内部使用,但它却是在springframework之前就存在了。
Jetty的IOC容器实现代码非常少,只涉及到两个类:∙org.mortbay.xml.XmlConfiguration∙org.mortbay.xml.XmlParser其本质是解析服务配置文件的组件为我们提供一个动态调用Java代码的工具,Jetty利用这个工具实现所谓的IOC容器配置Server对象和相关组件。
如果我们手写这些jetty.xml配置对应的Java代码的话,其实就是嵌入式使用Jetty的方法,这里也体现了Jetty设计精妙之处。
在本章节中我们先展示下Jetty默认的jetty.xml文件,让大家对它有关大概的了解;然后详细介绍jetty xml Configuration的语法;最后我们使用org.mortbay.xml.XmlConfiguration编写写测试用例来更深入的了解jetty.xml和jetty启动配置过程。
4.1 jetty.xml 示例剖析<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "/configure.dtd"><!-- 配置Server对象,此时会调用org.mortbay.jetty.Server默认构造函数new一个Server --><Configure id="Server" class="org.mortbay.jetty.Server"><!-- =========================================================== --><!-- 配置线程池 --><!-- =========================================================== --><!-- 调用当前Server对象的setThreadPool方法 --><Set name="ThreadPool"><!-- new一个ThreadPool对象,作为setThreadPool方法的参数 --> <New class="org.mortbay.thread.concurrent.ThreadPool"><!-- 设置线程池核心线程数大小 --><Set name="corePoolSize">50</Set><!-- 设置线程池最大线程数 --><Set name="maximumPoolSize">50</Set></New></Set><!-- =========================================================== --><!-- 注册connectors --><!-- =========================================================== --><!-- 调用当前Server对象的addConnector方法 --><Call name="addConnector"><Arg> <!--Arg 标签表示addConnector方法的参数列表--><!--new一个SelectChannelConnector对象--><New class="org.mortbay.jetty.nio.SelectChannelConnector"><!--调用当前SelectChannelConnector对象的setHost方法, host表示Connector需要监听的IP地址或者hostname, SystemProperty标签用来获取Java系统变量。
jetty原理
jetty原理Jetty原理Jetty是一个基于Java的Web服务器和Servlet容器,它是开源的并且是一个轻量级的服务器。
Jetty提供了高性能、低延迟、异步处理请求和响应的能力,可以作为独立的Web服务器使用,也可以作为Servlet容器嵌入到其他应用程序中使用。
本文将介绍Jetty的原理。
一、Jetty架构Jetty架构分为三层:底层I/O、Servlet API和Web应用程序。
1. 底层I/O层底层I/O层实现了HTTP请求和响应的读取和写入,包括TCP/IP连接管理、缓冲区管理、线程池等。
在这一层中,Jetty使用了Java NIO (非阻塞I/O)技术来实现异步处理请求和响应。
2. Servlet API层Servlet API层实现了Servlet规范中定义的接口,包括HttpServletRequest、HttpServletResponse、ServletContext等。
在这一层中,Jetty通过实现Servlet规范来提供对Web应用程序的支持。
3. Web应用程序层Web应用程序层包含了Web应用程序本身以及相关资源文件,如HTML文件、JSP文件、CSS文件等。
在这一层中,Jetty会根据配置文件加载相应的Web应用程序,并将请求转发给相应的Servlet进行处理。
二、Jetty工作流程Jetty的工作流程可以分为以下几个步骤:1. 启动Jetty服务器当启动Jetty服务器时,它会读取配置文件,并根据配置文件加载相应的Web应用程序。
2. 接收HTTP请求当客户端发送HTTP请求时,Jetty服务器会接收该请求,并将其封装成HttpServletRequest对象。
3. 处理HTTP请求Jetty服务器会将HttpServletRequest对象传递给相应的Servlet进行处理。
Servlet会根据HttpServletRequest对象中的信息来生成HttpServletResponse对象,并将响应返回给Jetty服务器。
实战Jetty
实战JettyJetty是一个用Java实现、开源、基于标准的,并且具有丰富功能的Http服务器和Web 容器,可以免费的用于商业行为。
Jetty 这个项目成立于1995年,现在已经有非常多的成功产品基于Jetty,比如Apache Geromino,JBoss,IBM Tivoli,Cisco SESM 等。
Jetty可以用来作为一个传统的Web服务器,也可以作为一个动态的内容服务器,并且Jetty可以非常容易的嵌入到Java应用程序当中。
易用性易用性是Jetty设计的基本原则,易用性主要体现在以下几个方面:1.通过XML或者API来对Jetty进行配置;2.默认配置可以满足大部分的需求;3.将Jetty嵌入到应用程序当中只需要非常少的代码;可扩展性在使用了Ajax的Web 2.0 的应用程序中,每个连接需要保持更长的时间,这样线程和内存的消耗量会急剧的增加。
这就使得我们担心整个程序会因为单个组件陷入瓶颈而影响整个程序的性能。
但是有了Jetty:1.即使在有大量服务请求的情况下,系统的性能也能保持在一个可以接受的状态。
2.利用Continuation机制来处理大量的用户请求以及时间比较长的连接。
另外Jetty 设计了非常良好的接口,因此在Jetty的某种实现无法满足用户的需要时,用户可以非常方便地对Jetty的某些实现进行修改,使得Jetty适用于特殊的应用程序的需求。
易嵌入性Jetty 设计之初就是作为一个优秀的组件来设计的,这也就意味着Jetty可以非常容易的嵌入到应用程序当中而不需要程序为了使用Jetty 做修改。
从某种程度上,你也可以把Jetty 理解为一个嵌入式的Web服务器。
部署应用程序将自己的应用程序部署到Jetty 上面是非常简单的,首先将开发好的应用程序打成WAR 包放到Jetty 的Webapps 目录下面。
然后用如下的命令来启动Jetty 服务器:Java –jar start.jar,在启动服务器后。
resolveractivity源码解析
【resolveractivity源码解析】1. 背景介绍在Android开发中,resolveractivity是一个常用的类,它用于处理Android系统中的“选择操作”(Intent.createChooser()方法),比如用户在打开某个文件时,系统会弹出一个选择对话框让用户选择要使用的应用程序。
resolveractivity就是负责展示这个选择对话框的类。
2. 源码解析resolveractivity的源码比较复杂,包括了很多涉及到Android系统底层的内容,我们这里主要对resolveractivity的几个重要方法进行简要的解析。
2.1 getIntent()方法在resolveractivity中,getIntent()方法是一个非常重要的方法。
这个方法用于获取启动resolveractivity的Intent,也就是启动选择对话框的Intent。
在这个方法中,resolveractivity会根据系统的设置和用户的选择来确定需要展示哪些应用程序,并将这些信息存储在一个Intent对象中返回。
2.2 onCreate()方法resolveractivity中的onCreate()方法也是一个核心方法。
在这个方法中,resolveractivity会进行一系列的初始化操作,比如设置界面的布局、获取系统的Intent等。
在这个方法中还会注册一些监听器,用于监听用户的选择操作。
2.3 onIntentSelected()方法onIntentSelected()方法是当用户选择了某个应用程序后会被调用的方法。
在这个方法中,resolveractivity会获取到用户选择的应用程序,并且将选择结果返回给启动resolveractivity的Activity。
3. 源码调用流程在理解了resolveractivity的几个重要方法后,我们可以简单地总结一下resolveractivity的源码调用流程。
Jetty使用教程28—Jetty开发指南
Jetty使用教程28—Jetty开发指南二十八、延续机制支持28.1 延续简介延续是一种机制用来实现类似于Servlet 3.0异步功能的异步Servlet,但提供了一个简单易操作的接口。
28.1.1 为什么使用异步Servlets不使用异步IO:异步servlet的概念往往与异步IO或NIO的使用产生混淆。
但是异步Servlets 和异步IO还是有主要不同点:HTTP请求通常很小并且位于一个单独的包,Servlets 很少在请求时阻塞。
许多responses 通常很小并且大小适合server缓冲,所以servlets 通常不会再写入response时堵塞即便我们能在servlet中使用异步IO,那也将时编程变得更加困难。
例如当一个应用程序读到2到3个字节的UTF-8它会怎么做?它不得不缓冲等待更多的字节。
这件事最好由容器来做而不是应用程序。
异步等待:异步servlets 的主要用法是用来等待非IO的事件或资源。
许多web应用程序需要等待处理HTTP请求的各种阶段,例如:处理请求前等待资源可用(例如:thread、JDBC连接)在AJAX Comet应用中等待一个应用程序的事件(例如:聊天消息、价格变动)等待远程服务的一个响应(例如:RESTful 、SOAP )servlet API(2.5之前)仅支持一种同步调用方式,所以servlet 的任何等待都是阻塞式的。
不幸的是,这意味着分配给请求的线程将会在等待所有资源的时候被持有:内核线程、栈存储、缓冲池、字符转换器、EE认真context等等。
保存对这些资源的等待会浪费大量的系统资源。
如果等待是异步进行的,那么可以进行更好的扩展和提高服务质量。
28.1.2 异步Servlets 例子AJAX服务端推送Web 2.0可以使用comet技术(又叫做AJAX推送、服务端推送、长轮询)动态更新一个页面,而不需要刷新整个页面。
考虑一个股票投资的web应用程序。
JettyContinuation实现原理和使用场景分析
JettyContinuation实现原理和使用场景分析Jetty Continuation实现原理和使用场景分析Jetty continuation是什么?简单的说,就是用一个NIO模拟http同步连接。
我们都知道http请求时同步的,就是说http request 发送到server之后,server分配一个单独的线程处理这个请求,请求完成之后再返回response给请求端。
这个过程中server处理线程一般是不释放,即使是什么都没有干。
更关键的是承载http请求的tcp socket是阻塞式的。
显而易见的是如果这个请求时间较长,不但server threads被占用而无法处理新请求,仅仅是并发连接数的问题就让人头疼。
Jetty Continuation翻译一下Jetty Continuation的官方解释:“Continuation是一种可以使HTTP请求可以被暂时挂起,并且当挂起超时或非同步的事件发生时,被挂起的HTTP请求可以被重新恢复的机制”。
这个机制的实现主要在SelectChannelConnector类中。
网上不少朋友都分析了这个实现,Continuation.suspend()会抛出一个特殊的运行时异常:RetryRequest。
这个异常将传播到servlet以外,然后通过过滤器传回,再由SelectChannelConnector捕获,将请求放入处于等待状态的Continuation队列中,此时HTTP连接并不关闭,而当前的线程却可以被放回线程池,供别的请求使用。
我想这里应该被强调的一点就是:Continuation机制实际就是对HTTP协议执行NIO。
简单的看一下代码,这是SelectChannelConnector$RetryContinuation类,resume方法Java代码1.public void resume()2.{3....4.SelectSet selectSet = _endPoint.getSelectSet();5.6.synchronized (selectSet)7.{8.this.cancel();9.}10.11._endPoint.scheduleIdle(); // TODO maybe not needed12.selectSet.addChange(this);13.selectSet.wakeup();14.}15.}可以看到resume()方法调用了selectSet.wakeup(),而SelectSet调用了NIO selector的wakeup方法,Java代码1.public void wakeup()2.{3.Selector selector = _selector;4.if (selector!=null)5.selector.wakeup();6.}基于NIO,Jetty可以在一个非阻塞的socket中处理多个HTTP 请求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Jetty 源码分析在文库看到一个关于jetty源码分析的PDF文档,发现该文档根本不全,遂在网上又找到了关于此文档内容的网站,将其网页内容拷贝了出来,供大家浏览!一、总括你了解Jetty 吗,就像我们所熟知的Tomcat一样, Jetty是一个免费的开放源码的100%纯Java的Http服务器和Servlet容器。
Jetty具备以下特点:快速高效。
Jetty是最快的Servlet服务器之一。
Jetty可以处理上千个并发连接小巧嵌入。
Jetty的jar只有600多K。
可动态嵌入到应用程序,适合开发web2.0等应用应用广泛。
开源项目有Geronimo, JBoss, JOnAS等。
商业项目有IBM Tivoli, Sonic MQ and Cisco SESM等可到Jetty网站 /jetty/查看最新信息本文将通过对Jetty最新稳定版Jetty5.1.5RC2 源码的研究,向读者展示Jetty在设计方面使用的不同设计理念, 希望对广大开发者在设计自己的系统时有所帮助。
Jetty按照功能可以分为四个主个主要的部分,HttpServer, HttpContext,HttpHandler,HttpListener,详见如下类图:<图1-1>二、HttpServer及配置对于初次接触Jetty的人一定会对上图感到迷惑,其实在Jetty中HttpServer是一个服务器的核心控制类, 我们可以看到,其它的组件类都是由该类扩展开来,HttpServer的作用就是在一系列的监听器类和处理器类之间搭起了一个桥梁,有效的控制着消息在系统内的传递,如下图:<图1-2 >HttpServer职责是接受从HttpListener传递过来的request(请求),HttpServer通过对request的Host(主机)或Path(路径)进行匹配,然后分发给相应的HttpContext(可以理解为一个web application)。
这里举个例子,假设我们现在要建立一个提供静态页面web服务,页面内容在c:\root \下,可以通过如此配置HttpServer:HttpServer server = new HttpServer(); // 创建一个新的HttpServerSocketListener listener = new SocketListener(); // 创建一个新监听器listener.setPort(8080);// 设置监听端口为8080server.addListener(listener);// 将监听类注册到server中HttpContext context = new HttpContext(); // 创建一个新HttpContextcontext.setContextPath("/app/*"); // 设置访问路径context.setResourceBase("c:/root/"); // 设置静态资源路径context.addHandler(new ResourceHandler()); // 为这个HttpContext添加一个静态资源处理器server.addContext(context); // 将这个HttpContext注册到server中server.start();// 最后启动这个server当我们要建立一个提供动态页面web服务时, 假设我们自己的web 应用放在Jetty目录下的webapps下并打好包文件名为myapp.war, 可以通过如此配置HttpServer:Server server = new Server(); // 创建一个新的HttpServerSocketListener listener = new SocketListener();// 创建一个新监听器listener.setPort(8080); // 设置监听端口为8080server.addListener(listener ); // 将监听类注册到server中server.addWebApplication("myapp","./webapps/myapp/"); // 将这个web应用注册到这个Server中server.start(); // 最后启动这个server短短数行代码就可创建一个web服务器并启动它,这有点类似于我们windows中的即插即用的概念,需要什么就添加什么,把这些类以HttpServer为核心组合在一起,就可以完成强大的功能。
三、Jetty Server1.上面我们探讨了HttpServer的启动,读者一定还存在这样疑问,整个Jetty 服务器是怎样启动的?首先我们可以在图1-1 看到左下角有一个Server类,这个类实际上继承了HttpServer,当启动Jetty服务器时,具体来说,在Jetty根目录下命令行下如输入JAVA -jar start.jar etc/demo.xml,注意这里有一个配置文件demo.xml做为运行参数,这个参数也可以是其它的配置文件,也可是多个xml配置文件,其实这个配置文件好比我们使用struts时的struts -config.xml文件,将运行Server需要用到的组件写在里面,比如上一节中HttpServer的配置需要的组件类都可以写在这个配置文件中。
2.我们自己部署到Jetty的webapps目录下的web application,Jetty如何运行我们自己的web application?首先当我们按上述方法启动Jetty Server时,就会调用Server类里面的main方法,这个入口方法首先会构造一个Server类实例(其实也就构造了一个HttpServer),创建实例过程中就会构造XmlConfiguration类的对象来读取参数配置文件,之后再由这个配置文件产生的XmlConfiguration对象来配置这个Server,配置过程其实是运用Java的反射机制调用Server的方法并传入配置文件中所写的参数来向这个Server添加HttpListener,HttpContext,HttpHandler,web application(对应我们自己部署的web应用)。
添加我们自己的web application过程中相应的就会读取我们所熟知的/WEB-INF/web.xml来创建一个WebApplicationContext(这个类继承了HttpContext)的实例,同时也会创建WebApplicationContext自身的ServletHandler(实现了HttpHandler接口),注意到ServletHandler中包含一组ServletHolder指向实际的Servlet,譬如说我们在web.xml文件中配置了两个Filter和一个Servlet,这里就会有三个ServletHolder,实际处理请求时ServeletHandler就会依次调用这三个ServletHolder传入request,response处理(实际最后交给这两个Filter和Servlet处理),这样我们自己做好的一个web应用就挂载到这个Server上了,可以接受客户端相应的request(请求)。
四、运行原理(请参考如下时序图)<图1-7 >上图展示了一个request的处理过程,首先HttpListener监听到客户端发来的请求创建一个HttpConnection实例(封装了连接细节,比如从Socket连接中获取的输入流和输出流), HttpConnection对象构建过程中会创建Jetty内部自定义的HttpRequest和HttpResponse对象,接着HttpListener会调用这个HttpConnection实例的handle方法, HttpConnection实例就调用HttpRequest对象的read()方法读取信息,调用HttpServer的service方法以HttpRequest,HttpResponse为参数传给HttpServer,HttpServer又将HttpRequest和HttpResponse分发给相应的HttpCotext,HttpContext最后将HttpRequest和HttpResponse交给自身的HttpHandler 处理,在这里HttpRequest,HttpResponse被再次封装为ServletHttpRequest和ServletHttpResponse,其实这两个类实现了我们所熟知的HttpServletRequest和HttpServletResponse接口。
五、高级性能1.HttpHandler:该接口的实现类用于处理HttpContext分发过来的reqeust,不同的实现类的有不同的处理功能,这里介绍几常用的HttpHandler实现类: ReourceHandler:用于处理静态内容,如以扩展名为.html的文件SecurityHandler:提供基本的安全验证ForwardHandler:转发一个request到另一个urlServletHandler:用于将request交由具体的Servlet类进行处理2.当你在看图1-2 时候会注意到HttpServer和HttpListener,HttpServer与HttpContext,HttpContext与HttpHandler存在一对多的关系,下面就介绍一下它们之间的这种关系如何通过程序来配置.HttpListener & HttpServer:HttpListener是所有监听器类的接口,如图中的SocketListener (基于传统的Socket技术)就实现了该接口,Jetty还有其它的实现该接口类,如SocketChannelListener(基于NIO技术)类等,HttpListener职责主要是在服务器启动后监听相应端口的来自客户端请求并建立连接(图1-1 中所示用HttpConnection封装连接细节),监听器可在同个IP上开启多个端口为同一个HttpServer 进行监听,所以HttpListener和HttpServer是多对一的关系,如下图:<图1-3 >配置代码:HttpServer server = new HttpServer();HttpListenrer listener1 = new SocketChanneListener();Listener1.setPort(8080);HttpListenrer listener1 = new SocketListener();Listener1.setPort(8443);server.addListener(listener1);server.addListener(listener2);HttpContext & HttpHandler:HttpContext相当于对应客户端请求的URL或某个虚拟机, 其子类中包含若干个HttpHandler, 当接受到request(请求)时,HttpContext 会依次(按某个预定的次序)把request交给这些HttpHandler处理,直到这个request被标示处理过为止, 需要注意的是这个request可能被多个HttpHandler处理,但只能有一个HttpHandler能标示这个request已被处理过.一个典型的HttpContext有用于安全处理、静态资源处理及Servlet类的HttpHandler,如下图:<图1-4>配置代码:HttpContext context = new HttpContext();context.setContextPath(“/myapp/*”);HttpHandler securitHandler = new SecurityHandler();HttpHandler resourceHandler = new ResourceHandler();HttpHandler servletHandler = new ServletHandler();context.addHandler(securitHandler);context.addHandler(resourceHandler);context.addHandler(servletHandler);HttpServer & HttpContext:一般的HTTP服务器软件可以同时处理多个web application,同样一个HttpServer可以包含多个HttpContext,如下图可以通过同一个端口的监听类来映射多个HttpContext:<图1-5 >配置代码:HttpServer server = new HttpServer();HttpContext context1 = new HttpContext();context1.setContextPath(“/app1/*”);HttpContext context2 = new HttpContext();context2.setCont extPath(“/app2/*”);server.addContext(context1);HttpServer & HttpLister & HttpContext:另外Jetty对多网卡(多个IP地址,不同的主机名)的服务器也提供了很好的支持,每个HttpContext都有自身的HttpServer:<图1-6 >配置代码:HttpServer server1 = new HttpServer();SocketListener listener1 = new SocketListener();listener1.setHost(“”);//orListener1.setHost(“”)listener2.setPort(80);HttpContext context1 = new HttpContext();context1.setContextPath(“/”);server1.addListener(listener1);server1.addContext(context1);3.Jetty对高并发的支持<图1-8>如果多用户请求服务就会涉及到多线程的管理,如图1-8,Jetty中主要由ThreadPool负责管理多线程,注意其中Pool.PondLife是Pool 的一个内部接口, ThreadPool.PoolThread是ThreadPool的一个内部线程类,我们看到Pool.PondLife和Pool存在一个聚集的关系,实际上Pool对象中存放在是一个个ThreadPool.PoolThread线程对象,当有新用户连接上Server时,ThreadPool就从Pool中取一个空闲的线程为当前用户连接服务。