פסק זמן של HttpClient

1. סקירה כללית

מדריך זה יראה כיצד הגדר פסק זמן עם ה- Apache HttpClient 4.

אם אתה רוצה להתעמק וללמוד דברים מגניבים אחרים אתה יכול לעשות עם ה- HttpClient - המשך אל הראשי HttpClient הדרכה.

2. קביעת תצורה של פסק זמן לפני HttpClient 4.3

2.1. גלם חוּט פרמטרים

לפני שיצאה גרסה 4.3, HttpClient הגיע עם הרבה פרמטרים לתצורה, ואת כל אלה ניתן היה להגדיר באופן כללי, דמוי מפה.

היו 3 פרמטרים לפסק זמן להגדרה:

DefaultHttpClient httpClient = new DefaultHttpClient (); פסק זמן int = 5; // שניות HttpParams httpParams = httpClient.getParams (); httpParams.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, פסק זמן * 1000); httpParams.setParameter (CoreConnectionPNames.SO_TIMEOUT, פסק זמן * 1000); httpParams.setParameter (ClientPNames.CONN_MANAGER_TIMEOUT, חדש ארוך (פסק זמן * 1000));

2.2. ממשק API

ניתן להגדיר את החשוב יותר מבין הפרמטרים הללו - כלומר שני הראשונים - באמצעות ממשק API בטוח יותר לסוג:

DefaultHttpClient httpClient = new DefaultHttpClient (); פסק זמן int = 5; // שניות HttpParams httpParams = httpClient.getParams (); HttpConnectionParams.setConnectionTimeout (httpParams, פסק זמן * 1000); // http.connection.timeout HttpConnectionParams.setSoTimeout (httpParams, פסק זמן * 1000); // http.socket.timeout

לפרמטר השלישי אין מגדיר מותאם אישית HttpConnectionParams, ועדיין יהיה צורך להגדיר אותו באופן ידני באמצעות setParameter שיטה.

3. הגדר את פסק הזמן באמצעות ה- 4.3 החדש. בּוֹנֶה

ממשק ה- API הרהוט והבנאי שהוצג ב- 4.3 מספק הדרך הנכונה לקבוע פסק זמן ברמה גבוהה:

פסק זמן int = 5; RequestConfig config = RequestConfig.custom () .setConnectTimeout (פסק זמן * 1000). SetConnectionRequestTimeout (פסק זמן * 1000) .setSocketTimeout (פסק זמן * 1000) .build (); CloseableHttpClient client = HttpClientBuilder.create (). SetDefaultRequestConfig (config) .build ();

זו הדרך המומלצת להגדיר את כל שלושת הפסקות הזמן בצורה בטוחה וקריאה.

4. הסבירו מאפייני פסק זמן

עכשיו, בואו נסביר מה המשמעות של סוגים שונים של פסק זמן:

  • ה פסק זמן לחיבור (http.connection.timeout) - זמן יצירת הקשר עם המארח המרוחק
  • ה פסק זמן לשקע (http.socket.timeout) זמן ההמתנה לנתונים - לאחר יצירת החיבור; זמן חוסר פעילות מרבי בין שתי חבילות נתונים
  • ה פסק זמן של מנהל החיבורים (http.connection-manager.timeout) - זמן ההמתנה לחיבור ממנהל החיבור / הבריכה

שני הפרמטרים הראשונים - פסק הזמן לחיבור ושקע - הם החשובים ביותר. עם זאת, הגדרת פסק זמן לקבלת חיבור היא בהחלט חשובה בתרחישים של עומס גבוה, ולכן אין להתעלם מהפרמטר השלישי.

5. שימוש ב- HttpClient

לאחר הגדרת התצורה, אנו יכולים כעת להשתמש בלקוח לביצוע בקשות HTTP:

HttpGet getMethod = HttpGet חדש ("// מארח: 8080 / נתיב"); תגובה HttpResponse = httpClient.execute (getMethod); System.out.println ("מצב HTTP של תגובה:" + response.getStatusLine (). GetStatusCode ());

עם הלקוח שהוגדר בעבר, החיבור למארח יפסק תוך 5 שניות. כמו כן, אם החיבור נוצר אך לא מתקבלים נתונים, גם פסק הזמן יהיה 5 שניות נוספות.

שים לב שפסק הזמן לחיבור יביא ל- org.apache.http.conn.ConnectTimeoutException נזרק, בעוד שפסק הזמן לשקע יביא ל- java.net.SocketTimeoutException.

6. פסק זמן קשה

אמנם הגדרת פסק זמן להקמת חיבור HTTP ואי קבלת נתונים היא שימושית מאוד, אך לפעמים אנו צריכים להגדיר פסק זמן קשה לכל הבקשה.

לדוגמא, הורדת קובץ בעל פוטנציאל גדול מתאימה לקטגוריה זו. במקרה זה, ייתכן שהחיבור נוצר בהצלחה, ייתכן שהנתונים עוברים באופן עקבי, אך עדיין עלינו לוודא שהפעולה לא תעבור רף זמן מסוים כלשהו.

HttpClient אין כל תצורה שמאפשרת לנו להגדיר פסק זמן כולל לבקשה; עם זאת, הוא מספק ביטול פונקציונליות לבקשותכדי שנוכל למנף את המנגנון הזה כדי ליישם מנגנון פסק זמן פשוט:

HttpGet getMethod = HttpGet חדש ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // שניות משימה TimerTask = TimerTask חדשה () {@Override public void run () {if (getMethod! = null) {getMethod.abort (); }}}; טיימר חדש (נכון). schedule (task, hardTimeout * 1000); תגובה HttpResponse = httpClient.execute (getMethod); System.out.println ("מצב HTTP של תגובה:" + response.getStatusLine (). GetStatusCode ());

אנו משתמשים ב- java.util.Timer ו java.util.TimerTask להקים א משימה מתעכבת פשוטה אשר מבטלת את בקשת ה- HTTP GET לאחר פסק זמן קשה של 5 שניות.

7. פסק זמן ו- DNS סביב רובין - משהו שצריך להיות מודע אליו

זה די שכיח שחלק מהדומיינים הגדולים ישתמשו בתצורת DNS עגולה - למעשה אותו תחום ממופה למספר כתובות IP. זה מציג אתגר חדש לפסק זמן כנגד דומיין כזה, פשוט בגלל הדרך שבה HttpClient ינסה להתחבר לתחום זה בתום הזמן:

  • HttpClient מקבל רשימת מסלולי ה- IP לתחום זה
  • זה מנסה הראשון - זה פסק הזמן (עם פסק הזמן שאנחנו מגדירים)
  • זה מנסה השני - שגם פסק הזמן
  • וכולי …

אז, כפי שאתה יכול לראות - הפעולה הכוללת לא תפסק כשאנחנו מצפים שזה יהיה. במקום זאת - יתפוגג הזמן שבו יתפסק הזמן לכל המסלולים האפשריים. יתרה מכך - זה יקרה בשקיפות מלאה עבור הלקוח (אלא אם כן הגדרת היומן שלך ברמת DEBUG).

הנה דוגמה פשוטה שתוכל להריץ ולשכפל בעיה זו:

פסק זמן int = 3; RequestConfig config = RequestConfig.custom (). setConnectTimeout (פסק זמן * 1000). setConnectionRequestTimeout (פסק זמן * 1000). setSocketTimeout (פסק זמן * 1000) .build (); CloseableHttpClient client = HttpClientBuilder.create () .setDefaultRequestConfig (config) .build (); HttpGet בקשה = HttpGet חדש ("// www.google.com:81"); תגובה = client.execute (בקשה);

תבחין בהיגיון המנסה מחדש ברמת יומן DEBUG:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - התחברות ל- www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - התחבר ל- www.google.com/173.194.34.212:81 זמן קצוב. החיבור ינוסה מחדש באמצעות כתובת IP אחרת DEBUG o.a.h.i.c. HttpClientConnectionOperator - התחברות ל- www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c. HttpClientConnectionOperator - התחבר ל- www.google.com/173.194.34.208:81 מתוזמן. החיבור ינוסה מחדש באמצעות כתובת IP אחרת DEBUG o.a.h.i.c. HttpClientConnectionOperator - התחברות ל- www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c. HttpClientConnectionOperator - התחבר ל- www.google.com/173.194.34.209:81 מתוזמן. החיבור ינסה שוב באמצעות כתובת IP אחרת // ...

8. מסקנה

הדרכה זו דנה כיצד להגדיר את סוגי הפסקות הזמן השונות הזמינות ל- HttpClient. זה גם המחיש מנגנון פשוט לפסק זמן קשה של חיבור HTTP מתמשך.

יישום הדוגמאות הללו ניתן למצוא בפרויקט GitHub.


$config[zx-auto] not found$config[zx-overlay] not found