Web服务器+Servlet容器理解
http并发请求过来,servlet容器(tomcat里面的容器,现在的tomcat已经不仅仅是容器)创建多个线程去调用javaweb程序的servlet
(一个function是可以被多线程调用)
一 web服务器
apache ,lighttpd,nginx,iis
1. lighttpd
lighttpd是一个具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。lighttpd是众多OpenSource轻量级的web server中较为优秀的一个。支持FastCGI, CGI, Auth, 输出压缩(output compress), URL重写, Alias等重要功能。
2.apache
apache是世界排名第一的web服务器
APACHE是一个web服务器环境程序 启用他可以作为web服务器使用 不过只支持静态网页. 但asp,php,cgi,jsp等动态网页的就不行.
如果要在APACHE环境下运行jsp 的话就需要一个解释器来执行jsp网页, 而这个jsp解释器就是TOMCAT, 为什么还要JDK呢?因为jsp需要连接数据库的话就要jdk来提供连接数据库的驱程,所以要运行jsp的web服务器平台就需要APACHE+TOMCAT+JDK 整合的好处是:如果客户端请求的是静态页面,则只需要Apache服务器响应请求如果客户端请求动态页面,则是Tomcat服务器响应请求因为jsp是服务器端解释代码的,这样整合就可以减少Tomcat的服务开销 .
IIS是微软公司的Web服务器。主要支持ASP语言环境.
Tomcat是Java Servlet 2.2和JavaServer Pages 1.1技术的标准实现,是基于Apache许可证下开发的SJP语言环境容器,严格得说不能算是一个WEB服务器,而是Apache服务适配器。
tomcat主要的任务不是WEB服务,而是支持JSP语言环境.
apache是web服务器,而Tomcat是应用(java)服务器,Tomcat只是一个servlet(jsp也翻译成servlet)容器,也可以认为是apache的扩展,但是可以独立于apache运行。
3.nginx
nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.
Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配 Lighttpd的性能,同时还没有Lighttpd的内存泄漏问题,而且Lighttpd的mod_proxy也有一些问题并且很久没有更新。
总结:web服务器提供静态内容的展现。如果客户端需要动态内容需要跟web程序交互,需要用到servlet容器。
建议方案:
Apache 后台服务器(主要处理php及一些功能请求 如:中文url)
Nginx 前端服务器(利用它占用系统资源少得优势来处理静态页面大量请求)
Lighttpd 图片服务器
二 servlet容器
也可以说是web容器
Servlet容器是用作运行Java web程序的,主要分为两类,一种是独立web容器,也可以称作Web服务器,只能运行Web程序,Tomcat就是这种服务器。另一种是与其他JavaEE容器混合在一起的容器,Web容器负责运行Web程序,其他容器负责EJB等程序,如WebLogic等。
Servlet容器是Web服务器和servlet进行交互的必不可少的组件。
1. 什么是Servlet?
Servlet是在javax.serlvet包中定义的一个接口。并且servlet和URL是对应的
它声明了servlet生命周期中必不可少的三个方法-init()、service()和destroy()。每个servlet(无论是在SDK中定义的,或是自定义的)都必须实现这三个方法,而且由服务器在特定的时刻调用。
1. init()方法在servlet生命周期的初始化阶段被调用。
2. 调度线程(Dispatchaer Thread) 调度它管理下线程池中等待执行的线程(Worker Thread)给请求者;
3. 线程执行service()方法。每个请求的处理都在独立的线程中进行。Web服务器对每个请求都会调用一次service()方法。service()方法判断请求的类型,并把它转发给相应的方法进行处理。
4. 当需要销毁servlet对象时,就要调用destroy()方法。该方法释放被占用的资源。
和所有的Java程序一样,servlet运行在JVM中。引入servlet容器是为了处理复杂的HTTP请求。Servlet容器负责servlet的创建、执行和销毁。
线程池工作逻辑
工作者线程Work Thread: 执行代码的一组线程。
调度线程Dispatcher Thread: 每个线程都具有分配给它的线程优先级,线程是根据优先级调度执行的。 线程池实际上是一系列的工作者线程集合。Servlet使用一个调度线程来管理工作者线程。
当容器收到一个Servlet请求,调度线程从线程池中选出一个工作者线程,将请求传递给该工作者线程,然后由该线程来执行Servlet的service方法。当这个线程正在执行的时候,容器收到另外一个请求,调度线程同样从线程池中选出另一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet.当容器同时收到对同一个Servlet的多个请求的时候,那么这个Servlet的service()方法将在多线程中并发执行。
Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间,对于Tomcat可以在server.xml中通过<Connector>元素设置线程池中线程的数目。
2. Servlet容器和Web服务器如何处理一个请求?
1. Web服务器接收到HTTP请求
2. Web服务器将请求转发给servlet容器
3. 如果容器中不存在所需的servlet(url对应Servlet),容器就会检索servlet,并将其加载到容器的地址空间中,通常根据web.xml的配置来加载
4. 容器调用servlet的init()方法对servlet进行初始化(该方法只会在servlet第一次被载入时调用)
5. 容器调用servlet的service()方法来处理HTTP请求,service()方法检查HTTP请求类型(GET、POST、PUT、DELETE等),然后相应调用doGet()、doPost()、doPut()、doDelete()等方法。 servlet会被保留在容器的地址空间中,继续处理其他的HTTP请求
6. Web服务器将动态生成的结果返回到正确的地址。
容器如何处理请求
client点击一个URL,其URL指向一个servlet而不是静态界面。
容器识别出这个请求索要的是一个servlet,所以创建两个对象:
httpservletrequest
httpservletresponse
容器根据请求中的URL找到对应的servlet,为这个请求创建或分配一个线程,并把两个对象request和response传递到servlet线程中。
容器调用servlet的service()方法。根据请求的不同类型,service()方法会调用doGet()或者doPost()方法。
doGet()方法生成动态页面,然后把这个页面填入到response对象中,此时,容器仍然拥有response对象的引用。
线程结束。容器把response对象转换成http响应,传回client,并销毁response和request对象。
注意:单实例多线程
一个Servlet同一时刻只有一个实例。
当多个请求发送到同一个Servlet,服务器会为每个请求创建一个新线程来处理。
2.1、Servlet的线程安全问题
当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。
需要注意:
1. 在Servlet中可以定义常量
2. 如果定义的变量只用查询操作,可以不加同步控制
3. 被Servlet调用的类中(如值对象、领域模型类)中是否可以安全的使用实例变量?
如果你在每次方法调用时新建一个对象,再调用它们的方法,则不存在同步问题。因为它们不是多个线程共享的资源,只有共享的资源才需要同步,而Servlet的实例对于多个线程是共享的,这也是为什么我们平时开发的web程序大多情况下单线程即可的原因。
3 Filter、interceptor、Listener
3.1 Filter
依赖于servlet容器。在实现上,基于函数回调
实现javax.servlet.Filter接口.Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链.
filter和servlet同时存在,且容器初始化都要加载,则先加载filter再加载servlet的init方法。
servlet和filter的关系:
如果请求的url既匹配filter又匹配servlet,并且servlet的init方法没有在容器初始化加载,则先加载匹配的servlet的init方法,再按顺序执行filter方法,最后再执行servlet的service方法
3.2 interceptor
基于JAVA的反射机制
与过滤器十分相似,通过层层拦截,处理用户的请求和响应。
拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。
3.3 listener
职责如概念。
servlet2.4规范中提供了8个listener接口,可以将其分为三类,分别如下:
第一类:与servletContext有关的listner接口。包括:ServletContextListener、ServletContextAttributeListener
第二类:与HttpSession有关的Listner接口。包括:HttpSessionListner、HttpSessionAttributeListener、HttpSessionBindingListener、 HttpSessionActivationListener;
第三类:与ServletRequest有关的Listener接口,包括:ServletRequestListner、ServletRequestAttributeListener
servlet、filter都是针对url之类的,而listener是针对对象的操作的,如session的创建,session.setAttribute的发生,在这样的事件发生时做一些事情。
参考:
https://blog.csdn.net/yw_1207/article/details/78706701