servlet的两个标签:
<load-on-startup>x<load-on-startup>
<async-supported>true</async-supported>
问题描述:将webSocket引入到项目中来的过程中需要配置一个servlet,而原本项目使用的框架是spring+mybatis+jersey,采用了spring+jersey来构建RESTFul Web服务,所以已经配置了如下servlet:
这里也对jersey和RESTFul Web服务简单的解释下,REST是一组架构约束条件和原则,满足这些约束和原则的应用程序或者是设计就可以称为RESTFul。
Web 应用最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URL(Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的界面,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。更多有关RESTFul的信息
而jersey是JAX-RS的参考实现,主要包括三部分:1、核心服务器(Core Server):通过提供JSR 311中标准化的注释和API标准化,可以用直观的方式开发RESTful Web服务.2、核心客户端(Core Client):Jersey客户端API可以让我们与REST服务轻松通信.3、集成(Integration):Jersey还提供可以轻松集成Spring,Guice,Apache Abdera的库
<span style="font-size:14px;"><servlet>上述配置的路径只能是rs/./.,无法满足webSocket中这种/websocket/*路径的处理,所以在配置的过程中需要设置servlet初始化的优先级。servlet提供了<load-on-startup>x<load-on-startup>,其中x是一个int型的值,一般为0,1,2,3...当然也可以为负数,如果为负数的话或者没有指定的时候表示容器在该servlet被选择时才会加载,当值为0或者正数表示服务启动了以后就会加载该servlet。这个时候值越小表示优先级越高。
<servlet-name>jerseyServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.whut.monitor.business,org.whut.platform.business</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jerseyServlet</servlet-name>
<url-pattern>/rs/*</url-pattern>
</servlet-mapping></span>
servlet 还提供了<async-supported>的子标签,这么貌似是servlet3.0才支持的,说来惭愧,项目中用的servlet版本还是:
<span style="font-size:14px;"><servlet.api.version>2.5</servlet.api.version></span>这个标签主要是提供异步处理支持,有了这个特性以后,servlet线程不再需要一直阻塞,只到业务处理完毕才能输出响应,最后才结束该servlet线程,有了异步支持,servlet在接收到请求之后,可以将耗时的操作委派给另一个线程来完成,自己在不生成响应的情况下返回至容器,这样一来对于业务处理耗时的情况将大大的减少服务器资源的占用,并且提供并发处理的速度。
具体来说,没有这个异步支持之前,一个普通的servlet的主要工作流程大致这样的:首先,servlet接受到请求之后,可能需要对请求携带的数据进行一些预处理;接着,调用业务接口的某些方法,用来完成业务处理;最后根据处理的结果提交相应,servlet线程结束。第二步的业务处理是最耗时的,主要体现在数据库操作,以及其他的跨网络调用的过程等,在这个过程中,servlet一直处于阻塞的状态,知道业务方法执行完毕,在处理业务的过程中,servlet资源一直被占用得不到释放,对于并发较大的应用,这有可能造成性能的瓶颈。对于这个问题,我们项目中貌似是没有处理的,一般貌似都是采用私有解决方案来提前结束servlet线程,并及时释放资源。
有了异步处理以后,servlet的工作流程如下:首先,servlet接受到请求,对请求携带的数据进行一些预处理;接着,serlvet线程将请求转交给一个异步线程来执行业务处理,线程本身返回到容器,此时servlet还没有生成响应数据,异步线程处理完业务以后可以直接生成响应数据(异步线程拥有ServletRequest和ServletResponse对象的引用),或者将请求继续转发给其他servlet,这样一来,servlet线程不再是一直处理阻塞状态以等待业务逻辑的处理,而是启动异步线程之后就可以立即返回。
servlet默认不是异步的,如果需要异步支持,需要添加标签:<async-supported>true</async-supported>