异步请求性能下降

时间:2015-02-09 02:56:16

标签: jetty tomcat7 servlet-3.0

我正在为机器人竞赛制作一个基于网络的评分系统。当得分时,我想刷新每个观看比赛的人的页面。我的代码正在“正确”工作。

我的问题是,当我测试并打开大约5到10个网页时,我要求的任何其他页面在我关闭某些页面之前都不会被处理。我认为发生的事情是request.startAsync()没有释放线程而且它正在无限期地等待。

我已经在Jetty 9.2.7.v20150116和Tomcat7上进行了测试。两者都有相同的缓慢行为。

// Display a game with all it's events
// http://stackoverflow.com/questions/10878243/sse-and-servlet-3-0

@WebServlet(urlPatterns = { "/gameRefresh" }, asyncSupported = true)
public class GameRefreshController extends HttpServlet 
{
    private static final long serialVersionUID = -6890088129187673292L;

    private static AtomicBoolean refreshNeeded = new AtomicBoolean();

    private final Queue<AsyncContext> ongoingRequests = new ConcurrentLinkedQueue<>();
    private ScheduledExecutorService service;

    public static void setRefreshNeeded(boolean value)
    {
        refreshNeeded.set(value);
    }

    @Override
    public void init(ServletConfig config) throws ServletException 
    {
        final Runnable notifier = new Runnable() 
        {
            @Override
            public void run() 
            {
                // Don't refresh if it's not needed.
                if(!refreshNeeded.get())
                {
                    return;
                }
                // This var is set by the backend when an event occurs.
                setRefreshNeeded(false);

                final Iterator<AsyncContext> iterator = ongoingRequests.iterator();
                // not using for : in to allow removing items while iterating
                while (iterator.hasNext()) 
                {
                    AsyncContext asyncContext = iterator.next();
                    final ServletResponse servletResponse = asyncContext.getResponse();
                    PrintWriter out;
                    try 
                    {
                        out = servletResponse.getWriter();
                        String toOutput = "data: refresh\n\n";
                        out.write(toOutput);
                        out.checkError();
                    } 
                    catch(IOException exception)
                    {
                        // iterator is always removed because we refresh the whole page.
                    }
                    finally
                    {
                        iterator.remove();
                    }
                }
            }
        };
        service = Executors.newScheduledThreadPool(1);
        service.scheduleAtFixedRate(notifier, 1, 1, TimeUnit.SECONDS);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");
        request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
        final AsyncContext asyncContext = request.startAsync();
        asyncContext.setTimeout(0);
        asyncContext.addListener(new AsyncListener() 
        {
            @Override
            public void onComplete(AsyncEvent event) throws IOException 
            {
                ongoingRequests.remove(asyncContext);
            }

            @Override
            public void onTimeout(AsyncEvent event) throws IOException 
            {
                ongoingRequests.remove(asyncContext);
            }

            @Override
            public void onError(AsyncEvent event) throws IOException 
            {
                ongoingRequests.remove(asyncContext);
            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException 
            {
            }
        });
        ongoingRequests.add(asyncContext);
    }
}

0 个答案:

没有答案