扫码关注公众号:芋道源码

发送: 百事可乐
获取永久解锁本站全部文章的链接

《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://ericcenblog.com/2017/05/27/jettyyuan-ma-pou-xi/ 「Eric Cen」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

Jetty是Eclipse Foundation出的一个轻量级Web服务器和Servlet容器。Spark使用了Jetty作为它的内嵌服务器。我一直都对Web服务器有着迷之兴趣,前前后后去读过好几个Web服务器的源码,有代码量太大设计模式复杂而半途而废的,如Tomcat,有因为代码量小而简单而读完的,如NanoHTTPD。相比之下,Jetty大小适中,而且也够成熟,之前在工作中写的一个项目就是用了Jetty Runner来实现了一个RESTful Service。这段时间重新去学习了一遍Java NIO,所以这次就趁机把Jetty的源码好好撸一遍。

Jetty Version: 9.4.5

Let’s hit on the road!

Jetty Architecture

在开始剖析代码之前,我们先看一下Jetty的整体架构,Jetty的官方文档对Jetty架构有很详细的介绍(点这里)。
img
如文档所述:

The Jetty Server is the plumbing between a collection of ‘Connector’s that accept connections and a collection of ‘Handler’s that service requests from the connections and produce responses, with threads from a thread pool doing the work.

Connector负责接收网络请求,Handler负责解析请求并产生响应,通过线程池ThreadPool来执行任务,而Connector,Handler,ThreadPool这三个组件都是依附在Server中。

启动一个内嵌的Jetty服务器

本文开头提到过Spark就是用了Jetty做为它内嵌的服务器,从上文所看到Jetty是由Server,Connector,Handler,ThreadPool这几个组件组成,那我们来看一下如何启动一个内嵌的Jetty服务器。img是的,上面的代码就已经是启动了一个内嵌的Jetty服务器!(当然,有部分代码我已经省略)。仔细看一下,ServerConnectorHandler,都有了,那ThreadPool呢?我们看一下Server类的构造函数:imgimg我们可以看到线程池是在Server的构造函数里面创建出来了,默认是一个QueuedThreadPool,基于队列的线程池。 实现一个线程池是一个不错的Java面试题,我们就先看一下Jetty是如何实现的。我们先看一下QueuedThreadPool的层级关系:img
再看QueuedThreadPool的构造函数:img我们可以看到QueuedThreadPool是把Runnable的job放在一个org.eclipse.jetty.util.BlockingArrayQueue里,org.eclipse.jetty.util.BlockingArrayQueue是Jetty自己实现的基于数组的阻塞队列。img从前文QueuedThreadPool的层级关系图看到QueuedThreadPool实现了LifeCycle接口,这个LifeCycle接口在Jetty里面是一个非常重要概念,ServerConnectorHandler,和QueuedThreadPool都是实现LifeCycle接口。这些组件都会通过调用start()方法来启动,而start()方法最终又会调用doStar()方法。我们先来看QueuedThreadPool这个线程池是怎样启动的:img它先把_threadsStarted这个Atomic的变量设成0,然后启动_minThreads个线程:imgimg可以看到,实际上它是启动了_minThreads个_runnable线程,而这个_runnable线程做的是什么的?img我们可以看到这个_runnable线程是去_jobs也就是BlockingArrayQueue这个队列里面取出一个Runnablejob,然后执行这个job:imgimg

To Be Continue……

文章目录
  1. 1. Jetty Architecture
  2. 2. 启动一个内嵌的Jetty服务器