2017-06-14 88 views
0

我正在尝试发送两个帖子请求。两者都应该同时发送(在我下面的当前代码中,也许它会一个接一个地发送),并且应该等待最多80毫秒的响应,如果没有响应请求,则将响应视为空。同时发送2个帖子请求,等待最大响应80ms

public void SendRequests(String requestString){ 

    TimeLimiter limiter1 = new SimpleTimeLimiter(); 
    Response response1 = null; 
    System.out.println("Request Sent to 1"); 
    try{ 
     response1 = limiter1.callWithTimeout(new Callable<Response>() { 
     public Response call() { 

      //assume sendPost1 method will send POST request to some server and return response from server 

      return sendPost1(requestString); 
     } 
     }, 80, TimeUnit.MILLISECONDS, true); 
    }catch(Exception te){ 
     te.printStackTrace(); 
    } 

    TimeLimiter limiter2 = new SimpleTimeLimiter(); 
    Response response2 = null; 
    System.out.println("Request Sent to 2"); 
    try{ 
     response2 = limiter2.callWithTimeout(new Callable<Response>() { 
      public Response call() { 

       //assume sendPost2 method will send POST request to some server and return response from server 


       return sendPost2(requestString); 
      } 
     }, 80, TimeUnit.MILLISECONDS, true); 
    }catch(Exception te){ 
     te.printStackTrace(); 
    } 

    //Do some process using response1 and response2 

    } 
} 

我要寻找一些方法来在同一时间发送2个POST请求,并等待80毫秒的响应,如果没有响应,则考虑响应为空。

@Gray 我按照下面的方法尝试了您的解决方案。首先几分钟,我的servlet响应时间是2ms-10ms,但之后突然增加到200-300ms。

@WebServlet("/incomingTraffic") 
public class ServletClass extends HttpServlet { 
Gson gson; 
private static URL url1; 
private static URL url2; 

public Exchanger() { 
    super(); 
} 
public void init(ServletConfig config) throws ServletException { 
    gson = new Gson(); 

    try{ 

    url1 = new URL(Constants.URL1); 
    url2 = new URL(Constants.URL2); 

    }catch(Exception e){ 

    } 

} 

public void destroy() { 
} 

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
    response.getWriter().append("Served at: ").append(request.getContextPath()); 
} 

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
    ServletInputStream inputStream = request.getInputStream(); 
    Reader reader = new InputStreamReader(inputStream); 

    //Request class is POJO 
    final Request requestString = gson.fromJson(reader, Request.class); 

    reader.close(); 
    //long start = System.currentTimeMillis(); 
    TimeLimiter limiter = new SimpleTimeLimiter(); 

    //Response class is POJO 
    Response response1 = null; 
    Response response2 = null; 

    final ExecutorService threadPool = Executors.newCachedThreadPool(); 

    Future<Response> future1 = threadPool.submit(new Callable<Response>() { 
     public Response call() { 
      return sendPost1(requestString); 
     } 
    }); 
    Future<Response> future2 = null; 

    if(Some Condition Satisfy){ 
     future2 = threadPool.submit(new Callable<Response>() { 
      public Response call() { 
       return sendPost2(requestString); 
      } 
     }); 
    } 
    threadPool.shutdown(); 

    long start = System.currentTimeMillis(); 
    try { 
     response1 = future1.get(80, TimeUnit.MILLISECONDS); 
    } catch (ExecutionException ee) { 
     // job threw exception 
    } catch (InterruptedException ie) { 
     // this (main?) thread was interrupted, good pattern to re-interupt 
     Thread.currentThread().interrupt(); 
    } catch (TimeoutException te) { 
     // wait timed out, maybe this is right? 
     response1 = null; 
     // try to interrupt the thread 
     future1.cancel(true); 
    } 

    if(requestString.getImp().get(0).getVideo() != null){ 
    // wait for 80 MILLISECONDS minus how long we've been waiting for 2nd request 
    long end = System.currentTimeMillis(); 
    //System.out.println(start+" - "+end); 
    long wait = 80 + start - end; 
    if (wait < 0) { 
     wait = 0; 
    } 

    try { 
     response2 = future2.get(wait, TimeUnit.MILLISECONDS); 
    } catch (ExecutionException ee) { 
     // job threw exception 
    } catch (InterruptedException ie) { 
     // this (main?) thread was interrupted, good pattern to re-interrupt 
     Thread.currentThread().interrupt(); 
    } catch (TimeoutException te) { 
     // wait timed out, maybe this is right? 
     response2 = null; 
     // try to interrupt the thread 
     future2.cancel(true); 
    } 
    } 
    try { 
     threadPool.awaitTermination(80, TimeUnit.MILLISECONDS); 
    } catch (InterruptedException e) { 

    } 

    if(response1 == null && response2 == null){ 
     response.setStatus(HttpServletResponse.SC_NO_CONTENT); 
    }else { 
     response.setContentType("application/json"); 
     PrintWriter output = response.getWriter(); 
     response.setStatus(HttpServletResponse.SC_OK); 
     if(Some Condition){ 
      response.getWriter().write(gson.toJson(response1)); 
     } 
     else{ 
      response.getWriter().write(gson.toJson(response1)); 
     } 
    } 
     output.flush(); 
     output.close(); 
    } 
} 

protected Response sendPost2(Request request){ 
    Response response = null; 
    String str = gson.toJson(request); 
    HttpURLConnection conn = null; 
    try{ 
     conn= (HttpURLConnection) url2.openConnection();   
     conn.setDoOutput(true); 
     conn.setInstanceFollowRedirects(false); 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty("Content-Type", "application/json"); 
     conn.setRequestProperty("Connection", "keep-alive"); 
     conn.setRequestProperty("Content-Length", Integer.toString(str.length())); 

     DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); 
     wr.writeBytes(str); 
     wr.flush(); 
     wr.close(); 

     int responseCode = conn.getResponseCode(); 

     if(responseCode != 200){ 
      return null; 
     } 

     Reader reader = new InputStreamReader(conn.getInputStream()); 
     response = gson.fromJson(reader, Response.class); 
     conn.disconnect(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
     conn.disconnect(); 
    } 

    return response; 
} 

protected Response sendPost1(Request request){ 
    Response response = null; 
    String str = gson.toJson(request); 
    HttpURLConnection conn = null; 
    try{ 
     conn= (HttpURLConnection) url1.openConnection();   
     conn.setDoOutput(true); 
     conn.setInstanceFollowRedirects(false); 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty("Content-Type", "application/json"); 
     conn.setRequestProperty("Connection", "keep-alive"); 
     conn.setRequestProperty("Content-Length", Integer.toString(str.length())); 

     DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); 
     wr.writeBytes(str); 
     wr.flush(); 
     wr.close(); 

     int responseCode = conn.getResponseCode(); 

     if(responseCode != 200){ 
      return null; 
     } 

     Reader reader = new InputStreamReader(conn.getInputStream()); 
     response = gson.fromJson(reader, Response.class); 
     conn.disconnect(); 

    }catch(Exception e){ 
     e.printStackTrace(); 
     conn.disconnect(); 
    } 

    return response; 
} 

}

+0

考虑使用'ExecutorService';特别是'ExecutorService.invokeAll'。这应该做你需要的。 –

+0

链接的问题有一些相关的答案。把这个问题作为重复来解决。 –

回答

0

我要寻找一些方法来在同一时间发送2个POST请求,并等待80毫秒的响应,如果没有响应,则考虑响应为空。

你当然可以提交既作为Callable<Response>作业固定或缓存的线程池,然后等待它们完成。像这样:

final ExecutorService threadPool = Executors.newCachedThreadPool(NUM_THREADS); 
... 
Future<Response> future1 = threadPool.submit(new Callable<>() { ... }); 
Future<Response> future2 = threadPool.submit(new Callable<>() { ... }); 
// once you have submitted the last job you can shutdown the pool 
threadPool.shutdown(); 

long start = System.currentTimeMillis(); 
try { 
    response1 = future1.get(80, TimeUnit.SECONDS); 
} catch (ExecutionException ee) { 
    // job threw exception 
} catch (InterruptedExeception ie) { 
    // this (main?) thread was interrupted, good pattern to re-interupt 
    Thread.currentThread().interrupt(); 
} catch (TimeoutException te) { 
    // wait timed out, maybe this is right? 
    response1 = null; 
    // try to interrupt the thread 
    future1.cancel(true); 
} 

// wait for 80 seconds minus how long we've been waiting for 2nd request 
long wait = System.currentTimeMillis() - start - 80000; 
if (wait < 0) { 
    wait = 0; 
} 
try { 
    response2 = future2.get(wait, TimeUnit.MILLISECONDS); 
} catch (ExecutionException ee) { 
    // job threw exception 
} catch (InterruptedExeception ie) { 
    // this (main?) thread was interrupted, good pattern to re-interrupt 
    Thread.currentThread().interrupt(); 
} catch (TimeoutException te) { 
    // wait timed out, maybe this is right? 
    response2 = null; 
    // try to interrupt the thread 
    future2.cancel(true); 
} 

这将工作正常,但诀窍将中断2个请求。只需中断线程不会终止任何网络套接字或数据库连接。您必须确保该作业可以自行测试中断状态,否则可能会泄露线程。

+0

我试过你的解决方案。我的系统有POST请求以1500 /秒的速率进入。并且,如上面提到的问题所述,我将每个请求转发给两台服务器,两台服务器的响应时间均为80毫秒。在我看服务器时,对于前几个请求,总处理时间在2ms到10ms之间,但几分钟后,我的处理时间增加到200ms到500ms。可能是什么原因? – Nik

+0

我已更新我的代码 – Nik

相关问题