2010-03-19 53 views
13

Tôi có một ứng dụng Spring mà tôi tin rằng có một số tắc nghẽn, vì vậy tôi muốn chạy nó với một trình lược tả để đo lường những chức năng nào mất bao nhiêu thời gian. Bất kỳ khuyến nghị nào về cách tôi nên làm điều đó?Lập hồ sơ ứng dụng Java Spring

Tôi đang chạy STS, dự án là một dự án maven, và tôi chạy mùa xuân 3.0.1

+0

Việc lập hồ sơ ứng dụng Spring không thực sự khác biệt trong việc định cấu hình bất kỳ ứng dụng java nào khác. Bạn có thể muốn mở rộng câu hỏi, để có được lựa chọn câu trả lời rộng hơn. – skaffman

Trả lời

15

Tôi đã thực hiện việc này bằng Spring AOP.

Thỉnh thoảng tôi cần thông tin về thời gian thực hiện một số phương pháp trong dự án của tôi (ví dụ như phương thức của Bộ điều khiển).

Trong servlet xml tôi đặt

<aop:aspectj-autoproxy/> 

Ngoài ra, tôi cần phải tạo ra các lớp cho các khía cạnh:

@Component 
@Aspect 
public class SystemArchitecture { 

    @Pointcut("execution(* org.mywebapp.controller..*.*(..))") 
    public void businessController() { 
    } 
} 

Và profiler khía cạnh:

@Component 
@Aspect 
public class TimeExecutionProfiler { 

    private static final Logger logger = LoggerFactory.getLogger(TimeExecutionProfiler.class); 

    @Around("org.mywebapp.util.aspects.SystemArchitecture.businessController()") 
    public Object profile(ProceedingJoinPoint pjp) throws Throwable { 
     long start = System.currentTimeMillis(); 
     logger.info("ServicesProfiler.profile(): Going to call the method: {}", pjp.getSignature().getName()); 
     Object output = pjp.proceed(); 
     logger.info("ServicesProfiler.profile(): Method execution completed."); 
     long elapsedTime = System.currentTimeMillis() - start; 
     logger.info("ServicesProfiler.profile(): Method execution time: " + elapsedTime + " milliseconds."); 

     return output; 
    } 

    @After("org.mywebapp.util.aspects.SystemArchitecture.businessController()") 
    public void profileMemory() { 
     logger.info("JVM memory in use = {}", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); 
    } 
} 

Đó là tất cả. Khi tôi yêu cầu một trang từ webapp của tôi, thông tin về thời gian thực hiện phương pháp và việc sử dụng bộ nhớ JVM sẽ được in ra trong tệp nhật ký webapp của tôi.

+0

Hehe, đây thực sự là cùng một công việc xung quanh tôi đã sử dụng cho đến nay. :-) Không phải là một profiler, nhưng được bạn một cách dài :-) – niklassaers

+0

Nói về, vì một số lý do này hoạt động tốt trên phương pháp kinh doanh của tôi, nhưng không phải trên bộ điều khiển của tôi. Bất kỳ ý tưởng tại sao điều này có thể? – niklassaers

+0

Xin lỗi, bạn không nói điều này trong câu hỏi của bạn :) Nếu câu hỏi của bạn là về ứng dụng web và nếu bạn sử dụng thùng chứa servlet tomcat, bạn có thể sử dụng máy chủ tc SpringSource với thông tin chi tiết về mùa xuân –

2

Bạn có thể sử dụng một nguồn java profiler mở như Profiler4J:

http://profiler4j.sourceforge.net/

hoặc Netbeans đi kèm với một trình biên dịch được xây dựng trong và Eclipse cũng có khả năng lược tả, tuy nhiên tôi thấy Profiler4J dễ sử dụng hơn vì nó có biểu đồ đẹp cho bạn thấy các phương thức tốn thời gian nhất.

Điều này hoạt động tốt trong STS (nhật thực), chỉ cần thực hiện theo hướng dẫn trên trang web.

+0

Cảm ơn lời khuyên. Có vẻ như phiên bản beta cuối cùng của Profiler4J đã được đăng trong năm 2006, đây vẫn là một dự án đang hoạt động? – niklassaers

+0

Có vẻ như nó có thể vẫn chưa được tích cực phát triển, nhưng khi tôi sử dụng nó một vài tháng trước, nó hoạt động tốt. Tôi đoán nó sẽ không được triển khai với dự án của bạn vì vậy nếu nó hoạt động như một công cụ một lần bạn không cần phải lo lắng. Có rất nhiều người khác có sẵn trên thị trường, nếu không thì chỉ cần sử dụng cái có kèm theo nhật thực. –

+0

Hmm, tôi đã thử nó, nhưng hóa ra là cả Call Graph lẫn Call Tree đều không được mặc dù tôi đã thiết kế tất cả các lớp và các lớp proxy. Bộ nhớ và Chủ đề hoạt động tốt, mặc dù – niklassaers

1

Tôi thích JRat, mặc dù như profiler4j nó dường như không được tích cực phát triển. Trong mọi trường hợp, nó rất đơn giản để sử dụng.

+0

Nó trông thực sự đơn giản để sử dụng, nhưng khi tôi đã thử nó ra, tôi đã nhận lỗi Nullpointer từ khía cạnh dệt. Không có ý tưởng tại sao, khi tôi vô hiệu hóa JRat họ đã biến mất. Mặc dù tôi sẽ không ngạc nhiên nếu chúng là lỗi của tôi, nhưng tôi không biết điều gì đã kích hoạt chúng hoặc chúng xuất phát từ đâu. : -I – niklassaers

3

Tôi khuyên bạn nên VisualVM để có hồ sơ ứng dụng chung. Nó có sẵn trong JDK từ phiên bản 1.6_10, và imho nhanh hơn nhiều và có thể sử dụng hơn Eclipse TPTP.

Nếu ứng dụng Spring của bạn hoạt động trong máy chủ ứng dụng (ví dụ: Tomcat), bạn có thể thử triển khai nó lên phiên bản dành cho nhà phát triển máy chủ tc (có sẵn trong STS downloads). Nó có khả năng giám sát thú vị.

+0

Cảm ơn bạn đã đề xuất. Tôi đang làm việc trên OS X, và vì lý do nào đó TPTP dường như không tồn tại ở đó. Tôi đã quên về tcServer, vì vậy tôi sẽ chắc chắn để cho rằng một whirl :-) – niklassaers

+0

Cập nhật URL VisualVm: https://visualvm.java.net/ – Daimon

+0

@Daimon, cảm ơn bạn đã cập nhật URL, tôi đã cập nhật nó trong câu trả lời cũng như –

0

Đây là một general discussion với các công cụ được đề xuất & kỹ thuật.

Về cơ bản, bạn hoàn toàn có thể giả định nếu muốn tìm hiểu cách làm cho ứng dụng nhanh hơn, bạn nên bắt đầu bằng cách đo các hàm mất bao lâu. Đó là cách tiếp cận từ trên xuống.

Có cách tiếp cận từ dưới lên khi bạn nghĩ về nó cũng giống như tự nhiên. Đó không phải là để hỏi về thời gian, nhưng để hỏi những gì nó đang làm, chủ yếu, và tại sao nó đang làm điều đó.

2

Chúng tôi đã phát triển một JMX & Ghi chú sản xuất dựa trên @Profiled Spring AOP giám sát sản xuất (hoạt động invocations, invocations count, thời gian dành cho invocations, ngoại lệ, vv).Số liệu được hiển thị thông qua JMX và có thể được thu thập thông qua Visual VM/JConsole và bằng hệ thống giám sát; chúng tôi đã phát triển một Plugin Hyperic HQ.

Chú thích @profiled này được đóng gói với nhiều tính năng bổ sung JMX khác để dễ dàng giám sát các thành phần chung (dbcp, util.concurrent, cxf, jms, v.v.) và được đề xuất theo Giấy phép Phần mềm Apache thân thiện với doanh nghiệp tại http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras.

Hope this helps,

Cyrille (Xebia)

0

Một phiên bản sửa đổi chút câu trả lời của Yuri trên đầu trang (câu trả lời được chọn) tự động cho phép tính tổng số những khoảng thời gian và sắp xếp chúng desc. Tổng số chỉ được in ở cuối. Có thể giúp bạn tiết kiệm 10 mns.

@Component 
    @Aspect 
    public class SystemArchitecture 
    { 

     @Pointcut("execution(* erp..*.*(..))") 
     public void businessController() 
     { 
     } 

     @Pointcut("execution(* TestMain..*.*(..))") 
     public void theEnd() 
     { 
     } 
    } 



    @Component 
    @Aspect 
    public class TimeExecutionProfiler 
    { 

     static Hashtable<String, Long> ht = new Hashtable<String, Long>(); 

     @Around("profiler.SystemArchitecture.businessController()") 
     public Object profile(ProceedingJoinPoint pjp) throws Throwable 
     { 
      long start = System.nanoTime(); 
      Object output = pjp.proceed(); 
      long elapsedTime = System.nanoTime() - start; 
      String methodName = pjp.getSignature().toString(); 
      if (ht.get(methodName) == null) 
      { 
       ht.put(methodName, elapsedTime); 
      } 
      else 
      { 
       ht.put(methodName, ht.get(methodName) + elapsedTime); 
      } 
      // System.out.println(methodName + " : " + elapsedTime + " milliseconds."); 

      return output; 
     } 

     @After("profiler.SystemArchitecture.theEnd()") 
     public void profileMemory() 
     { 
      List<Object> keys = Arrays.asList(ht.keySet().toArray()); 
      java.util.Collections.sort(keys, new Comparator<Object>() 
      { 

       @Override 
       public int compare(Object arg0, Object arg1) 
       { 
        return ht.get(arg1).compareTo(ht.get(arg0)); 
       } 
      }); 

      System.out.println("totals Used:"); 
      for (Object name : keys) 
      { 
       System.out.println("--" + name + " : " + (ht.get(name)/1000000)); 
      } 
      System.out.println("JVM memory in use = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); 
     } 
    } 
Các vấn đề liên quan