tomcat

1.Tomcat Server的结构图:
  1.Service是一个集合:它由一个或者多个Connector组成,以及一个Engine,负责处理所有Connector所获得的客户请求
  2.一个Connector将在某个指定端口上侦听客户请求,并将获得的请求交给Engine来处理,从Engine处获得回应并返回客户。
       TOMCAT有两个典型的Connector,一个直接侦听来自browser的http请求(8080),一个侦听来自其它WebServer的请求(8009)
       Coyote Http/1.1 Connector 在端口8080处侦听来自客户browser的http请求
       Coyote JK2 Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求
  3. Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名
    当Engine获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该Host来处理
    Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理
 

  catalina 就是Tomcat服务器使用的 Apache实现的servlet容器的名字。
  Tomcat的核心分为3个部分:
  (1)Web容器---处理静态页面;
  (2)catalina --- 一个servlet容器-----处理servlet;
  (3)还有就是JSP容器,它就是把jsp页面翻译成一般的servlet。

 

 
2.Tomcat Server处理一个http请求的过程
  假设来自客户的请求为:http://localhost:8080/wsota/wsota_index.jsp
  1.请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
  2.Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
  3.Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
  4.Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
  5.localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
  6.Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
  7.path="/wsota"的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
  Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
  8.构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
  9.Context把执行完了之后的HttpServletResponse对象返回给Host
  10.Host把HttpServletResponse对象返回给Engine
  11.Engine把HttpServletResponse对象返回给Connector
  12.Connector把HttpServletResponse对象返回给客户browser
 
3.Tomcat组成及初始化工作原理

  Tomcat在接收到用户请求时,将会通过以上组件的协作来给最终用户产生响应。首先是最外层的Server和Service来提供整个运行环境的基础设施,而Connector通过指定的协议和接口来监听用户的请求,在对请求进行必要的处理和解析后将请求的内容传递给对应的容器,经过容器一层层的处理后,生成最终的响应信息,返回给客户端。
  Tomcat的容器通过实现一系列的接口,来统一处理一些生命周期相关的操作,而Engine、Host、Context等容器通过实现Container接口来完成处理请求时统一的模式,具体表现为该类容器内部均有一个Pipeline结构,实际的业务处理都是通过在Pipeline上添加Valve来实现,这样就充分保证整个架构的高度可扩展性。Tomcat核心组件的类图如下图所示:

  在介绍请求的处理过程时,将会详细介绍各个组件的作用和处理流程。
  本文将会主要分析Tomcat的启动流程,介绍涉及到什么组件以及初始化的过程,简单期间将会重点分析HTTP协议所对应Connector启动过程。
 
  Tomcat在启动时的重点功能如下:
  ● 初始化类加载器:主要初始化CommonLoader、CatalinaLoader以及SharedLoader;
  ● 解析配置文件:使用Digester组件解析Tomcat的server.xml,初始化各个组件(包含各个web应用,解析对应的web.xml进行初始化);
  ● 初始化连接器:初始化声明的Connector,以指定的协议打开端口,等待请求。
  不管是通过命令行启动还是通过Eclipse的WST server UI,Tomcat的启动流程是在org.apache.catalina.startup. Bootstrap类的main方法中开始的,在启动时,这个类的核心代码如下所示:

  从以上的代码中,可以看到在Tomcat启动的时候,执行了三个关键方法即init、load、和start。
  后面的两个方法都是通过反射调用org.apache.catalina.startup.Catalina的同名方法完成的,所以后面在介绍时将会直接转到Catalina的同名方法。
  首先分析一下Bootstrap的init方法,在该方法中将会初始化一些全局的系统属性、初始化类加载器、通过反射得到Catalina实例,在这里我们重点看一下初始化类加载器的方法:

  在以上的代码总,我们可以看到初始化了三个类加载器,这三个类加载器将会有篇博文进行简单的介绍。
  然后我们进入Catalina的load方法:

  在以上的代码中,关键的任务有两项即使用Digester组件按照给定的规则解析server.xml、调用Server的initialize方法。关于Digester组件的使用,后续会有一篇专门的博文进行讲解,
  而Server的initialize方法中,会发布事件并调用各个Service的initialize方法,从而级联完成各个组件的初始化。
  每个组件的初始化都是比较有意思的,但是我们限于篇幅先关注Connector的初始化,这可能是最值得关注的。
  Connector的initialize方法,核心代码如下:

  在Http11Protocol的init方法中,核心代码如下:

  我们看到最终的初始化方法最终都会调到JIoEndpoint的init方法,网络初始化和对请求的最初处理都是通过该类及其内部类完成的,所以后续的内容将会重点关注此类:

  在上面的代码中,我们可以看到此时初始化了一个ServerSocket对象,用来准备接受请求。
  如果将其比作赛跑,此时已经到了“各就各位”状态,就等最终的那声“发令枪”了,而Catalina的start方法就是“发令枪”啦:

  此时会调用Server的start方法,这里我们重点还是关注JIoEndpoint的start方法:

  从以上的代码,可以看到,如果没有在server.xml中声明Executor的话,将会使用内部的一个容量为200的线程池用来后续的请求处理。
  并且按照参数acceptorThreadCount的设置,初始化线程来接受请求。而Acceptor是真正的幕后英雄,接受请求并分派给处理过程:

  从这里我们可以看到,Acceptor接受Socket请求,并调用processSocket方法来进行请求的处理。至此,Tomcat的组件整装待命,等待请求的到来。关于请求的处理,会在下篇文章中介绍。
 
4.Tomcat对HTTP请求处理的整体流程
  站在框架的顶层的是Server和Service
  Server: 其实就是BackGroud程序, 在Tomcat里面的Server的用处是启动和监听服务端事件(诸如重启、关闭等命令。 在tomcat的标准配置文件:server.xml里面, 我们可以看到“<Server port="8005"       shutdown="SHUTDOWN" debug="0">”这里的"SHUTDOWN"就是server在监听服务端事件的时候所使用的命令字)
  Service: 在tomcat里面, service是指一类问题的解决方案。 通常我们会默认使用tomcat提供的:Tomcat-Standalone 模式的service。
       在这种方式下的service既给我们提供解析jsp和servlet的服务, 同时也提供给我们解析静态文本的服务。
  Connector: Tomcat都是在容器里面处理问题的, 而容器又到哪里去取得输入信息呢?
  Connector就是专干这个的。 他会把从socket传递过来的数据, 封装成Request, 传递给容器来处理。
  通常我们会用到两种Connector,一种叫http connectoer, 用来传递http需求的。 另一种叫AJP, 在我们整合apache与tomcat工作的时候, apache与tomcat之间就是通过这个协议来互动的。
  (说到apache与tomcat的整合工作, 通常我们的目的是为了让apache 获取静态资源, 而让tomcat来解析动态的jsp或者servlet。)
 
5.Tomcat 与 Servlet
  Tomcat(最直接产生原因:可以直接提供Web服务的JSP服务器,当然同时也支持Servlet):
  Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat 部分是Apache 服务器的扩展,但它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。
  另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。
 
  Jsp 与 Servlet:
    JSP容器对JSP文件进行自动解析并转换成Servlet类(jsp to servlet 编译过程)来交给WEB服务器运行。其中jsp与servlet是没有本质区别的,因为jsp最后在提交的时候还是要编译成servlet类。
    JSP是Servlet技术的扩展,是基于java servlet技术,本质上是Servlet的简易方式,更强调应用的外表表达。
    Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。
    而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,servlet主要用于控制逻辑。
    当我们访问一个JSP页面的时候,这个文件首先会被JSP引擎翻译为一个Java源文件,其实就是一个Servlet,并进行编译,然后像其他Servlet一样,由Servlet引擎来处理。
    Servlet引擎装载这个类,处理来自客户的请求,并把结果返回给客户,以后再有客户访问这个页面的时候,只要该文件没有发生过更改,JSP引擎就直接调用已经装载的Servlet。
    如果已经做过修改的话,那就会再次执行以上过程,翻译、编译并装载。
 
  Servlet的生命周期
  servlet容器负责加载和实例化servlet 。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。 Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。
  · 只有一个servlet对象
  ·第一次请求的时候被初始化,只一遍
  · 初始化后先调用init方法,只一遍
  · 每个请求,调用一遍serviceàserviceàdoGet/doPost。以多线程的方式运行
  · 不要在servlet中设计成员变量。
  · 卸载前servlet容器调用destroy方法
 
 

6.Tomcat多线程是怎么回事呢?
  Tomcat内部有一个线程池,如果这个servlet的访问量很大,一下子有100个人,全部过来了,tomcat 不会帮我们new出100个HelloWorldServlet的对象出来的,自始至终,这个对象只有一个,这个对象会提前准备出若干个线程,但是让一个线程跑起来,是有开销的,有时开销我们都会感觉出来的,因为线程比较耗时,所以,让线程提前跑起来,这些跑起来的线程组成一个线程池。
客户端的请求,比如,第一个请求过来了,tomcat会从线程池,分配一个空闲的线程,处理这个请求,如果同时有第二个客户端的请求过来了,tomcat从线程池里分配另外一个闲着的线程,处理第二个请求,也就是说,以是这种并发的方式进行处理的,多线程的方式处理的。
  每一个线程,都是访问同一个servlet对象,都是通过这一个对象的引用,调用service()方法。

  Tomcat默认servlet是单例多线程模式。
  当容器收到一个Servlet请求,调度线程从线程池中选出一个工作者线程,将请求传递给该工作者线程,然后由该线程来执行Servlet的service方法。

  当这个线程正在执行的时候,容器收到另外一个请求,调度线程同样从线程池中选出另一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet.

  当容器同时收到对同一个Servlet的多个请求的时候,那么这个Servlet的service()方法将在多线程中并发执行。
  对于Tomcat可以在server.xml中通过元素设置线程池中线程的数目。
  不过提醒题主一句,静态变量,这可不是线程安全的哦,要注意哇

 

7.Tomcat集群
  多个tomcat要一起协同工作有几种办法,可以考虑的方案有以下几个:
  1. 使用tomcat自带的cluster方式,多个tomcat间自动实时复制session信息,配置起来很简单。但这个方案的效率比较低,在大并发下表现并不好。
  2. 利用nginx的基于访问ip的hash路由策略,保证访问的ip始终被路由到同一个tomcat上,这个配置更简单。但如果应用是某一个局域网大量用户同时登录,这样负载均衡就没什么作用了。
  3. 利用memcached把多个tomcat的session集中管理,前端在利用nginx负载均衡和动静态资源分离,在兼顾系统水平扩展的同时又能保证较高的性能。

 

8.Tomcat 与 Apache

  1.WEB服务器:
  理解WEB服务器,首先你要理解什么是WEB?WEB你可以简单理解为你所看到的HTML页面就是WEB的数据元素,处理这些数据元素的应用软件就叫WEB服务器,如IIS、apache。 WEB服务器与客户端打交道,它要处理的主要信息有:session、request、response、HTML、JS、CS等。
  
  2.应用服务器:
  应用服务器如JSP,处理的是非常规性WEB页面(JSP文件),他动态生成WEB页面,生成的WEB页面在发送给客户端
  (实际上当应用服务器处理完一个JSP请求并完成JSP生成HTML后它的任务就结束了,其余的就是WEB处理的过程了)。
  WEB服务器与应用服务器的联系:
  WEB服务器一般是通用的,而应用服务器一般是专用的,如Tomcat只处理JAVA应用程序而不能处理ASPX或PHP。而Apache是一个WEB服 务器f(HTTP服务器),后来连接Tomcat应用服务器来支持java。
 
 
  apache与tomcat的区别:
  1. Apache是web服务器,Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展。
  2. Apache和Tomcat都可以做为独立的web服务器来运行,但是Apache不能解释java程序(jsp,serverlet)。
  3. Apache是普通服务器,本身只支持html即普通网页。不过可以通过插件支持php,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源。反之不然)
  4. 两者都是一种容器,只不过发布的东西不同:Apache是html容器,功能像IIS一样;Tomcat是jsp/servlet容器,用于发布jsp及java的,类似的有IBM的webshere、EBA的Weblogic,sun的JRun等等。
  5. Apache和Tomcat是独立的,在通一台服务器上可以集成。
    打个比方:Apache是一辆卡车,上面可以装一些东西如html等。但是不能装水,要装水必须要有容器(桶),Tomcat就是一个桶(装像Java这样的水),而这个桶也可以不放在卡车上。
    Apache只支持静态网页,但像asp,php,cgi,jsp等动态网页就需要Tomcat来处理。
  6.Apache和Tomcat整合使用:如果客户端请求的是静态页面,则只需要Apache服务器响应请求;如果客户端请求动态页面,则是Tomcat服务器响应请求;
   因为jsp是服务器端解释代码的,这样整合就可以减少Tomcat的服务开销 。

转载于:https://www.cnblogs.com/novalist/p/6398706.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值