Jetty 9 源码分析 Connector及Server类(一)
本文的源码基于Jetty9,主要分析了Jetty 的Connector与Server类间在Jetty启动过程中的一些细节。
Jetty9 对以前的Connector体系进行了重构, 结构与6和7都不同,原有的一些BIO类已经被抛弃。
先看Server 构造函数
public Server(@Name("port")int port)
{
this((ThreadPool)null);
ServerConnector connector=new ServerConnector(this);
connector.setPort(port);
setConnectors(new Connector[]{connector});
}
将本身传入ServerConnector构造, 设置connector的port, 并将ServerConnector传入自身的
Connector数组,保持引用。
Server自身的Connectors数组变量,采用CopyOnWriteArrayList,保证可能的线程操作的安全。
private final List<Connector> _connectors = new CopyOnWriteArrayList<>();
Server启动类在Jetty.xml中定义,并设置线程池,Handler
<Configure id="Server" class="org.eclipse.jetty.server.Server">
ThreadPool是共享的, Connector与dispatch类都会用到。
Server继承自HandlerWrapper, HandlerWrapper将handle代理给其装饰的类,即实际的Handler类,实现Decorator模式。
继承关系如下:

AbstractHandler
|-AbstractHandlerContainer
|-HandlerWrapper
|-Server
Server的启动方法是doStart(),该方法先调用上层doStart()方法,然后调用自身Connector数组的中的Connector类的start()方法。
try
{
super.doStart();
} for (Connector _connector : _connectors)
{
try
{
_connector.start();
}
catch (Throwable e)
{
mex.add(e);
}
}
ServerConnector是Jetty9中主要的Connector实现,负责主要接入处理,此类主要的操作还有Java对接入连接的抽象Connection,
Connection由Connector中设置的工厂类产生,如果没设置过,默认的工厂类是HttpConnectionFactory。
Connector中还会与另一抽象Selector交互。
描述了ServerConnector继承关系的类图:

ServerConnector的继承层次如下:

下面看一些具体点的代码:
AbstractLifeCycle start() -> doStart(); 预留了doStart()方法供子类重写。
|-ContainerLifeCycle doStart()
|-AbstractConnector
|-AbstractNetworkConnector doStart() ->open(); 设置了一个open方法供子类重写
|-ServerConnector open(); 实现了open方法,打开ServerSocketChannel
AbstractLifeCycle中start()的内容:
try
{
if (_state == __STARTED || _state == __STARTING)
return;
setStarting();
doStart();
setStarted();
}
可看到此方法作为一个模板方法,将doStart()的实现留给子类重写,其自身的doStart()是一个空方法,这种用法在Jetty跟生命周期有关的类很多。
Open方法的内容,隐藏部分不太重要的细节:
if (serverChannel == null)
{
serverChannel = ServerSocketChannel.open(); InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
serverChannel.socket().setReuseAddress(getReuseAddress()); _localPort = serverChannel.socket().getLocalPort();
if (_localPort <= 0)
throw new IOException("Server channel not bound"); addBean(serverChannel);
} serverChannel.configureBlocking(true);
addBean(serverChannel); _acceptChannel = serverChannel;
这里的ServerSocketChannel使用的是阻塞模式,
回到 AbstractNetworkConnector 的doStart中:
protected void doStart() throws Exception
{
open();
super.doStart();
}
方法继续调用了父类的doStart(), 那么再看父类AbstractConnector的doStart():
protected void doStart() throws Exception
{
_defaultConnectionFactory = getConnectionFactory(_defaultProtocol); super.doStart(); _stopping=new CountDownLatch(_acceptors.length);
for (int i = 0; i < _acceptors.length; i++)
getExecutor().execute(new Acceptor(i)); }
此方法设置的默认的ConnectionFactory, 另一个重要概念Acceptor类也是这里出现的。
Acceptor是AbstractConnector的私有内部类,这里用的CountDownLatch是给doStop用的, stop中会计算这个CountDownLatch是否为空,
不为空则会调用CountDownLatch.await等待, 知道Acceptor的线程都停掉才继续做stop的其他事情。
Acceptor的数量在该类的构造方法中进行初始化,下面是片段:
if (acceptors<=0)
acceptors=Math.max(1,(Runtime.getRuntime().availableProcessors()) / 2);
主要计算方式就是最少是1个,是否大于一个要根据CPU数量来,按CPU核心数量/2来计算Acceptor的数量。
Jetty 9 源码分析 Connector及Server类(一)的更多相关文章
- Jetty - Container源码分析
1. 描述 Container提供管理bean的能力. 基于Jetty-9.4.8.v20171121. 1.1 API public interface Container { // 增加一个bea ...
- tomcat8源码分析-Connector初始化
谈起Tomcat的诞生,最早可以追溯到1995年.近20年来,Tomcat始终是使用最广泛的Web服务器,由于其使用Java语言开发,所以广为Java程序员所熟悉.很多人早期的J2EE项目,由程序员自 ...
- 【Canal源码分析】Canal Server的启动和停止过程
本文主要解析下canal server的启动过程,希望能有所收获. 一.序列图 1.1 启动 1.2 停止 二.源码分析 整个server启动的过程比较复杂,看图难以理解,需要辅以文字说明. 首先程序 ...
- Eureka 源码分析之 Eureka Server
文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/FfJrAGQuHyVrsedtbr0Ihw 简介 上一篇文章<Eureka 源码分析 ...
- Spring Developer Tools 源码分析:二、类路径监控
在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...
- Jetty - LifeCycle源码分析
1. 描述 基于Jetty-9.4.8.v20171121. LifeCycle主要管理Jetty里面通用组件的生命周期,比如组件启动中.启动.运行.停止中.停止等,实现该接口就可以定义一套生命周期. ...
- nova-api源码分析(WSGI server的创建及启动)
源码版本:H版 一.前奏 nova api本身作为一个WSGI服务器,对外提供HTTP请求服务,对内调用nova的其他模块响应相应的HTTP请求.分为两大部分,一是服务器本身的启动与运行,一是加载的a ...
- [编织消息框架][netty源码分析]6 ChannelPipeline 实现类DefaultChannelPipeline职责与实现
ChannelPipeline 负责channel数据进出处理,如数据编解码等.采用拦截思想设计,经过A handler处理后接着交给next handler ChannelPipeline 并不是直 ...
- tp5底层源码分析之------tp5.1类的自动加载机制
tp框架作为国内主流框架,目前已经发布了6.0版本,相当于3.*版本是进行了重构,今天我们从源码的角度来研究下tp5.1自动加载的实现 作为单入口框架,从入口文件看起,入口文件在public/下,那么 ...
随机推荐
- Hadoop2.6.0的事件分类与实现
前言 说实在的,在阅读Hadoop YARN的源码之前,我对于java枚举的使用相形见绌.YARN中实现的事件在可读性.可维护性.可扩展性方面的工作都值得借鉴. 概念 在具体分析源码之前,我们先看看Y ...
- 解决jquery1.9不支持browser对象的问题||TypeError: $.browser is undefined
在插件的源代码里插入如下代码: (function(jQuery){ if(jQuery.browser) return; jQuery.browser = {}; jQuery.browser.mo ...
- http statusCode(状态码) 200、300、400、500序列
201-206都表示服务器成功处理了请求的状态代码,说明网页可以正常访问. 200(成功) 服务器已成功处理了请求.通常,这表示服务器提供了请求的网页. 201(已创建) ...
- CodeForces 742B Arpa’s obvious problem and Mehrdad’s terrible solution (暴力枚举)
题意:求定 n 个数,求有多少对数满足,ai^bi = x. 析:暴力枚举就行,n的复杂度. 代码如下: #pragma comment(linker, "/STACK:1024000000 ...
- VM12安装OS X10.11步骤及说明
参考文献: 1. http://www.crsay.com/network/enable-hardware-based-dep.html 2. http://jingyan.baidu.com/art ...
- 【九度OJ】题目1054:字符串内排序
题目描述: 输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串. 输入: 测试数据有多组,输入字符串. 输出: 对于每组输入,输出处理后的结果. 样例输入: bacd 样例输出 ...
- 电子数字 网易游戏在线笔试 第一题 hihocoder
题目链接 http://hihocoder.com/contest/ntest2016spring1/problem/1 这个题目有几个算法考点: (1)对于一个LED数码管(由7个发光二极管封装在一 ...
- 使用CSS中的meta实现web定时刷新或跳转的方法
这篇文章主要介绍了使用CSS中的meta实现web定时刷新或跳转的方法,比使用JavaScript脚本实现起来更加简单一些,需要的朋友可以参考下 meta源信息功能之页面定时跳转与刷新 几乎所有的网页 ...
- solr&lucene3.6.0源码解析(四)
本文要描述的是solr的查询插件,该查询插件目的用于生成Lucene的查询Query,类似于查询条件表达式,与solr查询插件相关UML类图如下: 如果我们强行将上面的类图纳入某种设计模式语言的话,本 ...
- Pair Project:电梯控制程序
12061160刘垚鹏 & 12061166宋天舒 1.1结对编程的优缺点结对编程相对于个人编程有很多优点.首先,督促作用,在讨论过程中能够很快投入工作,为了不耽误对方时间,我们会尽快完成各自 ...