在特定时间开放抢票的网站,常常会有流量爆炸的问题。这时候可以透过服务器的异步处理来解决。
让买票处理使用主线程,而需要等待的出票处理使用异步线程。
要使用异步线程,需在Servlet前注解支持异步处理。然後利用request物件叫出AsyncContext物件。
这时response回应就会等到AsyncContext.complete()结束时才被送出。关键程序码如下:
@WebServlet(urlPatterns="/AsynSvl",asyncSupported=true)
AsyncContext ac = request.startAsync();
ServletResponse res = ac.getResponse();
新建一个测试案例
"<body>
<input type=""button"" value=""测试"" onclick=""submit()""><br>
<span id=""info"" style=""color:red;font-size:12px""></span>
</body>"
"<%
String path = request.getContextPath();
String basePath = request.getScheme() + ""://"" + request.getServerName()
+ "":"" + request.getServerPort() + path + ""/"";
%><script src=""http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.4.min.js""></script>
<script type=""text/javascript"">
function submit(){
var url = ""<%=basePath%>AsynSvl"";
$.ajax({
type:""get"",
url:url,
success:function(msg){
document.getElementById(""info"").innerHTML=msg;
}
})
}
</script>"
(余略…)
@WebServlet(urlPatterns="/AsynSvl",asyncSupported=true)
public class AsynSvl extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext ac = request.startAsync();
ServletResponse res = ac.getResponse();
res.setCharacterEncoding("utf-8");
PrintWriter out = res.getWriter();
try {
Thread.sleep(3000);
}catch(Exception e){
}
out.println("异步处理OK");
out.flush();
out.close();
}
(余略…)
}
如果异步处理的url有经过过滤器(Filter),则过滤器也要设定支持异步。
@WebFilter(urlPatterns = "/*",
asyncSupported=true,
initParams = {@WebInitParam(name = "encoding",value = "utf-8")})
直接拜访jsp网址,然後点选测试。
http://localhost:8080/Hello/main/asynTest.jsp
成功的话会看到"异步处理OK"字样
利用异步监听器可以检测异步处理的执行状况。监听器可能会收到以下几种结果,可以设定相应的处理:
修改刚才的AsynSvl,在里面添加一个MyListener类。
public class AsynSvl extends HttpServlet {
class MyListener implements AsyncListeren{
public void onComplete(AsyncEvent e) throws IOException{
System.out.println(e.getAsyncContext().hashCode() + "onComplete");
}
public void onError(AsyncEvent e) throws IOException{
System.out.println(e.getAsyncContext().hashCode() + "onError");
}
public void onStartAsync(AsyncEvent e) throws IOException{
System.out.println(e.getAsyncContext().hashCode() + "onStartAsync");
}
public void onTimeout(AsyncEvent e) throws IOException{
System.out.println(e.getAsyncContext().hashCode() + "onTimeout");
}
}
(中略…)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext ac = request.startAsync();
ac.addListener(new MyListener());
ServletResponse res = ac.getResponse();
res.setCharacterEncoding("utf-8");
PrintWriter out = res.getWriter();
try {
Thread.sleep(3000);
}catch(Exception e){
}
out.println("异步处理OK");
out.flush();
out.close();
ac.complete();
//ac.setTimeout(5000);
}
}
建立了MyListener类之後别忘了在doGet()里面添加这行ac.addListener(new MyListener());
不然待会儿测试的时候,脑海中就会响起五月天的听不到
当执行到ac.complete()时,监听器会在後台印出onComplete。
如果把这行注解掉,那麽预设等待30秒後,会得到onTimeout及onComplete。
如果注解掉ac.complete()後,再添加ac.setTimeout(5000),则五秒後会得到onTimeout及onComplete。
<<: 什麽是零信任(What is Zero Trust)?
>>: .net framework 4.5.2 升级到 .net framework 4.6.2 笔记
前言 当一个网站取得 Public IP 与 internet 连接时,也就表示网站正开始面对来自全...
tags: 2021铁人赛 React 在Card元件中有使用到useState,是React中一个...
大家好我是乌木白,今日要和大家分享如何安装Git的环境! 如何安装Git的环境 安装在 Windo...
虽然一讲到敏捷开发、DevOps 时就很常听到 CI/CD 这些词汇,不过到底什麽是 CI?又什麽是...