java udp服务器100%cpu
我有一个UDP服务器,它以每秒40 pkt的速度接收数据包。 主回路如下:java udp服务器100%cpu,java,performance,server,udp,Java,Performance,Server,Udp,我有一个UDP服务器,它以每秒40 pkt的速度接收数据包。 主回路如下: public void serve() { while(true) { ByteBuffer bytes = ByteBuffer.allocate(1024); bytes.clear(); channel.receive(bytes); THandler th = new THandler
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));
THandler类扩展了thread类,它根据正则表达式过滤消息,然后从匹配的消息中查找id。
然后将此id与订户列表(约300k)进行比较。然后是数据库选择,然后是更新
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。但问题是,我在99.6%或更多用户的情况下耗尽了CPU时间
任何关于如何提高服务器性能和代码的输入都是非常受欢迎的。您的搜索很可能只是通过数组进行迭代。您可能希望用一种更有效的方法替换这些方法 看一下特别的和
- 确保通道处于阻塞模式
- 您不需要清除新创建的
ByteBuffer。
- 使用具有合理大小的线程池的
,而不是为每个数据报创建一个新线程ExecutorService
- 确保您使用的是O(1)数据结构
- 使用
,如果需要查看是否发生了任何事情,请获取更新计数update。。。其中
- 忽略任何将睡眠添加到网络代码中的建议。他们简直是在浪费时间
频道的代码。似乎您需要分析代码。这可以通过JDK附带的jvisualvm
来完成。@EJP有一个很好的答案。我建议您使用缓存线程池,即ExecutorService,而不是为每个数据包创建一个线程。创建一个线程非常昂贵,您可能会发现池中很少有多个线程。您只需要在使用ByteBuffer时清除它。新的ByteBuffer总是clear()
我试图将列表删减到只有一个订户,但没有成功,CPU仍然100%占用。在这种情况下,数据通道可能不会像@EJP提到的那样处于阻塞模式。我怀疑数据处理/搜索占用了所有CPU。