图解WildFly8之Servlet容器Undertow剖析

Undertow简介

Undertow 是RedHat(红帽公司)的开源产品,采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。

WildFly8的默认Servlet容器采用的不是Tomcat,也不是Jetty,而是JBoss自己开源的Undertow,Undertow是用Java编写的性能灵活的Servlet容器,底层基于高性能的NIO框架XNIO,XNIO也是JBoss开源的产品,JBoss开源的高性能NIO框架还有一个很有名:Netty。Undertow在WildFly8中的角色如图:

图解WildFly8之Servlet容器Undertow剖析_第1张图片

Undertow的架构类似于Jetty,采用应用内嵌的方式,这也正是为什么说它有灵活的性能的原因,利用Undertow可以快速构建一个小巧的应用服务,实现代码如下:

import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.handlers.PathHandler;
import io.undertow.servlet.Servlets;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.servlet.api.ServletContainer;
import io.undertow.servlet.api.ServletInfo;

public class WildFlyServer {

    public static void main(final String[] args) throws Exception {
        
        // 创建ServletInfo,名字"MyServlet"必须唯一
        ServletInfo servlet1 = Servlets.servlet("MyServlet", MyServlet.class);
        // 设置Servlet的init方法执行时需要的数据
        servlet1.addInitParam("message", "Hello World");
        // 绑定映射为/hello
        servlet1.addMapping("/hello");
        
        // 创建名字MessageServlet为的ServletInfo
        ServletInfo servlet2 = Servlets.servlet("MessageServlet", MessageServlet.class);
        servlet2.addInitParam("message", "MyServlet");
        // 绑定映射为/myservlet
        servlet2.addMapping("/qrcode");
        
        // 创建DeploymentInfo应用布署
        DeploymentInfo deployment = Servlets.deployment();
        // 指定ClassLoader
        deployment.setClassLoader(WildFlyServer.class.getClassLoader());
        // 应用上下文(必须与映射路径一致,否则sessionID会有问题,每次都新建)
        deployment.setContextPath("/myapp");
        // 设置布署包名
        deployment.setDeploymentName("test.war");
        // 添加ServletInfo
        deployment.addServlets(servlet1,servlet2);

        // 创建DeploymentInfo2应用布署
        DeploymentInfo deployment2 = Servlets.deployment();
        deployment2.setClassLoader(WildFlyServer.class.getClassLoader());
        deployment2.setContextPath("/myapp2");
        deployment2.setDeploymentName("test2.war");
        deployment2.addServlets(servlet1,servlet2);
        
        // 使用默认Servlet容器,并将布署添加至容器
        ServletContainer container = Servlets.defaultContainer();
        // 将布署添加至容器,生成布置对应的管理器
        DeploymentManager manager = container.addDeployment(deployment);
        DeploymentManager manager2 = container.addDeployment(deployment2);
        // 实施布署
        manager.deploy();
        manager2.deploy();
        
        // 生成路径处理器(作用是dispatch servlet),默认返回"/*"处理器
        PathHandler path = Handlers.path();
        // 生成路径处理器,返回"/*"自动重定向到"/myapp"的处理器
//        PathHandler path = Handlers.path(Handlers.redirect("/myapp"));
        
        // 启动容器,生成请求处理器
        HttpHandler myapp = manager.start();
        HttpHandler myapp2 = manager2.start();
        // 绑定映射关系
        path.addPrefixPath("/myapp", myapp);
        path.addPrefixPath("/myapp2", myapp2);
        
        Undertow server = Undertow.builder()
                // 绑定端口与主机
                .addHttpListener(8080, "localhost")
                // 设置分发处理器PathHandler
                .setHandler(path)
                .build();
        // 启动Server
        server.start();
        
    }
}

从源代码,我们可以抽象出Undertow生成应用的架构,如图所示

图解WildFly8之Servlet容器Undertow剖析_第2张图片

利用运行调试,我们可以更加深入地了解Undertow中的一些概念:
ServletInfo:Servlet的最小单位,是对javax.servlet.Servlet具体实现的再次封装

FilterInfo:过滤器封装
DeploymentInfo:包布署对象,包含多个ServletInfo,可以说是ServletInfo的集合
ServletContainer:容器,用来管理DeploymentInfo,一个容器可以添加多个DeploymentInfo
DeploymentManager:包布署的管理,是对添加到ServletContainer的DeploymentInfo的一个引用,用于运行发布和启动容器
HttpHandler:servlet path处理器,DeploymentManager启动后返回的Servlet处理器,通常是HttpContinueReadHandler(连续读处理器)
PathHandler:分发器,将用户请求分发给对应的HttpHandler
HttpServerExchange:数据交换封装,可以转换成ServletRequest和ServletResponse
示例代码的调试运行栈如下:

图解WildFly8之Servlet容器Undertow剖析_第3张图片

连接通道

图解WildFly8之Servlet容器Undertow剖析_第4张图片

作为Servlet协议协议转换的实体HttpServerExchange的结构如下:

图解WildFly8之Servlet容器Undertow剖析_第5张图片

Undertow的性能

专业测评结果的数据如下:

图解WildFly8之Servlet容器Undertow剖析_第6张图片

你可能感兴趣的:(中间件)