如何使用多线程定期获取服务器状态

huangapple go评论62阅读模式
英文:

How to get server status using multi-threads periodically

问题

以下是代码的翻译部分:

下面的代码运行良好它连接到给定的服务器主机端口并获取连接状态

它的功能是
1. PollService 实现了 Callable 接口连接到服务器主机端口),然后返回状态
2. 由于这应该定期发生它在一个 while(true) 循环中迭代 Hashmap 条目

问题在服务器端我发现它需要2到3秒才能到达线程如果我使用带有定期实现的 Runnable它将在1秒内连接看起来无限迭代 Hashmap 是一种缓慢的方法

然而我不能使用 Runnable因为它不会返回我后面需要使用的连接状态

下面是连接到服务器的 ServiceMonitor 类客户端)。

    package org.example;
    
    import java.time.LocalDateTime;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import java.util.stream.Collectors;
    
    public class ServicesMonitor {
      private ExecutorService scheduledExecutorService = null;
      private static Logger logger = Logger.getLogger(ServicesMonitor.class.getName());
      private final Map<ServiceType, List<ClientMonitorService>> clientMonitorServicesMap = new HashMap<>();
    
      public void registerInterest(ClientMonitorService clientMonitorService) {
        clientMonitorServicesMap.computeIfAbsent(clientMonitorService.getServiceToMonitor().getServiceType(), v -> new ArrayList<>()).add(clientMonitorService);
      }
    
      public Map<ServiceType, List<ClientMonitorService>> getClientMonitorService() {
        return clientMonitorServicesMap;
      }
    
      public void poll(){
        //Observable.interval(1, TimeUnit.SECONDS).st
      }
      public void pollServices() {
        scheduledExecutorService = Executors.newFixedThreadPool(clientMonitorServicesMap.size());
        try {
    
          while (true) {
            clientMonitorServicesMap.forEach((k, v) -> {
              Future<Boolean> val = scheduledExecutorService.submit(new PollService(k));
              try {
                boolean result = val.get();
                System.out.println("service " + k.getHost() + ":" + k.getPort() + " status is " + result);
                if (result) {
                  List<ClientMonitorService> list = v.stream().filter(a -> LocalDateTime.now().getSecond() % a.getServiceToMonitor().getFreqSec() == 0)
                          .collect(Collectors.toList());
                  list.stream().forEach(a -> System.out.println(a.getClientId()));
                }
    
              } catch (InterruptedException e) {
                e.printStackTrace();
              } catch (ExecutionException e) {
                e.printStackTrace();
              }
    
            });
          }
        } catch (Exception e) {
          logger.log(Level.SEVERE, e.getMessage());
        } finally {
          scheduledExecutorService.shutdown();
        }
      }
    }
  • 如何通过减少连接到服务器所需的时间来改善此代码的性能?
  • 如何改进此代码?
英文:

The below code works fine and it connects to a given server (host, port) and gets the connection status.

What it does is:

  1. PollService implements the Callable interface and connects to a server(host, port) then it returns the status.
  2. Since this should happen periodically, it iterates the Hashmap entries in a while(true) loop infinitely.

The problem: On the server-side, I see it takes 2 or 3 seconds to reach the thread and if I use Runnable with periodic implementation it connects within 1 sec. Looks like iterating the Hashmap infinitely is a slow approach.

However, I can not use Runnable as it doesn't return the status of the connection which I need later to use.

Below is the ServiceMonitor class (client) which connects to the server.

package org.example;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class ServicesMonitor {
private ExecutorService scheduledExecutorService = null;
private static Logger logger = Logger.getLogger(ServicesMonitor.class.getName());
private final Map&lt;ServiceType, List&lt;ClientMonitorService&gt;&gt; clientMonitorServicesMap = new HashMap&lt;&gt;();
public void registerInterest(ClientMonitorService clientMonitorService) {
clientMonitorServicesMap.computeIfAbsent(clientMonitorService.getServiceToMonitor().getServiceType(), v -&gt; new ArrayList&lt;&gt;()).add(clientMonitorService);
}
public Map&lt;ServiceType, List&lt;ClientMonitorService&gt;&gt; getClineMonitorService() {
return clientMonitorServicesMap;
}
public void poll(){
//Observable.interval(1, TimeUnit.SECONDS).st
}
public void pollServices() {
scheduledExecutorService = Executors.newFixedThreadPool(clientMonitorServicesMap.size());
try {
while (true) {
clientMonitorServicesMap.forEach((k, v) -&gt; {
Future&lt;Boolean&gt; val = scheduledExecutorService.submit(new PollService(k));
try {
boolean result = val.get();
System.out.println(&quot;service &quot; + k.getHost() + &quot;:&quot; + k.getPort() + &quot;status is &quot; + result);
if (result) {
List&lt;ClientMonitorService&gt; list = v.stream().filter(a -&gt; LocalDateTime.now().getSecond() % a.getServiceToMonitor().getFreqSec() == 0)
.collect(Collectors.toList());
list.stream().forEach(a -&gt; System.out.println(a.getClientId()));
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
}
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage());
} finally {
scheduledExecutorService.shutdown();
}
}
}
  • How to improve the performance of this code by reducing the time it takes to connect to the server?
  • How to improve this code?

答案1

得分: 0

使用get(1, TimeUnit.SECONDS)后,我也开始在服务器端看到了改进(线程达到不到1秒)因为在客户端我们不再等待超过1秒。

while (true) {
    clientMonitorServicesMap.forEach((k, v) -> {
        Future<Boolean> val = scheduledExecutorService.submit(new PollService(k));
        try {
            boolean result = val.get(1, TimeUnit.SECONDS);
            System.out.println("service " + k.getHost() + ":" + k.getPort() + " status is " + result);
            if (result) {
                List<ClientMonitorService> list = v.stream()
                        //.filter(a -> LocalDateTime.now().getSecond() % a.getServiceToMonitor().getFreqSec() == 0)
                        .collect(Collectors.toList());
                list.stream().forEach(a -> System.out.println(a.getClientId()));
            }

        } catch (InterruptedException e) {
            logger.log(Level.WARNING, "Interrupted -> " + k.getHost() + ":" + k.getPort());
        } catch (ExecutionException e) {
            logger.log(Level.INFO, "ExecutionException exception -> " + k.getHost() + ":" + k.getPort());
        } catch (TimeoutException e) {
            logger.log(Level.INFO, "TimeoutException exception -> " + k.getHost() + ":" + k.getPort());
        }

    });
}
英文:

after using the get(1, TimeUnit.SECONDS); I started to see improvement on the server side as well (Reaching the threads less than 1 second) since we are not waiting more than 1 second on the client side.

while (true) {
clientMonitorServicesMap.forEach((k, v) -&gt; {
Future&lt;Boolean&gt; val = scheduledExecutorService.submit(new PollService(k));
try {
boolean result = val.get(1, TimeUnit.SECONDS);
System.out.println(&quot;service &quot; + k.getHost() + &quot;:&quot; + k.getPort() + &quot;status is &quot; + result);
if (result) {
List&lt;ClientMonitorService&gt; list = v.stream()
//.filter(a -&gt; LocalDateTime.now().getSecond() % a.getServiceToMonitor().getFreqSec() == 0)
.collect(Collectors.toList());
list.stream().forEach(a -&gt; System.out.println(a.getClientId()));
}
} catch (InterruptedException e) {
logger.log(Level.WARNING,&quot;Interrupted -&gt; &quot; + k.getHost()+&quot;:&quot;+k.getPort());
} catch (ExecutionException e) {
logger.log(Level.INFO,&quot;ExecutionException exception -&gt; &quot;+ k.getHost()+&quot;:&quot;+k.getPort());
} catch (TimeoutException e) {
logger.log(Level.INFO,&quot;TimeoutException exception -&gt; &quot;+ k.getHost()+&quot;:&quot;+k.getPort());
}
});
}

huangapple
  • 本文由 发表于 2020年9月29日 11:49:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64112611.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定