tomcat 整体架构

tomcat 整体的架构

在这里插入图片描述
tomcat是实现了Servlet规范的一个容器.最顶层的容器是server,一个Tomcat只能有一个server
tomcat通过service对外提供服务,service比作一个家庭这个家庭的核心就是connector container,多个connector对应一个container.
connector container两个组件就是tomcat整个架构的心脏.

Connector 作用

用于接收客户端的请求,底层通过socket技术监听特定的端口,来接收请求并将请求按照一定的编码(默认UTF-8) 通信协议 http协议
tcp/ip 协议等,来封装 request response.最后将请求传递给Container.

Container作用

封装管理servlet处理request的请求.Container内部也是风层级的最外层是依次 Engine Host Context Warpper
connnector 和container的关系图
在这里插入图片描述
通过conf/server.xml文件也可以看出组件之间的关系
在这里插入图片描述

Connector架构

在这里插入图片描述
connector 通过ProtocolHandler来处理请求的,不同类型的ProtocolHandler来处理不同类型的请求

在这里插入图片描述
ProtocolHandler由三个主要的部件构成 Endpoint Processor Adapter 请求的处理也是依靠三个完成的,可以从AbstractProtocol的部分源码看出来

//ProtocolHandler 主要构件
public abstract class AbstractProtocol<S> implements ProtocolHandler,
        MBeanRegistration {
    
	
    private final AbstractEndpoint<S> endpoint;
	
	protected Adapter adapter;
    @Override
    public void setAdapter(Adapter adapter) { this.adapter = adapter; }
    @Override
    public Adapter getAdapter() { return adapter; }
	
	
	
    public void addWaitingProcessor(Processor processor) {
        if (getLog().isDebugEnabled()) {
            getLog().debug(sm.getString("abstractProtocol.waitingProcessor.add", processor));
        }
        waitingProcessors.add(processor);
    }


    public void removeWaitingProcessor(Processor processor) {
        if (getLog().isDebugEnabled()) {
            getLog().debug(sm.getString("abstractProtocol.waitingProcessor.remove", processor));
        }
        waitingProcessors.remove(processor);
}

下面再看一下这个三个组件分别有什么作用

Endpoint 底层用的socket技术,监听到请求并将请求传递给Processor.
Endpoint 通过其内部类Acceptor来实现这个功能,Acceptor 是实现了Runable 重写了run()
在这里插入图片描述


public class NioEndpoint extends AbstractJsseEndpoint<NioChannel> {
// 内部类 Acceptor是一个线程 用来接收连接的
  protected class Acceptor extends AbstractEndpoint.Acceptor {

        @Override
        public void run() {
           ....
                try {
                    //if we have reached max connections, wait
                    countUpOrAwaitConnection();

                    SocketChannel socket = null;
                    try {
                        //监听请求的链接
                        socket = serverSock.accept();
                    } catch (IOException ioe) {
                        // We didn't get a socket
                        countDownConnection();
                        if (running) {
                            // Introduce delay if necessary
                            errorDelay = handleExceptionWithDelay(errorDelay);
                            // re-throw
                            throw ioe;
                        } else {
                            break;
                        }
                    }                    
                   ....
}

Processor接受Endpoint 并把封装request response

//Processor 接收请求 创建Request Response
public abstract class AbstractProcessor extends AbstractProcessorLight implements ActionHook {
 public AbstractProcessor(AbstractEndpoint<?> endpoint) {
        this(endpoint, new Request(), new Response());
    }
}	

Adapter 执行service方法 将请求传递到Container容器中.
CoyoteAdapter 是Adapter 唯一的实现类,所有的功能都是在这个类中实现的.

public class CoyoteAdapter implements Adapter {
  @Override
    public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
            throws Exception {

       ...
        try {
            // Parse and set Catalina and configuration specific
            // request parameters
            postParseSuccess = postParseRequest(req, request, res, response);
            if (postParseSuccess) {
                //设置异步的支持
                request.setAsyncSupported(
                        connector.getService().getContainer().getPipeline().isAsyncSupported());
                //调用容器处理请求 以管道的形式执行 
                connector.getService().getContainer().getPipeline().getFirst().invoke(
                        request, response);
            }
			...
        }
}

Container的架构

首先看一下container的总体架构
在这里插入图片描述
Engine 引擎,一个service只能有一个engine,用来管理多个站点
Host:站点 也可以叫做虚拟主机
Context 一个应用
wrapper 每个Wrapper 封装一个Servlet
这四个容器都是自己的标准实现StandardXXXX

public final class StandardServer extends LifecycleMBeanBase implements Server

public class StandardService extends LifecycleMBeanBase implements Service 

public class StandardEngine extends ContainerBase implements Engine 

public class StandardHost extends ContainerBase implements Host 

public class StandardContext extends ContainerBase implements Context, NotificationEmitter

public class StandardWrapper extends ContainerBase implements ServletConfig, Wrapper, NotificationEmitter 

public abstract class ContainerBase extends LifecycleMBeanBase  implements Container 

每个容器都继承ContainerBase ContainerBase 继承 LifecycleMBeanBase
最终的基类就是 Lifecycle 通过监听器模式 tomcat 就可以管理各个容器的生命周期.
Container中请求的处理是通过Pipeline和Valve(管道和阀门)来实现的运用了责任链的设计默认

在这里插入图片描述
StandardPipeline 是管道的标准实现 用来管理各种valve阀门

public class StandardPipeline extends LifecycleBase
        implements Pipeline, Contained {
@Override
    public void addValve(Valve valve) {

        // Validate that we can add this Valve
        if (valve instanceof Contained)
            ((Contained) valve).setContainer(this.container);

        // Start the new component if necessary
        if (getState().isAvailable()) {
            if (valve instanceof Lifecycle) {
                try {
                    ((Lifecycle) valve).start();
                } catch (LifecycleException e) {
                    log.error(sm.getString("standardPipeline.valve.start"), e);
                }
            }
        }

        // Add this Valve to the set associated with this Pipeline
        if (first == null) {
            first = valve;
            valve.setNext(basic);
        } else {
            Valve current = first;
            while (current != null) {
                if (current.getNext() == basic) {
                    current.setNext(valve);
                    valve.setNext(basic);
                    break;
                }
                current = current.getNext();
            }
        }

        container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve);
    }


   
    @Override
    public Valve[] getValves() {

        List<Valve> valveList = new ArrayList<>();
        Valve current = first;
        if (current == null) {
            current = basic;
        }
        while (current != null) {
            valveList.add(current);
            current = current.getNext();
        }

        return valveList.toArray(new Valve[0]);

    }
}

标准阀门的实现 只有一个invoke(),执行本阀门的invoke并调用管道内下一个阀门的invoke

final class StandardEngineValve extends ValveBase {
    @Override
    public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Select the Host to be used for this Request
        Host host = request.getHost();
        if (host == null) {
            response.sendError
                (HttpServletResponse.SC_BAD_REQUEST,
                 sm.getString("standardEngine.noHost",
                              request.getServerName()));
            return;
        }
        if (request.isAsyncSupported()) {
            request.setAsyncSupported(host.getPipeline().isAsyncSupported());
        }

        // Ask this Host to process this request
        host.getPipeline().getFirst().invoke(request, response);

    }
}


final class StandardContextValve extends ValveBase {

    private static final StringManager sm = StringManager.getManager(StandardContextValve.class);

    public StandardContextValve() {
        super(true);
    }


    
    @Override
    public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Disallow any direct access to resources under WEB-INF or META-INF
        MessageBytes requestPathMB = request.getRequestPathMB();
        if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0))
                || (requestPathMB.equalsIgnoreCase("/META-INF"))
                || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
                || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // Select the Wrapper to be used for this Request
        Wrapper wrapper = request.getWrapper();
        if (wrapper == null || wrapper.isUnavailable()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // Acknowledge the request
        try {
            response.sendAcknowledgement();
        } catch (IOException ioe) {
            container.getLogger().error(sm.getString(
                    "standardContextValve.acknowledgeException"), ioe);
            request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }

        if (request.isAsyncSupported()) {
            request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported());
        }
        wrapper.getPipeline().getFirst().invoke(request, response);
    }
}

到这里tomcat的整体架构就说完了,附带了少部分源码,便于大家通过源码来理解

欢迎大家关注我的微信公众号 您的关注就是我不懈的动力
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值