2010-06-29 23 views
7

Tôi đang thực hiện một số thử nghiệm tải trên ứng dụng web được triển khai trong JBoss. Nó khởi động tốt, nhưng là dốc thử nghiệm lên và nhiều người dùng mô phỏng bắt đầu đánh JBoss, làm giảm hiệu suất nghiêm trọng:Các chủ đề JBoss đang chờ trên màn hình ngẫu nhiên

Resposne time chart http://i46.tinypic.com/2mob2f9.jpg

Connecting VisualVM với nó, tôi có thể thấy các chủ đề đều tốt, sau đó đột nhiên bắt đầu chi tiêu hầu hết thời gian của họ chờ đợi một màn hình (màu xanh lá cây đang chạy, màu đỏ là màn hình, màu vàng là chờ đợi):

Thread state graph http://i46.tinypic.com/105v6lk.jpg

chạy jstack, tôi thấy chủ đề đang chờ đón ở cùng một chỗ:

"http-0.0.0.0-8080-172" daemon prio=6 tid=0x000000005da90000 nid=0xd2c waiting for monitor entry [0x000000006cb4e000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at org.apache.log4j.Category.callAppenders(Category.java:185) 
    - waiting to lock (a org.apache.log4j.spi.RootCategory) 
    at org.apache.log4j.Category.forcedLog(Category.java:372) 
    at org.apache.log4j.Category.debug(Category.java:241) 
    [my code]

Hầu hết ~ 200 chuỗi bộ xử lý HTTP đang đợi cùng một màn hình. Nhìn vào log4j.xml cho WAR, nó có một thiết lập appender đơn cho CONSOLE. Tôi xóa ứng dụng và thử lại bài kiểm tra của mình. Cùng hành vi, ngoại trừ jstack thấy tất cả các chủ đề chờ đợi ở một nơi khác nhau:

"http-0.0.0.0-8080-251" daemon prio=6 tid=0x0000000059811800 nid=0x1108 waiting for monitor entry [0x0000000073ebe000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at java.util.Hashtable.get(Hashtable.java:333) 
    - waiting to lock (a org.jboss.util.property.PropertyMap) 
    at java.util.Properties.getProperty(Properties.java:932) 
    at org.jboss.util.property.PropertyMap.getProperty(PropertyMap.java:626) 
    at java.lang.System.getProperty(System.java:653) 
    at org.jaxen.saxpath.helpers.XPathReaderFactory.createReader(XPathReaderFactory.java:109) 
    at org.jaxen.BaseXPath.(BaseXPath.java:124) 
    at org.jaxen.BaseXPath.(BaseXPath.java:153) 
    at nu.xom.JaxenConnector.(JaxenConnector.java:49) 
    at nu.xom.Node.query(Node.java:424) 
    [my code]

Thay đổi không có gì, tôi khởi động lại JBoss, chạy thử nghiệm, sau đó chạy jstack khi nó trở nên chậm chạp. Tất cả các chủ đề đang chờ ở một địa điểm khác:

"http-0.0.0.0-8080-171" daemon prio=6 tid=0x000000005d0d1000 nid=0x15d4 waiting for monitor entry [0x000000006cb4e000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at sun.nio.cs.FastCharsetProvider.charsetForName(FastCharsetProvider.java:118) 
    - waiting to lock (a sun.nio.cs.StandardCharsets) 
    at java.nio.charset.Charset.lookup2(Charset.java:449) 
    at java.nio.charset.Charset.lookup(Charset.java:437) 
    at java.nio.charset.Charset.isSupported(Charset.java:479) 
    at sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:49) 
    at java.io.InputStreamReader.(InputStreamReader.java:57) 
    at java.io.FileReader.(FileReader.java:41) 
    [my code]

Điều gì đang xảy ra? Tôi đã sử dụng jstack trong quá khứ và tôi đã cố gắng chạy nó khi mọi thứ đang chạy tốt và có kết quả mong đợi. Tôi giả định jstack là tốt. Bất kỳ ý tưởng gì có thể gây ra hành vi kỳ lạ như vậy? Bất kỳ ý tưởng về nơi để đi từ đây?

+0

Không có nhiều ngữ cảnh/thông tin hơn, rất khó để nói cụ thể những gì đang diễn ra. Nói chung, có vẻ như có rất nhiều tranh chấp cho các tài nguyên khác nhau và/hoặc tình huống bế tắc có thể xảy ra. Bước đầu tiên của bạn, có vẻ như bạn đã xóa một số tranh chấp cho log4j. Có thể làm điều tương tự cho hai tài nguyên kia bằng cách kết hợp các kết quả truy vấn bộ nhớ đệm hoặc đồng bộ hóa quyền truy cập vào cấu trúc dữ liệu có thể dẫn đến bế tắc không? – btreat

+0

Tôi rất vui được cung cấp thêm thông tin, tôi chỉ không chắc chắn những gì cần cung cấp. Điều kỳ lạ là, mặc dù có rất nhiều tranh chấp, các chủ đề không bị bế tắc. Họ chờ đợi trên một màn hình từ 2 đến 10 giây, sau đó thực hiện tiếp tục, sau đó ngay sau khi chờ đợi trên một màn hình một lần nữa. Các cuộc gọi rất cơ bản (ví dụ: System.getProperties) và không thể tránh được. JBoss và mã bên thứ ba khác thực hiện các cuộc gọi này. Kể từ khi tôi khá chắc chắn System.getProperties và HashTable là vững chắc, dự đoán tốt nhất tiếp theo của tôi là jstack là gây hiểu nhầm khi tranh chấp xảy ra. Nếu vậy, làm thế nào khác tôi có thể xác định nơi tranh chấp xảy ra? – NateS

Trả lời

2

Tôi thiết lập ứng dụng trong Tomcat chạy qua Eclipse và không thấy sự cố. Cuối cùng tôi tìm thấy chúng tôi đã bắt đầu JBoss bằng cách sử dụng một wrapper dịch vụ Windows 32-bit, mặc dù chúng tôi đã sử dụng một JDK 64-bit. Máy này là 64-bit. Tôi không chắc làm thế nào điều này thậm chí sẽ làm việc? Dù sao, việc đổi sang một JDK 32 bit đã khiến cho vấn đề điên rồ biến mất và tôi có thể tiếp tục cuộc sống của mình.

3

Loại hành vi này được mong đợi. Khi bạn mở rộng thử nghiệm tải, bạn sẽ luôn tìm thấy tắc nghẽn, và trong một hệ thống phức tạp, những tắc nghẽn đó sẽ thay đổi.

Công việc của bạn là xác định những tắc nghẽn đó và cố gắng sửa chúng, từng lần một. Mỗi lần bạn làm như vậy, bạn sẽ luôn tìm thấy một ứng dụng khác, nhưng hy vọng hệ thống sẽ mở rộng tốt hơn mỗi lần. Nó không phải dễ dàng, nhưng sau đó mở rộng quy mô cho tải là không dễ dàng.

  • Lấy ví dụ thứ nhất của bạn. Bạn có rất nhiều cuộc gọi đến phương thức Logger.debug() của log4j. Log4j không hoạt động tốt khi đăng nhập dưới tải, vì vậy bạn cần phải thực hiện một số biện pháp phòng ngừa. Ngay cả khi cấu hình log4j của bạn nói "không đăng nhập DEBUG tin nhắn", log4j vẫn phải làm một số công việc trước khi thực hiện điều này. Cách tiếp cận được đề nghị để xử lý là bao gồm mọi cuộc gọi Logger.debug() trong một if Logger.isDebugEnabled() {Logger.debug(); } `khối. Điều này sẽ thay đổi nút cổ chai cụ thể đó.

  • Trong ví dụ 2 của bạn, bạn đang gọi phương thức Node.query() của XOM. Phương pháp này phải biên dịch lại biểu thức XPath trên mọi cuộc gọi, và điều này có vẻ là một nút cổ chai. Tìm một API nơi bạn có thể biên dịch trước biểu thức XPath và tái sử dụng nó.

  • Trong ví dụ thứ 3, bạn đang đọc File. Đây không phải là một ý tưởng hay trong một hệ thống tải cao, file-io chậm khi bạn đang thực hiện một số lượng lớn các hoạt động nhỏ. Xem xét việc thực hiện lại điều này để làm việc theo cách khác nếu bạn có thể.

Tất cả những điều này không liên quan, nhưng tất cả các tắc nghẽn hiệu suất hiện tại bạn sẽ thấy khi mở rộng tải. Bạn sẽ không bao giờ loại bỏ tất cả, nhưng hy vọng bạn có thể làm cho nó đến một điểm mà nó đủ tốt.

+0

Tôi không thấy nút cổ chai. Các cuộc gọi Log4j (thậm chí là ghi vào một tập tin một cách liên tục), gọi System.getProperty và gọi Charset.isSupported là các hoạt động nhanh, không phải các cuộc gọi thông thường cần phải tránh. Tôi chỉ chạy 250 luồng. Những ổ khóa này thường đi rất nhanh. Hơn 100 chủ đề chờ đợi trên System.getProperty có nghĩa là thread khóa HashTable mất nhiều thời gian. Các chủ đề khóa chỉ là gọi Hashtable.get. Có rất ít lý do cho việc đó mất nhiều thời gian. Có lẽ jstack là sai lầm? Có vẻ như không, vì nó không hiển thị các chuỗi chặn khi ứng dụng web chạy trơn tru. – NateS

+0

@NateS: Chúng có thể hoạt động nhanh nhưng chúng đơn luồng và khiến chúng bị tắc nghẽn. Không quan trọng chúng nhanh như thế nào, chúng không đồng thời. Ngăn xếp ngăn xếp của riêng bạn chứng minh điều này. – skaffman

+0

Tôi không thể tin rằng một chương trình thử nghiệm đơn giản có 250 luồng gọi là System.getProperties sẽ hiển thị cùng một vấn đề tranh chấp mà tôi thấy với ứng dụng của mình. – NateS

Các vấn đề liên quan