אביב WebClient לעומת RestTemplate

REST למעלה

רק הכרזתי על החדש למד אביב קורס, המתמקד ביסודות האביב 5 ומגף האביב 2:

>> בדוק את הקורס

1. הקדמה

במדריך זה נשווה שתיים מיישומי לקוח האינטרנט של אביב - RestTemplate והחלופה המגיבה החדשה של אביב 5 WebClient.

2. חסימה לעומת לקוח שאינו חוסם

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

2.1. RestTemplate לקוח חוסם

במשך זמן רב, אביב מציע RestTemplate כהפשטה של ​​לקוח אינטרנט. מתחת למכסת המנוע, RestTemplate משתמש ב- Java Servlet API המבוסס על מודל החוט לפי בקשה.

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

בואו נשקול לקבל הרבה בקשות נכנסות, שמחכות לשירות איטי כלשהו הדרוש להפקת התוצאה.

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

2.2. WebClient לקוח שאינו חוסם

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

בזמן RestTemplate משתמש בשרשור המתקשר לכל אירוע (שיחת HTTP), WebClient תיצור משהו כמו "משימה" לכל אירוע. מאחורי הקלעים, המסגרת התגובתית תעמוד בתור "משימות" אלה ותבצע אותן רק כאשר התגובה המתאימה זמינה.

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

WebClient הוא חלק מספריית Spring WebFlux. לָכֵן, אנו יכולים גם לכתוב קוד לקוח באמצעות ממשק API פונקציונלי שוטף עם סוגים תגובתי (מונו ו שֶׁטֶף) כהרכב הצהרתי.

3. דוגמה להשוואה

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

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

לצורך מאמר זה, בואו ניישם שתי נקודות קצה של REST, אחת באמצעות RestTemplate והשני משתמש WebClient. המשימה שלהם היא להתקשר לשירות אינטרנט איטי נוסף של REST, שמחזיר רשימה של ציוצים.

בתור התחלה, נצטרך תלות המתנע של Spring Boot WebFlux:

 org.springframework.boot spring-boot-starter-webflux 

יתר על כן, הנה נקודת הקצה REST של שירות איטי שלנו:

@GetMapping ("/ tweets-service-tweets") רשימה פרטית getAllTweets () {Thread.sleep (2000L); // עיכוב החזרת Arrays.asList (ציוץ חדש ("כללי RestTemplate", "@ user1"), ציוץ חדש ("WebClient עדיף", "@ user2"), ציוץ חדש ("OK, שניהם שימושיים", "@ משתמש 1 ")); }

3.1. באמצעות RestTemplate להתקשר לשירות איטי

בואו וניישם כעת נקודת קצה נוספת של REST שתקרא לשירות האיטי שלנו באמצעות לקוח האינטרנט.

ראשית, נשתמש RestTemplate:

@GetMapping ("/ חסימת ציוצים") רשימה ציבורית getTweetsBlocking () {log.info ("הפעלת בקר חסימה!"); מחרוזת סופית uri = getSlowServiceUri (); RestTemplate restTemplate = RestTemplate חדש (); תגובה תגובה תגובה = restTemplate.exchange (uri, HttpMethod.GET, null, ParameterizedTypeReference חדש() {}); תוצאת רשימה = response.getBody (); result.forEach (ציוץ -> log.info (tweet.toString ())); log.info ("יציאה מבקר החסימה!"); תוצאת החזרה; }

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

מתחיל בקר חסימה! ציוץ (טקסט = כללי RestTemplate, [מוגן באמצעות דוא"ל]) ציוץ (טקסט = עדיף WebClient, [מוגן באמצעות דוא"ל]) ציוץ (טקסט = בסדר, שניהם שימושיים, [מוגן באמצעות דוא"ל]) יציאה מבקר חסימה!

3.2. באמצעות WebClient להתקשר לשירות איטי

שנית, בואו נשתמש WebClient להתקשר לשירות האיטי:

@GetMapping (value = "/ tweets-non-blocking"), מייצר = MediaType.TEXT_EVENT_STREAM_VALUE) שטף ציבורי getTweetsNonBlocking () {log.info ("הפעלת בקר NON-BLOCKING!"); שטף tweetFlux = WebClient.create () .get () .uri (getSlowServiceUri ()). Retrieve () .bodyToFlux (Tweet.class); tweetFlux.subscribe (ציוץ -> log.info (tweet.toString ())); log.info ("יציאה מבקר שאינו חסום!"); החזר tweetFlux; }

במקרה הזה, WebClient מחזירה א שֶׁטֶף מפרסם וביצוע השיטה מסתיים. לאחר שהתוצאה תהיה זמינה, המו"ל יתחיל לשלוח ציוצים למנויים. שים לב שלקוח (במקרה זה, דפדפן אינטרנט) שמתקשר אליו / ציוצים-לא חוסמים נקודת הקצה תירשם כמנוי לחזרה שֶׁטֶף לְהִתְנַגֵד.

בואו נצפה ביומן הפעם:

מתחיל בקר ללא חסימה! יציאה מבקר שאינו חסום! ציוץ (טקסט = כללי RestTemplate, [מוגן באמצעות דוא"ל]) ציוץ (טקסט = עדיף WebClient, [מוגן באמצעות דוא"ל]) ציוץ (טקסט = בסדר, שניהם שימושיים, [מוגן באמצעות דוא"ל])

שים לב ששיטת נקודת קצה זו הושלמה לפני שהתגובה התקבלה.

4. מסקנה

במאמר זה בחנו שתי דרכים שונות לשימוש בלקוחות אינטרנט באביב.

RestTemplate משתמש ב- Java Servlet API ולכן הוא סינכרוני וחוסם. לעומת זאת, WebClient הוא אסינכרוני ולא יחסום את שרשור הביצוע בזמן שהוא ממתין לתגובה שתחזור. רק כאשר התגובה מוכנה, ההודעה תימסר.

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

ניתן למצוא את כל קטעי הקוד המוזכרים במאמר ב- GitHub.

REST תחתון

רק הכרזתי על החדש למד אביב קורס, המתמקד ביסודות האביב 5 ומגף האביב 2:

>> בדוק את הקורס

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