מבוא לקונג

1. הקדמה

קונג הוא שער קוד פתוח של API ושכבת ניהול מיקרו-שירות.

בהתבסס על Nginx ועל מודול lua-nginx (במיוחד OpenResty), הארכיטקטורה הניתנת לניתוק של קונג הופכת אותו לגמיש ועוצמתי.

2. מושגי מפתח

לפני שנצלול לדוגמאות קוד, בואו נסתכל על מושגי המפתח בקונג:

  • אובייקט API - עוטף מאפיינים של כל נקודת סיום של HTTP (ים) שמבצעת משימה מסוימת או מספקת שירות כלשהו. התצורות כוללות שיטות HTTP, URI של נקודות קצה, כתובת URL במעלה המפנה לשרתי ה- API שלנו וישמשו לבקשות שרת proxy, הפסקות מקסימליות, מגבלות תעריף, פסק זמן וכו '.
  • אובייקט צרכני - עוטף מאפיינים של כל מי שמשתמש בנקודות הקצה של ה- API שלנו. הוא ישמש למעקב, בקרת גישה ועוד
  • אובייקט במעלה הזרם - מתאר כיצד בקשות נכנסות יסופקו או יתאזן בין עומסים, המיוצג על ידי שם מארח וירטואלי
  • אובייקט יעד - מייצג את השירותים מיושמים ומוגשים, מזוהים על ידי שם מארח (או כתובת IP) ויציאה. שים לב כי ניתן להוסיף או להשבית יעדים בכל זרם עליון בלבד. ההיסטוריה של שינויי היעד נשמרת על ידי הזרם
  • אובייקט תוסף - תכונות ניתנות להעברה כדי להעשיר את הפונקציות של היישום שלנו במהלך מחזור חיי הבקשה והתגובה. לדוגמה, ניתן להוסיף אימות API ותכונות הגבלת קצב על ידי הפעלת תוספים רלוונטיים. קונג מספק תוספים חזקים מאוד בגלריית התוספים שלו
  • ממשק API למנהלי מערכת - נקודות קצה של RESTful המשמשות לניהול תצורות של קונג, נקודות קצה, צרכנים, תוספים וכו '

התמונה למטה מתארת ​​כיצד קונג שונה מארכיטקטורה מדור קודם, שיכולה לעזור לנו להבין מדוע הציג מושגים אלה:

(מקור: //getkong.org/)

3. התקנה

התיעוד הרשמי מספק הוראות מפורטות לסביבות שונות.

4. ניהול API

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

@RestController @RequestMapping ("/ stock") מחלקה ציבורית QueryController {@GetMapping ("/ {code}") מחרוזת ציבורית getStockPrice (@PathVariable קוד מחרוזת) {להחזיר "BTC" .equalsIgnoreCase (קוד)? "10000": "0"; }}

4.1. הוספת ממשק API

לאחר מכן, בואו נוסיף את ה- API של השאילתה שלנו לקונג.

ממשקי ה- API של מנהל המערכת נגישים באמצעות // localhost: 8001, כך שכל פעולות ניהול ה- API שלנו יבוצעו באמצעות ה- URI הבסיסי הזה:

APIObject stockAPI = APIObject חדש ("stock-api", "stock.api", "// localhost: 8080", "/"); HttpEntity apiEntity = HttpEntity חדש (stockAPI); ResponseEntity addAPIResp = restTemplate.postForEntity ("// localhost: 8001 / apis", apiEntity, String.class); assertEquals (HttpStatus.CREATED, addAPIResp.getStatusCode ());

כאן הוספנו API עם התצורה הבאה:

{"name": "stock-api", "hosts": "stock.api", "upstream_url": "// localhost: 8080", "uris": "/"}
  • "שֵׁם" הוא מזהה עבור ה- API, המשמש בעת מניפולציה על התנהגותו
  • "מארחים" ישמש לניתוב בקשות נכנסות לנתון "Upstream_url" על ידי התאמת ה- "מנחה" כּוֹתֶרֶת
  • נתיבים יחסית יתואמו ל" uris "שהוגדר

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

restTemplate.delete ("// localhost: 8001 / apis / stock-api");

לאחר הוספת APIs, הם יהיו זמינים לצריכה דרך // localhost: 8000:

מחרוזת apiListResp = restTemplate.getForObject ("// localhost: 8001 / apis /", String.class); assertTrue (apiListResp.contains ("stock-api")); כותרות HttpHeaders = HttpHeaders חדשות (); headers.set ("מארח", "stock.api"); RequestEntity requestEntity = RequestEntity חדש (כותרות, HttpMethod.GET, URI חדש ("// localhost: 8000 / stock / btc")); ResponseEntity stockPriceResp = restTemplate.exchange (requestEntity, String.class); assertEquals ("10000", stockPriceResp.getBody ());

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

על ידי בקשה // localhost: 8000 / stock / btc, אנו מקבלים את אותו השירות כמו שאילתות ישירות מאת // localhost: 8080 / stock / btc.

4.2. הוספת צרכן API

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

בואו נוסיף צרכן לממשק ה- API של שאילתת המניות שלנו כדי שנוכל להפעיל את תכונת האימות בהמשך.

להוסיף צרכן ל- API זה פשוט כמו להוסיף API. שמו (או מזהה) של הצרכן הוא השדה הנדרש היחיד מכל נכסי הצרכן:

ConsumerObject צרכן = ConsumerObject חדש ("eugenp"); HttpEntity addConsumerEntity = HttpEntity חדש (צרכן); ResponseEntity addConsumerResp = restTemplate.postForEntity ("// localhost: 8001 / consumer /", addConsumerEntity, String.class); assertEquals (HttpStatus.CREATED, addConsumerResp.getStatusCode ());

כאן הוספנו את "eugenp" כצרכן חדש:

{"שם משתמש": "eugenp"}

4.3. הפעלת אימות

הנה התכונה החזקה ביותר של קונג, תוספים.

כעת אנו נשתמש בתוסף auth על ממשק ה- API של שאילתת המניות הסמוכה שלנו:

PluginObject authPlugin = PluginObject חדש ("מפתח אימות"); ResponseEntity enableAuthResp = restTemplate.postForEntity ("// localhost: 8001 / apis / stock-api / plugins", HttpEntity חדש (authPlugin), String.class); assertEquals (HttpStatus.CREATED, enableAuthResp.getStatusCode ());

אם ננסה לשאול את מחיר המניה באמצעות ה- URI של ה- proxy, הבקשה תידחה:

כותרות HttpHeaders = HttpHeaders חדשות (); headers.set ("מארח", "stock.api"); RequestEntity requestEntity = RequestEntity חדש (כותרות, HttpMethod.GET, URI חדש ("// localhost: 8000 / stock / btc")); ResponseEntity stockPriceResp = restTemplate .exchange (requestEntity, String.class); assertEquals (HttpStatus.UNAUTHORIZED, stockPriceResp.getStatusCode ());

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

מחרוזת consumerKey = "eugenp.pass"; KeyAuthObject keyAuth = KeyAuthObject חדש (consumerKey); ResponseEntity keyAuthResp = restTemplate.postForEntity ("// localhost: 8001 / consumer / eugenp / key-auth", HttpEntity חדש (keyAuth), String.class); assertTrue (HttpStatus.CREATED == keyAuthResp.getStatusCode ());

לאחר מכן אוגן יכול להשתמש ב- API זה כמו בעבר:

כותרות HttpHeaders = HttpHeaders חדשות (); headers.set ("מארח", "stock.api"); headers.set ("apikey", consumerKey); RequestEntity requestEntity = חדש RequestEntity (כותרות, HttpMethod.GET, URI חדש ("// localhost: 8000 / stock / btc")); ResponseEntity stockPriceResp = restTemplate .exchange (requestEntity, String.class); assertEquals ("10000", stockPriceResp.getBody ());

5. תכונות מתקדמות

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

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

5.1. איזון עומסים

קונג מספק שתי אסטרטגיות של בקשות לאיזון עומסים לשירותי backend: מאזן טבעת דינמי ושיטה מבוססת DNS פשוטה. למען הפשטות, נשתמש במאזנת הטבעת.

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

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

ראשית, בואו נכין את הזרם:

UpstreamObject upstream = UpstreamObject חדש ("stock.api.service"); ResponseEntity addUpstreamResp = restTemplate.postForEntity ("// localhost: 8001 / upstreams", HttpEntity חדש (upstream), String.class); assertEquals (HttpStatus.CREATED, addUpstreamResp.getStatusCode ());

לאחר מכן, הוסף שתי מטרות למעלה הזרם, גרסת מבחן עם משקל = 10, וגרסת שחרור עם משקל = 40:

TargetObject testTarget = TargetObject חדש ("localhost: 8080", 10); ResponseEntity addTargetResp = restTemplate.postForEntity ("//localhost:8001/upstreams/stock.api.service/targets", HttpEntity חדש (testTarget), String.class); assertEquals (HttpStatus.CREATED, ddTargetResp.getStatusCode ()); TargetObject releaseTarget = TargetObject חדש ("localhost: 9090", 40); addTargetResp = restTemplate.postForEntity ("//localhost:8001/upstreams/stock.api.service/targets", HttpEntity חדש (releaseTarget), String.class); assertEquals (HttpStatus.CREATED, addTargetResp.getStatusCode ());

עם התצורה לעיל, אנו יכולים להניח ש 1/5 מהבקשות יעבור לגרסת הבדיקה ו- 4/5 ילך לגרסת הגרסה:

APIObject stockAPI = חדש APIObject ("מאזן מאוזן-api", "balanced.stock.api", "//stock.api.service", "/"); HttpEntity apiEntity = HttpEntity חדש (stockAPI); ResponseEntity addAPIResp = restTemplate.postForEntity ("// localhost: 8001 / apis", apiEntity, String.class); assertEquals (HttpStatus.CREATED, addAPIResp.getStatusCode ()); כותרות HttpHeaders = HttpHeaders חדשות (); headers.set ("מארח", "balanced.stock.api"); עבור (int i = 0; i <1000; i ++) {RequestEntity requestEntity = RequestEntity חדש (כותרות, HttpMethod.GET, URI חדש ("// localhost: 8000 / stock / btc")); ResponseEntity stockPriceResp = restTemplate.exchange (requestEntity, String.class); assertEquals ("10000", stockPriceResp.getBody ()); } int releaseCount = restTemplate.getForObject ("// localhost: 9090 / stock / reqcount", Integer.class); int testCount = restTemplate.getForObject ("// localhost: 8080 / stock / reqcount", Integer.class); assertTrue (Math.round (releaseCount * 1.0 / testCount) == 4);

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

5.2. אבטחת ממשק ה- API לניהול

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

לחלופין, אנו יכולים לגרום לקונג לשמש כ- proxy עבור ממשק ה- API לניהול עצמו. נגיד שאנחנו רוצים לנהל ממשקי API עם הנתיב "/ admin-api", אנחנו יכולים להוסיף API כזה:

APIObject stockAPI = חדש APIObject ("admin-api", "admin.api", "// localhost: 8001", "/ admin-api"); HttpEntity apiEntity = HttpEntity חדש (stockAPI); ResponseEntity addAPIResp = restTemplate.postForEntity ("// localhost: 8001 / apis", apiEntity, String.class); assertEquals (HttpStatus.CREATED, addAPIResp.getStatusCode ());

כעת נוכל להשתמש בממשק ה- API הסמוך למנהל API:

כותרות HttpHeaders = HttpHeaders חדשות (); headers.set ("מארח", "admin.api"); APIObject baeldungAPI = APIObject חדש ("baeldung-api", "baeldung.com", "//ww.baeldung.com", "/"); RequestEntity requestEntity = RequestEntity חדש (baeldungAPI, כותרות, HttpMethod.POST, URI חדש ("// localhost: 8000 / admin-api / apis")); ResponseEntity addAPIResp = restTemplate. Exchange (requestEntity, String.class); assertEquals (HttpStatus.CREATED, addAPIResp.getStatusCode ());

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

6. סיכום

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

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

כמו תמיד, ניתן למצוא את היישום המלא ב- Github.


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