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/下,那么 ...
随机推荐
- ASP.NET MVC分页组件MvcPager 2.0版发布暨网站全新改版
MvcPager分页控件是在ASP.NET MVC Web应用程序中实现分页功能的一系列扩展方法,该分页控件的最初的实现方法借鉴了网上流行的部分源代码, 尤其是ScottGu的PagedList< ...
- app.js
//第一步,引入express模块 var exp = require('express'), http = require('http'),//引入http模块 path = req ...
- SVM系列之拉格朗日对偶
在学习SVM(Support Vector Machine) 支持向量机时,对于线性可分的分类样本求出的分类函数为: 其中,分类超平面可以表示为:
- 通俗易懂的 JSon解析处理
1.主要用到的类: 主要用到了JavaScriptSerializer类,该类在System.Web.Script.Serialization命名空间(在System.Web.Extensions.d ...
- Linux 查看进程、清理缓存、查看磁盘空间、查看宽带的命令
一.查看进程 查看所有的进程命令:ps 查看指定的进程命令:ps -ef|grep java (java 指的是服务名称) 结束进程命令:kill -9 9028 (9028指的是PID) 二.清理 ...
- Win7 64位 VS2015及MinGW环境编译FFMPEG-20160326
因为又要弄MinGW了,所以顺便把FFMPEG编译了,文章主要参考这篇,防抽所以复制一遍,顺便加些自己的内容 http://blog.csdn.net/finewind/article/details ...
- 【随机化】bzoj4080 [Wf2014]Sensor Network
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; typedef ...
- java中枚举(enum)小例子。之前学过枚举但是一直没用,这里有个枚举类帮你我理解下(很肤浅)
直接上枚举类,代码简单易懂. package com.jy.modules.cims.data.interact.tbj.loan.request; /** * * @author shengzhou ...
- Oozie命令行常用命令汇总[转]
Oozie命令行常用命令汇总 有时候脚本跑多了就不愿意在OozieWeb端去看脚本的运行情况了.还好Oozie提供了很多命令行命令.能通过命令行直接检索自己想看到的脚本信息.在这里简单进行一下总结.一 ...
- Sqlite 管理工具收藏
1.SQLite Administrator http://download.orbmu2k.de/files/sqliteadmin.zip 2.SQLite2009Pro-v3.8.3.1 h ...