jetty架构及工作原理

1. jetty 是什么

jetty是一个轻量级的servelt容器,是一个提供HHTP服务器、HTTP客户端和javax.servlet容器的开源项目。

2. 和tomcat比较

2.1 架构层面

Jetty的架构比Tomcat的更为简单

Jetty的架构是基于Handler来实现的,主要的扩展功能都可以用Handler来实现,扩展简单。

Tomcat的架构是基于容器设计的,进行扩展是需要了解Tomcat的整体设计结构,不易扩展。

2.2. Jetty和Tomcat性能方面差异不大

Jetty可以同时处理大量连接而且可以长时间保持连接,适合于web聊天应用等等。

Jetty的架构简单,因此作为服务器,Jetty可以按需加载组件,减少不需要的组件,减少了服务器内存开销,从而提高服务器性能。

Jetty默认采用NIO结束在处理I/O请求上更占优势,在处理静态资源时,性能较高

2.3 其它比较

Jetty的应用更加快速,修改简单,对新的Servlet规范的支持较好。

Tomcat目前应用比较广泛,对JavaEE和Servlet的支持更加全面,很多特性会直接集成进来。

Tomcat适合处理少数非常繁忙的链接,也就是说链接生命周期短的话,Tomcat的总体性能更高。

Tomcat默认采用BIO处理I/O请求,在处理静态资源时,性能较差。

所以具体使用jetty还是Tomcat需要具体根据场景而定

3. jetty架构

      jetty 的核心组件包括Server,Handle和Connector,Server是整个Jetty的核心,包含了Handle和Connector

jetty架构及工作原理

整个Jetty的核心由Server和Connector两个组件构成,整个Server组件是基于Handler容器工作的,它类似Tomcat的Container容器。Connector组件负责接受客户端的连接请求,并将请求分配给一个处理队列去执行。

jetty架构及工作原理

整个Jetty的核心围绕着Server类来构建,Server类继承了Handler,关联了Connector和Container,Container是管理Mbean的容器。Jetty的Server的扩展主要是实现一个个Handler并将Handler加到Server中,Server中提供了调用这些Handler的访问规则。

4.jetty 启动过程

Jetty的入口是Server类,Server中包含了一个HandleList和ConnectorList, 这些组件都继承了LifeCycle,在Server的启动过程中会一次都调用这两个注册组件的Start方法,因此Server类启动完了,就代表Jetty能提供服务了。在Jetty的配置文件我们可以发现,配置Jetty的过程就是将那些类配置到Server的过程。

jetty架构及工作原理

因为Jetty的所有组件都会继承LifeCycle,所以Server的start方法就会调用所有已经注册到Server的组件,Server启动其他组件的顺序:首先启动设置Server的Handler,通常这个Handler会有多个子Handler,接着会启动注册在Server上JMX的Mbean,让Mbena也一起工作,最后启动Connector,打开端口,接受客户端请求。

5. Jetty配置

5.1 Jetty启动配置文件

  Jetty使用如下配置文件来实例和启动一个服务,通过start.jar处理

ini files:

Jetty启动原理使用命令行,使用$JETTY_BASE/start.ini和$JETTY_BASE/start.d/*.ini文件来创建一个有效的命令参数参数如下:

  • **的模块  --module=name
  • 通过name=value的来为Jetty的IOC配置属性
  • XML files in Jetty IoC (or Spring) XML format
  • 一个标准的Java属性文件包含额外的启动属性
  • 其他start.jar选项(see java -jar start.jar --help)
  • 一些JVM参数组合通过--exec,例如-Xbootclasspath.

5.2 Jetty常用配置

5.2.1 配置服务

  Server实例是Jetty服务的重要组成部分,它为其它Jetty组件提供服务和生命周期管理。在标准的Jetty应用中,核心的配置信息在etc/jetty.xml文件中 ,但是你也可以在配置文件中添加其它配置 ,包括:

ThreadPool:

  服务器实例提供了一个默认ThreadPool实例,用来供其它组件调用。配置线程池的主要参数有最大和最小数量的设置,设置在start.ini文件或者start.d/server.ini文件中。

Handlers:

  一个Jetty服务器可以只有一个处理程序实例来处理传入的HTTP请求。然而一个处理程序可能是一个容器或包装其他处理程序形成一个树的处理程序。在etc/jetty.xml文件中配置的默认的处理程序包含处理程序集合和一个默认的处理程序,根据路径找到相应的处理程序,默认的处理器处理404错误。其他配置信息可以增加到处理树中(例如,jetty-rewrite.xml, jetty-requestlog.xml), 或者配置一个组件用于热部署处理(例如,jetty-deploy.xml) 。

Server Attributes:

  服务器可以通过字符串来映射到一个对象上,如果一个对象实现了LifeCycle接口,那么这个对象可以监听这个Jetty服务的启停。通常服务器的属性保存在服务器生命周期内。

Server fields:

  服务器也有一些特殊的的配置属性,配置在start.ini或者start.d/server.ini文件中,除了控制属性外还有发送时间和http响应的版本。

Connectors:

  服务器拥有一个连接的集合,用来接收http请求,和其它Jetty支持的协议请求,下一章节将要介绍配置连接。对于服务器可以设置所有的连接也可以增加或者删除个别连接。

Services:

  服务器能容纳额外的服务对象,有时作为属性,但经常做为有生命周期的bean。

5.2.2配置连接

  Jetty服务器连接器是一个网络端点接受连接一个或多个协议产生Jetty服务器的请求或消息。在标准Jetty服务器中,可以通过额外的文件增加Jetty服务器支持的协议,例如http.ini,https.ini 和jetty-http2.xml,连接的配置一般都是典型的,如下:

Port:

  监听TCP/IP连接请求的端口,使用jetty.http.port(或者jetty.ssl.port)属性进行配置,如果没有配置默认8080(TLS默认8443)。

Host:

  您可以配置一个主机的主机名或IP地址来识别一个特定的网络接口的监听。如果没有设置,或者设置为0.0.0.0,连接器将监听所有主机。可以通过xml文件中jetty.host的这个属性进行设置。

Idle Timeout:

  时间以毫秒为单位,一个连接的超时时间。

HTTP Configuration:

  通过HttpConfiguration 实例来配置HTTP连接(包含HTTP, HTTPS 和HTTP2),可以独立于特定的网络协议,标准的Jetty服务通过jetty.xml来配置一个单例的HttpConfiguration对象。

SSL Context Factory:

  通过本地的**来保证ssl连接的安全性。

Note

虚拟主机不能配置连接,用户应该通过虚拟主机的context来实现它们的相应。

Note

Jetty9同时支持连接协议(HTTP,HTTPS,AJP,SPDY)和自然连接(NIO或者BIO),Jetty9以后只有一个主要的连接器ServerConnector

5.2.3配置上下文环境

一个Jetty环境包含一组处理器处理指定路径的请求。一个Jetty环境可以包含默认处理器和用户自定义处理器。

Note

servlet规范定一个web应用。在Jetty规范中一个标准的web项目必须有一个标准的WEB-INF/web.xml文件,用来配置classpath,资源,session处理,登录,以及servlet,jsp,以及静态资源。标准的web应用需要很少的额外的配置文件。

常见的上下文配置:

contextPath:

  contextPath 是URL的前缀。例如一个contextPath 是/foo,它将处理 /foo, /foo/index.html, /foo/bar/,and /foo/bar/image.png等请求,但是它不会处理像/,/other/,or /favicon.ico这样的请求,若contextPath是/,则为根contextPath。contextpath可以被默认设置(默认为部署的文件名),也可以在xml里面或者代码里面进行设置,或者在WEB-INF/jetty-web.xml文件中设置。

virtualHost:

  配置监听主机ip或名称,没有配置的将不会被监听到。

classPath:

  配置类路径,标准的类路径为 WEB-INF/lib和WEB-INF/classes ,也可以增加额外的路径到classpath下。

attributes:

  配置属性,可以传递到实体类中,比如javax.servlet.context.tempdir属性用来配置临时目录。

resourceBase:

  配置资源,这个配置是一个目录,包含各种静态资源信息,可以是图片或者HTML页面。

5.2.3.1 通过API配置上下文

在嵌入式的server,用户可以通过ContextHandler API来配置上下文,示例如下:

//
//  ========================================================================
//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//
package org.eclipse.jetty.embedded;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
public class OneContext
{
    public static void main( String[] args ) throws Exception
    {
        Server server = new Server( 8080 );
        // Add a single handler on context "/hello"
        ContextHandler context = new ContextHandler();
        context.setContextPath( "/hello" );
        context.setHandler( new HelloHandler() );
        // Can be accessed using http://localhost:8080/hello
        server.setHandler( context );
        // Start the server
        server.start();
        server.join();
    }
}

6.Handle介绍

jetty架构及工作原理

Handler体系结构影响着整个Jetty的方方面面。主要有两种Handler类型。一种是HandlerWrapper,它可以将一个Handler委托给另一个类去执行,如我们将一个Handler加到Jetty中,那么必须将这个Handler委托给Server去调用。配合ScopeHandler类可以拦截Handler的执行,在调用Handler之前或之后可以做另外一件事,类似于Tomcat的Valve。另一种Handler类型是HandlerCollection,这个Handler类可以将多个Handler组装在一起,构成一个Handler链。

 

jetty Handle 介绍:https://blog.csdn.net/yishifu/article/details/52671755

jetty Handle 源码分析 : https://blog.csdn.net/qq_41084324/article/details/83313924

7.Connector介绍

 Connector是Jetty中可以直接接受客户端连接的抽象,一个Connector监听Jetty服务器的一个端口,所有客户端的连接请求首先通过该端口,而后由操作系统分配一个新的端口(Socket)与客户端进行数据通信(先握手,然后建立连接,但是使用不同的端口)。不同的Connector实现可以使用不同的底层结构,如Socket Connector、NIO Connector等,也可以使用不同的协议,如Ssl Connector、AJP Connector,从而在不同的Connector中配置不同的EndPoint和Connection。EndPoint用于连接(Socket)的读写数据(参见深入Jetty源码之EndPoint),Connection用于关联Request、Response、EndPoint、Server,并将解析出来的Request、Response传递给在Server中注册的Handler来处理(参见深入Jetty源码之Connection)。在Jetty中Connector的有:SocketConnector、SslSocketConnector、Ajp13SocketConnector、BlockingChannelConnector、SelectChannelConnector、SslSelectChannelConnector、LocalConnector、NestedConnector等,其类图如下。
jetty架构及工作原理

8.jetty简单使用

1. 首先创建一个Server类,其中创建了两个Connector实例,一个绑定到了8080端口,另一个绑定到了9090端口:

package com.google.code.garbagecan.jettystudy.sample2;  
  
import org.eclipse.jetty.server.Connector;  
import org.eclipse.jetty.server.Server;  
import org.eclipse.jetty.server.nio.SelectChannelConnector;  
  
public class MyServer {  
    public static void main(String[] args) throws Exception {  
        Server server = new Server();  
  
        SelectChannelConnector connector1 = new SelectChannelConnector();  
        connector1.setPort(8080);  
  
        SelectChannelConnector connector2 = new SelectChannelConnector();  
        connector2.setPort(9090);  
  
        server.setConnectors(new Connector[] { connector1, connector2 });  
  
        server.setHandler(new HelloHandler());  
  
        server.start();  
        server.join();  
    }  
}  

2. 创建一个Handler类,用了处理所有客户端的请求

package com.google.code.garbagecan.jettystudy.sample2;  
  
import java.io.IOException;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
import org.eclipse.jetty.server.Request;  
import org.eclipse.jetty.server.handler.AbstractHandler;  
  
public class HelloHandler extends AbstractHandler {  
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)  
            throws IOException, ServletException {  
        response.setContentType("text/html;charset=utf-8");  
        response.setStatus(HttpServletResponse.SC_OK);  
        baseRequest.setHandled(true);  
        response.getWriter().println("<h1>Hello World</h1>");  
        response.getWriter().println("<li>Request url: " + target + "</li>");  
        response.getWriter().println("<li>Server port: " + request.getServerPort() + "</li>");  
    }  
}  

 3. 运行MyServer类,通过浏览器分别访问http://localhost:8080/和http://localhost:9090/。

 

https://www.cnblogs.com/beaconSky/articles/5339429.html   Jetty的工作原理

https://www.cnblogs.com/yiwangzhibujian/p/5856857.html  jetty使用原理