2015-05-21 16 views
6

Tôi đang xây dựng một ứng dụng nhắn tin sử dụng Netty 4.1 Beta3 để thiết kế máy chủ của tôi và máy chủ hiểu giao thức MQTT.Điều chỉnh hiệu suất cho Netty 4.1 trên máy linux

Đây là lớp MqttServer.java của tôi thiết lập máy chủ Netty và liên kết nó với một cổng cụ thể.

 EventLoopGroup bossPool=new NioEventLoopGroup(); 
     EventLoopGroup workerPool=new NioEventLoopGroup(); 

     try { 

      ServerBootstrap boot=new ServerBootstrap(); 

      boot.group(bossPool,workerPool); 
      boot.channel(NioServerSocketChannel.class); 
      boot.childHandler(new MqttProxyChannel()); 

      boot.bind(port).sync().channel().closeFuture().sync(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     }finally {   
      workerPool.shutdownGracefully(); 
      bossPool.shutdownGracefully(); 
     } 
    } 

Bây giờ tôi đã làm một thử tải về ứng dụng của tôi trên máy Mac của tôi có cấu hình như sau enter image description here

Việc thực hiện Netty was exceptional. Tôi đã có một cái nhìn tại jstack trong khi thực hiện mã của tôi và thấy rằng NIO Netty sinh ra khoảng 19 chủ đề và không ai trong số họ dường như bị mắc kẹt chờ đợi cho các kênh hoặc cái gì khác.

Sau đó, tôi thực hiện mã của tôi trên một máy linux

enter image description here

Đây là một máy 15GB 2 lõi. Vấn đề là các gói dữ liệu được gửi bởi client MQTT của tôi dường như mất nhiều thời gian để đi qua các đường ống dẫn Netty và cũng trên tham jstack tôi thấy rằng đã có 5 đề Netty và tất cả đã bị mắc kẹt lên như thế này

."nioEventLoopGroup-3-4" #112 prio=10 os_prio=0 tid=0x00007fb774008800 nid=0x2a0e runnable [0x00007fb768fec000] 
     java.lang.Thread.State: RUNNABLE 
      at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 
      at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) 
      at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79) 
      at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) 
      - locked <0x00000006d0fdc898> (a 
io.netty.channel.nio.SelectedSelectionKeySet) 
      - locked <0x00000006d100ae90> (a java.util.Collections$UnmodifiableSet) 
      - locked <0x00000006d0fdc7f0> (a sun.nio.ch.EPollSelectorImpl) 
      at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) 
      at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:621) 
      at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:309) 
      at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:834) 
      at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) 
      at java.lang.Thread.run(Thread.java:745) 

Đây có phải là một số vấn đề hiệu suất liên quan đến epoll trên máy linux. Nếu có thì những thay đổi sẽ được thực hiện cho cấu hình netty để xử lý điều này hoặc để cải thiện hiệu suất.

Sửa

Version Java trên hệ thống địa phương là: -

phiên bản java "1.8.0_40" Java (TM) SE Runtime Environment (xây dựng 1.8.0_40-B27) Java HotSpot (TM) 64-Bit server VM (xây dựng 25,40-B25, chế độ hỗn hợp)

phiên bản Java trên AWS là: -

phiên bản openjdk "1.8.0_40-nội" OpenJDK Runtime Environment (xây dựng 1.8.0_40-nội-b09) OpenJDK 64-Bit Server VM (xây dựng 25,40-b13, chế độ hỗn hợp)

+0

Bạn có chắc chắn bạn có cùng phiên bản java trên cả hai máy không? sames JVM? –

+0

thử phiên bản mới nhất 4.1.0.Beta5. tôi đọc về một số bản sửa lỗi cho epoll. –

+0

@ArnaudPotier. Các phiên bản JVM khác nhau. –

Trả lời

1

Chơi xung quanh với các các chuỗi công việc để xem điều này có cải thiện hiệu suất hay không. Các nhà xây dựng tiêu chuẩn của NioEventLoopGroup() tạo ra số tiền mặc định của đề vòng lặp sự kiện:

DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
      "io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2)); 

Như bạn thấy, bạn có thể vượt qua io.netty.eventLoopThreads như một đối số ra mắt nhưng tôi thường không làm điều đó.

Bạn cũng có thể chuyển số lượng chủ đề trong hàm tạo của NioEventLoopGroup().

Trong môi trường của chúng tôi, chúng tôi có các máy chủ netty chấp nhận truyền thông từ hàng trăm khách hàng. Thông thường một sợi chỉ để xử lý các kết nối là đủ. Số lượng công nhân thread cần phải được thu nhỏ mặc dù.Chúng tôi sử dụng này:

private final static int BOSS_THREADS = 1; 
private final static int MAX_WORKER_THREADS = 12; 

EventLoopGroup bossGroup = new NioEventLoopGroup(BOSS_THREADS); 
EventLoopGroup workerGroup = new NioEventLoopGroup(calculateThreadCount()); 

private int calculateThreadCount() { 
    int threadCount; 
    if ((threadCount = SystemPropertyUtil.getInt("io.netty.eventLoopThreads", 0)) > 0) { 
     return threadCount; 
    } else { 
     threadCount = Runtime.getRuntime().availableProcessors() * 2; 
     return threadCount > MAX_WORKER_THREADS ? MAX_WORKER_THREADS : threadCount; 
    } 
} 

Vì vậy, trong trường hợp của chúng tôi, chúng tôi sử dụng chỉ một thread sếp. Các chuỗi công việc phụ thuộc vào nếu một đối số khởi chạy đã được đưa ra. Nếu không thì hãy sử dụng lõi * 2 nhưng không bao giờ lớn hơn 12.

Bạn sẽ phải tự kiểm tra xem con số nào hoạt động tốt nhất cho môi trường của bạn.

+0

Tôi đã thử điều này trước đây nhưng vô ích. Chúng tôi đã sử dụng khoảng 10k chủ đề công nhân;) và cũng đã chỉ định một CachedPoolExecutor tuy nhiên điều này không làm giảm độ trễ theo bất kỳ cách nào. Vấn đề vẫn còn tồn tại. Cảm ơn mặc dù :) –

+2

10k chủ đề trên một lõi kép có thể là contra sản xuất và cũng có thể gây chậm đi. http://stackoverflow.com/questions/481970/how-many-threads-is-too-many –

+0

Tôi đã thử 12 chủ đề. Vẫn không cho tôi hiệu suất được yêu cầu :( –

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