(三)Web模块:【2】Web3.0 新特性之异步处理
一、servlet3.0异步处理
在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求。 即每一次Http请求都由某一个线程从头到尾负责处理。 如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。即便是像Spring、Struts这样的高层框架也脱离不了这样的桎梏,因为他们都是建立在Servlet之上的。为了解决这样的问题,Servlet 3.0引入了异步处理,然后在Servlet 3.1中又引入了非阻塞IO来进一步增强异步处理的性能。 在以前的servlet中,如果作为控制器的servlet调用了一个较为耗时的业务方法,则servlet必须等到业务执行完后才会生成响应,这使得这次调用成了阻塞式调用,效率比较差。 Servlet3.0支持异步处理支持,Servlet接收到请求之后,可能首先需要对请求携带的数据进行一些预处理;接着,Servlet线程将请求转交给一个异步线程来执行业务处理,线程本身返回至容器,此时Servlet还没有生成响应数据,异步线程处理完业务以后,可以直接生成响应数据(异步线程拥有ServletRequest和ServletResponse对象的引用),或者将请求继续转发给其他Servlet。二、同步Servlet
@WebServlet(value = "/sync")
public class HelloSyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(Thread.currentThread()+" start..."+"==>"+System.currentTimeMillis());
try {
sayHello();
} catch (Exception e) {
e.printStackTrace();
}
resp.getWriter().write("hello...");
System.out.println(Thread.currentThread()+" end..."+"==>"+System.currentTimeMillis());
}
public void sayHello() throws Exception {
System.out.println(Thread.currentThread()+" processing...");
Thread.sleep(3000);
}
}
三、配置异步的 servlet 与 filter
(1)通过注解asyncSupported=true实现
(2)通过web.xml配置
<servlet>
<servlet-name>asyncservlet-name>
<servlet-class>com.njf.servlet.AsyncServletservlet-class>
<async-suppored>trueasync-suppored>
servlet>
<servlet-mapping>
<servlet-name>asyncservlet-name>
<url-pattern>/asyncurl-pattern>
servlet-mapping>
对于使用传统的部署描述文件web.xml配置Servlet和过滤器的情况,Servlet3.0为
对于使用Servlet3.0提供的@WebServlet和@WebFilter进行Servlet或过滤器配置的情况,这两个标注都提供了asyncSupported属性,默认该属性的取值为false,要启动异步处理支持,只需将该属性设置为true即可。