注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭州 QA Team

务实 专注 分享 做有态度的QA

 
 
 
 
 

日志

 
 

JavaWeb开发手记:服务器启动时加载servlet  

来自隋相   2015-11-17 15:04:57|  分类: 默认分类 |举报 |字号 订阅

  下载LOFTER 我的照片书  |
       在我的java web工程当中,由于场景不同、需求不同不断出现各种复杂难解的问题。近期较有突破的一个问题就是页面加载速度过慢,解决办法是在服务器启动时加载servlet。
       背景介绍:在之前的java web开发过程中,遇到的最大的一个技术瓶颈是页面加载速度太慢,粗略地估计了下某个页面加载的速度要大约8秒钟,这实在不能令人接受。从首页index.jsp的某个按钮按下后打开链接,到后台执行servlet然后分发给另一个jsp显示的过程如下简图所示。我们可以看到首页跳转链接至某一个servlet是由web.xml配置文件中关于servlet路由部分所指定的;简单理解,serlvet本质上就是一个java类,只不过它继承了特定类且有特定方法而已;servlet中可以处理包括对关键类的初始化以及关键方法的调用,结束后可以将产生的数据设置属性setAttribute通过分发至jsp页面,最后jsp将获取到的属性及数据通过EL表达式予以展示即可。
JavaWeb开发手记:服务器启动时加载servlet - 网易杭州QA - 网易杭州 QA Team
之前的思路就是这样,导致watch.jsp页面加载速度极慢的罪魁祸首就是servlet对关键类和关键方法的调用速度较慢导致的。而这些类和方法中由于数据量多且方法复杂,速度较慢在所难免,另外这些类和方法主要是监测后台数据的合理性,在一次检测周期内不会有变化,因而对方法的实时性没有要求。综上所述,能否在服务器启动的时候就加载该servlet,这样在页面跳转的时候只需要获取到属性数据即可。

解决方法是:设置web.xml中<load-on-startup>属性值,然后编写servlet的init()方法。具体分步讨论:

一、在服务器启动时就加载某servlet,是通过web.xml中关于某servlet的<load-on-startup>属性值来设定的。
官方关于load-on-startup属性是这样介绍的:
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses.   If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.
翻译过来就是:load-on-startup是在web应用启动时加载该servlet并调用她的Init方法。这个load-on-startup属性值必须是一个整数,用来作为该servlet被加载的顺序。如果该属性值被设定为负数或者没有设定,那么只有当显式调用该servlet时容器才会加载它。反之,当该属性值设定为正数或者0,那么容器必须在应用部署的时候就加载该servlet。属性值越小,加载的优先级越高。如果多个servlet设定同样的load-on-startup属性值,那么容器会随机安排这几个servlet的加载顺序。
也就是说,现在web.xml可以写成这样:
JavaWeb开发手记:服务器启动时加载servlet - 网易杭州QA - 网易杭州 QA Team
 servlet属性包括servlet-name:该名字自己指定,servlet-class:该servlet对应的class,init-param:提供给该servlet加载时的初始化参数值,load-on-startup:应用启动时即加载该servlet的顺序(设定为0,优先级最高),servlet-mapping:指定访问该servlet的路由url(注意servlet-name要与之前的保持一致)。

二、设置好了web.xml,接下来就是编写servlet的init()方法。
init方法其实就是将原先写在doGet()方法中的代码移植过来即可,doGet()方法只保留分发给特定jsp页面的语句。即:
JavaWeb开发手记:服务器启动时加载servlet - 网易杭州QA - 网易杭州 QA Team
 另外一点需要注意的是,原先写在doGet方法中的setAttribute属性值,如果是设定为request属性,现在因为没有声明request对象,因而改为设定为ServletContext属性值。代码如下:
JavaWeb开发手记:服务器启动时加载servlet - 网易杭州QA - 网易杭州 QA Team
 
上面两步搞定之后,现在我们再将工程重新打包,并部署至服务器上。服务器启动过程需要10秒钟左右,然后再打开浏览器链接。
我们惊奇地发现再点击首页的某个按钮,跳转至另一个页面的时候没有任何停顿和迟疑了!
当然,这种服务器启动的时候加载servlet的方法比较适合实时性要求不高的场景,如果对实时性要求很高,需要不断刷新的场景,就需要再结合其他的策略甚至是前端方法(比如Ajax)一起来改进了。

 
  评论这张
 
阅读(583)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016