集群中Web页面分批输出的问题

为了提高性能和减少用户等待时间,我们常用response.flushBuffer方法来分批输出已经转换好的页面。这样内容可以分块逐步显示在网页上,用户不用长时间面对一个空白的页面等待。但在集群系统中,当某个服务器瘫痪从而引起服务迁移情况下,问题就来了,用户可能会看到重复的内容。

 

这里我们做个实验,写如下一段代码:

      response.setContentType("text/html");
      response.setContentLength(500);

 

        //不同的机器用不同的颜色和名字

        String color=this.getInitParameter("Color");
        String server=this.getInitParameter("Server");
       
        PrintWriter writer = response.getWriter();
        writer.println("<html><body>");
        writer.println("<h1><font color=/"" + color + "/">Session serviced by tomcat " + server + "</font></h1>");
       
        writer.println("<table aligh=/"center/" border=/"1/">");
        writer.println("<tr><td>Session ID</td><td>");
        writer.println(request.getSession(true).getId());
        writer.println("</td>");
               
        writer.println("</tr><tr><td>Created on</td><td>");
        writer.println(request.getSession().getCreationTime());
        writer.println("</td></tr></table>");
       
        writer.println("<form method=/"POST/" action=/"LongTask/">");
        writer.println("<Input name=/"test/" value=/"/">");
        writer.println("<INPUT TYPE=submit name=/"submit/" value=/"update/">");
        writer.println("</form>");

 

        //提前把前面的内容输出

        writer.flush();

 

        Object ob = request.getParameter("test");
        if (ob!=null) {
            request.getSession().setAttribute("test",ob);
            try {
                String time=this.getInitParameter("WaitTime");

                  //这里模拟一个长时间的任务,以便有机会手动把一个机器停掉
                Thread.sleep(Integer.parseInt(time));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }       
        }
        writer.println(request.getSession().getAttribute("test"));
        writer.flush();
        writer.close();

        writer.println("</body></html>");

 

我们用Apache 2.2 + mod_jk + Tomcat 6.0 (In-memory session replication)来架设集群。注意要在httpd.conf的配置中设置Flush选项:

JkWorkersFile conf/workers.properties
JkOptions +FlushPackets
JkMount /examples/jsp/* bal1
JkMount /jkstatus/ stat1

mod_jk的配置

worker.list = bal1,stat1

worker.Tomcat6A.type = ajp13
worker.Tomcat6A.host = localhost
worker.Tomcat6A.port = 8009
worker.Tomcat6A.lbfactor = 10

worker.Tomcat6B.type = ajp13
worker.Tomcat6B.host = localhost
worker.Tomcat6B.port = 8010
worker.Tomcat6B.lbfactor = 10

worker.Tomcat6C.type = ajp13
worker.Tomcat6C.host = localhost

worker.Tomcat6C.port = 8011
worker.Tomcat6C.lbfactor = 10

worker.bal1.type = lb
worker.bal1.sticky_session = 1
worker.bal1.balance_workers = Tomcat6A, Tomcat6B, Tomcat6C

worker.stat1.type = status

 

我们把上段代码编译成名字为LongTask的servlet,并放到Tomcat自带的例子examples下面。架设三个Tomcat实例在三台机器上。(本文为了方便都放到一台机器localhost上)。当一台机器正在处理请求时,我们手动停掉它。测试结果如下:

 

 

图1:发生故障前

 

图2:发生故障后

 

除了数据重复外,Session数据也丢失了(原因还未知). 但如果关闭分批输出,则没有这些问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值