java udp 服务器 100% cpu

java udp server 100% cpu

我有一个 UDP 服务器,它以每秒 40 pkts 的速度接收数据包。 主循环如下:

 public void serve() {
        while(true) {
              ByteBuffer bytes = ByteBuffer.allocate(1024);
              bytes.clear();
              channel.receive(bytes);
              THandler th = new THandler(bytes);
              th.start();
        }
    }

频道初始化:

private final DatagramChannel channel ;  
channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(port));

classTHandler 扩展了一个线程class,它根据正则表达式过滤消息,然后从匹配的消息中找到一个 id。 然后将此 ID 与订阅者列表(大约 300k)进行比较。接着是数据库 select 然后是更新。

public void run() {

    if (!this.isValidLog()){ //does a regular expression match
        return;
    }
    String subsId = this.getSubscriberId(); // extracts the id from message
    if (this.isServiceSubscribed(subsId)) { // compares in a list of subscribers

        usageDetails = this.getServiceUsage(subsId); // db Query
        if(usageDetails.isFeatureAvailable()){
            usageDetails.updateUsageCounter(); // db Update
        }
    }


}

我也尝试过使用 ExecutorService。但问题是我 运行 在 CPU 时间里有 99.6% 或更多的用户。

欢迎就如何改进服务器和代码的性能提出任何意见。

很可能您的搜索只是通过数组进行迭代。您可能想用更有效的方法替换它们。

看看Map specially HashMap and TreeMap

  • 确保频道处于阻塞模式。
  • 您不需要清除新创建的 ByteBuffer.
  • 使用具有合理大小线程池的 ExecutorService,而不是为每个数据报创建一个新线程。
  • 确保您使用的是 O(1) 数据结构。
  • 将数据库查找和更新合并为一个操作,使用UPDATE ... WHERE,如果您需要查看是否发生任何事情,则获取更新计数。
  • 忽略任何将睡眠添加到网络代码中的建议。它们实际上是在浪费时间。