Jetty 服务器架构分析(中)

    接上一篇,说到XmlConfiguration ,XmlConfiguration 利用自己实现的 IOC 组装 Server 的全过程如下图所示:

这里可以看到 3 个关键的配置文件, jetty.xml jetty-deploy.xml 、以及 contexts/xxx.xml

l  Jetty.xml 文件中定义了入口类 Server, 以及其所需要的线程池、 Connector Handler

l  Jetty-deploy.xml 中则定义了部署 web 应用用到部署工具,在其中指定了部署 web 应用的两种方式,类似于 tomcat, 如果采用 webappProvider ,则表示将 web 应用放在 webapp 下即可生效,如果采用 ContextProvider ,则需要定义 Contexts 目录所在位置,只要在该目录下放置任何应用的 context 配置文件就可以生效。

l  Xxx.xml 这是一个用户自定义文件,表示采用 ContextProvider 时,在其中定义一个 WebAppContext handler, 它指定了我们应用所在的位置,便于加载。

 

XmlConfiguration 解析装配完毕之后,就开始启动服务, Jetty 的启动是从 Server 开始的,我们来看一下服务器真正的启动过程。

 

 

 

 

 

 

从上图中我们能大概看出服务器启动过程,先是由用户设置好需要的核心组件,然后调用 Server.start() 开始启动服务,其中会首先启动 handler 处理器,之后启动用户自定义组件,这个自定义组件需要实现 LifeCyle 接口,最后才启动 Connector 接受请求。可以想到,关闭过程恰好是反过来,首先关闭接受请求的 connector ,然后再关闭用户自定义组件,最后关闭 handler.

         我们再来详细看一下 Server 源代码的核心实现过程,当调用 start 方法时,其实是调用其祖先类 AbstractLifeCycle 中方法,该方法在这里有一个模板实现,如下:

public final void start() throws Exception { synchronized (_lock) { try { if (_state == __STARTED || _state == __STARTING) return; setStarting(); doStart(); setStarted(); } catch (Exception e) { setFailed(e); throw e; } catch (Error e) { setFailed(e); throw e; } } }

 

  • Connector 启动过程

 

看下 Connector 的详细启动过程: ( NIO 为例 )

 

NIOConnector 启动过程中,先创建了多个 SelectSet 对象,每个 SelectSet 负责一个 NIO Selector ,专门用于监听 read 事件 ( 这里利用的多线程 Reactor 模式, http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf ) ,当然这里仅仅是创建了对象,并没有启动,后面会提到。

SelectorManager

 

 

然后再调用 open 创建了一个 blocking 的阻塞 channel ,专门用于接受用户的新连接,我们看下:

 

public void open() throws IOException { synchronized(this) { if (_acceptChannel == null) { // Create a new server socket _acceptChannel = ServerSocketChannel.open(); // Set to blocking mode _acceptChannel.configureBlocking(true); // Bind the server socket to the local host and port _acceptChannel.socket().setReuseAddress(getReuseAddress()); InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort()); _acceptChannel.socket().bind(addr,getAcceptQueueSize()); _localPort=_acceptChannel.socket().getLocalPort(); if (_localPort<=0) throw new IOException("Server channel not bound"); } } }

 

随后从线程池中分配了 N ( 可以在配置文件中配置 ) 线程用于启动 SelectSet 监听 read 事件。

 

 

 

 

 

 

 

 

synchronized (this) { _acceptorThread = new Thread[getAcceptors()]; for (int i = 0; i < _acceptorThread.length; i++) _threadPool.dispatch(new Acceptor(i)); if (_threadPool.isLowOnThreads()) Log.warn("insufficient threads configured for {}",this); }

最后再分配 1 个线程用于 accept 用户的新连接,新连接来之后,会将其设置为 nonblocking 模式,之后就将其 Register 给某个 SelectSet 去监听 read 事件,然后又返回来继续监听新连接:

 

_manager.dispatch(new Runnable() { public void run() { final ServerSocketChannel server=_acceptChannel; while (isRunning() && _acceptChannel==server && server.isOpen()) { try { SocketChannel channel = server.accept(); channel.configureBlocking(false); Socket socket = channel.socket(); configure(socket); _manager.register(channel); } catch(IOException e) { Log.ignore(e); } } } });

 

 

 

  • Handler 启动过程

 

Jetty 将所有的真正处理请求的动作都抽象成了 Handler ,因此做事情的组件都是实现了这个接口的,包括上图所示的 WebAppContext 等等,需要做什么样的工作,那么就添加什么样的 Handler ,这里 SessionHandler 不是必须的,但是默认是创建好的。 ServletHandler 主要负责处理 web 应用的 Servlet Filter 等工作,最后将请求直接交给 Servlet Filter 都是在这里完成。

   这里展示的 Handler 的启动过程其实是在准备 web 应用环境,例如解析 web 应用的 web.xml 等等工作,做好一切准备工作。

 

 

 

转载于:https://www.cnblogs.com/lovingprince/archive/2011/02/23/2166259.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python去掉列表中的单引号_Python:如何从列表项中删除单引号(Python: How to remove single quotes from list item)...

I’m working on a bit of python code to run a query against a redshift (postgres) SQL database, and I’m running into an issue where I can’t strip off the surrounding single quotes from a variable I’m passing to the query. I’m trying to drop a number of…

VxWorks嵌入式操作系统的TrueFFS文件系统驱动开发

嵌入式系统对执行速度和系统可靠性的要求&#xff0c;决定了嵌入式系统需要一种安全、快速的存储设备&#xff0c;这种设备备同时还需要体积小、容量大、掉电数据不丢失等特点。而Flash存储器恰恰能够满足上述要求。这也使得Flash存储器成为嵌入式系统中的主要存储设备。 现…

神经网络与深度学习——TensorFlow2.0实战(笔记)(五)(NumPy科学计算库<矩阵和随机数>python)

矩阵和随机数 矩阵 创建矩阵 #创建矩阵 astring np.mat("1 2 3; 4 5 6") alist [[1,2,3],[4,5,6]] anplist np.array(alist) print(np.matrix(astring))#字符串、列表、元组、数组 print(np.mat(astring))#字符串、列表、元组、数组 print(np.mat(alist)) prin…

python爬虫抓取文本_Python实现可获取网易页面所有文本信息的网易网络爬虫功能示例...

本文实例讲述了Python实现可获取网易页面所有文本信息的网易网络爬虫功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a; #codingutf-8 #--------------------------------------- # 程序&#xff1a;网易爬虫 # 作者&#xff1a;ewang # 日期&#xff1a;2016-7-6 #…

DOC学习之TrueFFS

TrueFFS原理 引用TrueFFS原理及其在CF卡上的实现的部分内容 “1、Wear-Leveling 闪速存储器不能无限次重复使用。它的每个扇区的擦除次数虽然很大&#xff0c;但却有限&#xff1b;因此&#xff0c;随着使用次数的加长&#xff0c;它最终会变成只读状态&#xff0c;所以应该尽…

安装 sql server 2005 com+ 目录要求警告 解决方案

用法&#xff1a; 创建记事本&#xff0c;然后改后缀名为.bat echo off setlocal echo %WINDIR%\System32\msdtc.exe -uninstall %WINDIR%\System32\msdtc.exe -uninstall call :delkey "HKCR\CID" call :delkey "HKLM\SYSTEM\CurrentControlSet\Serv…

神经网络与深度学习——TensorFlow2.0实战(笔记)(五)(Matplotlib绘图基础<1>python)

数据可视化 数据分析阶段&#xff1a;理解和洞察数据之间的关系 算法调试阶段&#xff1a;发现问题&#xff0c;优化算法 项目总结阶段&#xff1a;展示项目成果 Matplotlib&#xff1a; 第三方库&#xff0c;可以快速方便地生成高质量的图表 安装Matplotlib库 Figure 对…

Linux 定时器设置

函数alarm设置的定时器只能精确到秒&#xff0c;而以下函数理论上可以精确到微妙&#xff1a; #include <sys/select.h> #include <sys/time.h> int getitimer(int which, struct itimerval*value); int setitimer(int which, const structitimerval *value, s…

idea lombok不生效_Spring Boot 集成 Lombok 让代码更简洁!

点击上方“Java之间”&#xff0c;选择“置顶或者星标”你关注的就是我关心的&#xff01;作者&#xff1a;Anoyi lombok的威力简化代码IntelliJ IDEA安装lombok插件1、菜单栏 File > Settings > Plugins > Browse repositories…安装插件2、搜索 Lombok Plugin 安装后…

IT人转型做技术型销售到底行不行

想想自己已经做了八年的销售了&#xff0c;说不上很成功自己也算满意&#xff0c;多多少少有一些相关的经验。如果有刚刚入行或者即将入行的朋友愿意从一个过来人的视角着手去对这个行当多一些了解&#xff0c;我乐于慢慢码字出来与大家分享。 对很多职业来说&#xff0c;足够的…

arcgis按属性设置符号大小

一般都在高级设置里&#xff0c;以下是两个示例 1.相同颜色&#xff0c;不同大小 2不同颜色&#xff0c;不同大小

3648

/* 2SAT,找出一组解 逆缩图序&#xff0c;拓扑排序&#xff0c;然后染色。 找出和新娘颜色相同的点 */// include file #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <ctime>#i…

druiddatasource配置_Spring核心配置文件详解

点击蓝字“程序员考拉”欢迎关注&#xff01;1&#xff1a;spring的核心配置文件中的各种配置。 spring的核心配置文件的名字 叫做 applicationContext.xml&#xff0c;后期也可以通过配置文件中的配置修改名称&#xff0c;在web.xml中进行如下配置&#xff1a;<contex…

Linux两种定时器

Linux下的定时器有两种&#xff0c;以下分别介绍&#xff1a;     1、alarm     如果不要求很精确的话&#xff0c;用alarm&#xff08;&#xff09;和signal&#xff08;&#xff09;就够了     unsigned int alarm&#xff08;unsigned int seconds&#xff09;   …

origin(1)

origin窗口结构与布局 工作表 0.数据导入 0.1直接拖拽 0.2导入 配置相关参数 1.添加新列 1.1方法一 1.2方法二 2.设置x&#xff0c;y&#xff0c;z 2.1设置单列 2.2设置多列 2.3设置无关列 2.4设置误差线 2.5设置为标签 3.长短名称设置 3.1长名称设置 3.1.1方法一 3.1.2方…

Access 时间比较错误

原因 selete * from tab1 where addate>2010-12-24 14:07:44 拼接的时候改成 datetime dt datetime.now(); string sql "selete * from tab1 where addate>#"dt"#"; 把号换成#好就好了&#xff01;&#xff01;&#xff01;&#xff01;转载于:https…

神经网络与深度学习——TensorFlow2.0实战(笔记)(五)(Matplotlib绘图基础<散点图>python)

散点图&#xff08;Scatter&#xff09;&#xff1a; 是数据点在直角坐标系中的分布图 scatter() 函数 marker参数——数据点样式 添加文字——text() 函数 坐标轴设置 增加图例 绘制标准正态分布的散点图步骤 #散点图&#xff08;Scatter&#xff09;&#xff1a;是数据点在直…

十字路口红绿灯plc程序_实例讲解红绿灯PLC程序设计方法

十字路口的交通指挥信号灯布置如下图&#xff1a;一、控制要求&#xff08;1&#xff09;信号灯系统由一个启动开关控制&#xff0c;当启动开关接通时&#xff0c;该信号灯系 统开始工作&#xff0c;当启动开关关断时&#xff0c;所有信号灯都熄灭。&#xff08;2&#xff09;南…

listview刷新_Flutter NestedScrollView 滑动折叠头部下拉刷新效果

题记—— 执剑天涯&#xff0c;从你的点滴积累开始&#xff0c;所及之处&#xff0c;必精益求精。Flutter是谷歌推出的最新的移动开发框架。本实例运行效果如下 &#xff1a;//启动函数void main() { runApp(RootApp());}//根目录class RootApp extends StatelessWidget { ov…

神经网络与深度学习——TensorFlow2.0实战(笔记)(六)(Matplotlib绘图基础<折线图和柱状图>python)

折线图&#xff08;Line Chart&#xff09;&#xff1a; 散点图的基础上&#xff0c;将相邻的点用线段相连接 plot()函数 #折线图&#xff1a;在散点图的基础上将相邻两个点链接 #描述变量变化的趋势 #plot(x,y,color,marker,label,linewidth,markersize) #x数据点的x坐标 #y…