2017-06-14 121 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

相關問題