【问题标题】:How do I make "simple" throughput servlet-filter?如何制作“简单”的吞吐量 servlet 过滤器?
【发布时间】:2011-02-23 22:42:05
【问题描述】:

我正在寻找一个过滤器,它可以给我两件事:每分钟的请求数和每分钟的平均响应时间。我已经得到了个人读数,我只是不知道如何将它们相加。

我的过滤器捕获每个请求,并记录每个请求所花费的时间:

public void doFilter(ServletRequest request, ...()  
{       
    long start = System.currentTimeMillis(); 
    chain.doFilter(request, response);
    long stop = System.currentTimeMillis();

    String time = Util.getTimeDifferenceInSec(start, stop);
}

这些信息将用于创建一些漂亮的 Google Chart 图表。我不想将数据存储在任何数据库中。只是一种在请求时获取当前数字的方法

因为这是一个大容量的应用程序;低开销是必不可少的。

我假设我的应用程序服务器不提供此信息。

【问题讨论】:

  • 您能详细说明一下吗?答案“静态变量”可能只是误解了您需要的结果。
  • “这是一个大容量应用程序;低开销是必不可少的。”那么,当市场上有工具经过适当的工具、数据管理和可视化测试时,为什么要自己编写代码呢?当有人要求 X、Y 和 Z 时会发生什么。专注于应用程序开发并考虑使用性能专​​家创建的工具来简化初始工作和未来的维护。其中一些工具甚至提供带有开放 API 的无头(无 UI)运行时,供您将其集成到您自己的管理仪表板中。查看opencore.jinspired.com
  • @William Louth 您的评论很有价值。我想你可以把它写成答案。
  • 旁注:您应该使用nanoTime() 来测量经过的时间,而不是currentTimeMillis()。有关这方面的背景信息,请参阅 Kevin Bourrillion 的 answer
  • 在低开销和低占用空间之间进行权衡。我不想重新发明轮子或任何东西。只是一种简单的方法来衡量这些东西。

标签: java performance jakarta-ee servlet-filters


【解决方案1】:

我曾经做过类似的事情。如果我没记错的话,我有类似的东西

public class StatisticsFilter implements ... 
{
    public static Statistics stats;

    public class PeriodicDumpStat extends Thread
    {
       ...
    }

    public void doFilter(ServletRequest request, ...()  
    {       
      long start = System.currentTimeMillis(); 
      chain.doFilter(request, response);
      long stop = System.currentTimeMillis();
      stats.add( stop - start ); 
    }

    public void init()
    {
       Thread t = new PeriodicDumpStat();
       t.setDaemon( true );
       t.start();
    }
}

(这只是一个草图)

确保Statistics 对象正确同步,因为它将被并发访问。

我有一个后台 DumpStatistics 线程,它定期将统计信息转储到 XML 文件中,以便稍后处理。为了更好地封装,我将线程作为内部类。你当然也可以使用Runnable。正如@Trevor Tippins 所指出的,将线程标记为daemon thread 也很好。

我还使用了谷歌图表,实际上还有另一个ShowStatisticsServlet 可以将 XML 文件转换成漂亮的图表。 servlet 不依赖于过滤器,而只依赖于 XML 文件,因此两者实际上是分离的。 XML 文件可以创建为temporary fileFile.createTempFile。 (另一种变体当然是将所有数据保存在内存中,但存储数据方便我们备份性能测试的结果并稍后进行分析)

一些同事声称Statistics 对象中的同步会“扼杀”应用程序的性能,但实际上它确实可以忽略不计。转储文件的开销也是如此,因为它每 10 秒左右完成一次。

希望对你有帮助,或者给你一些想法。

PS:正如@William Louth 评论的那样,只有当您无法使用现有解决方案解决您的问题时,您才应该编写此类基础架构代码。就我而言,我还对代码的内部时间进行了基准测试,而不仅仅是完整的请求处理时间

【讨论】:

  • 你可能想让转储线程成为一个守护进程,这样它就不会阻止容器干净地关闭。
  • 有趣的是 PeriodicDumpStat 的内部。但我不喜欢 Web 应用程序中的线程。
  • @Tommy 如果您不想要线程,您可以说您在 10、20、30 等措施之后转储文件;您要避免的是在 each 测量之后将其转储。转储文件后,重置统计信息。转储统计数据的代码取决于您使用的数据格式,因此很难提供任何有用的信息。
  • @Trevor Tippin 我一直想知道为什么 tomcat 这么多年都没有关闭,它如此简单、愚蠢的默认 ThreadFactory 没有创建守护线程,谢谢。
猜你喜欢
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多