בדיקת קפקא ומגף קפיץ

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

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

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

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

2. תלות

כמובן שנצטרך להוסיף את התקן אביב-קפקא תלות שלנו pom.xml:

 org.springframework.kafka spring-kafka 2.6.3.RELEASE 

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

 org.springframework.kafka spring-kafka-test 2.6.3.RELEASE test 

ולבסוף, נוסיף את תלות קפקא של Testcontainers, אשר זמינה גם ב- Maven Central:

 מבחן org.testcontainers kafka 1.15.0 

כעת, לאחר שהגדרנו את כל התלות הדרושה, אנו יכולים לכתוב יישום פשוט של Spring Boot באמצעות Kafka.

3. יישום פשוט של קפקא ליצרן ולצרכן

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

נתחיל בהגדרת נקודת הכניסה ליישום:

@SpringBootApplication @EnableAutoConfiguration class public KafkaProducerConsumerApplication {public static void main (String [] args) {SpringApplication.run (KafkaProducerConsumerApplication.class, args); }}

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

3.1. הגדרת מפיק

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

מחלקה ציבורית @Component KafkaProducer {לוגר סופי סטטי פרטי LOGGER = LoggerFactory.getLogger (KafkaProducer.class); @ KafkaTemplate פרטית אוטומטית kafkaTemplate; שליחה בטלנית ציבורית (נושא מחרוזת, מטען מחרוזת) {LOGGER.info ("שליחת מטען =" {} "לנושא =" {} "", מטען, נושא); kafkaTemplate.send (נושא, מטען); }}

שֶׁלָנוּ KafkaProducer שעועית שהוגדרה לעיל היא רק עטיפה סביב KafkaTemplate מעמד. מחלקה זו מספקת פעולות ברמת בטיחות ברמה גבוהה, כגון שליחת נתונים לנושא הניתן, וזה בדיוק מה שאנחנו עושים אצלנו לִשְׁלוֹחַ שיטה.

3.2. הגדרת הצרכן

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

מחלקה ציבורית @Component KafkaConsumer {לוגר לוגרי סופי סטטי פרטי LOGGER = LoggerFactory.getLogger (KafkaConsumer.class); תפס CountDownLatch פרטי = CountDownLatch חדש (1); מטען פרטי מחרוזת = null; @KafkaListener (topics = "$ {test.topic}") קבלת חלל ציבורי (ConsumerRecord consumerRecord) {LOGGER.info ("קיבלה מטען =" {} "", consumerRecord.toString ()); setPayload (consumerRecord.toString ()); latch.countDown (); } CountDownLatch ציבורי getLatch () {תפס חזרה; } מחרוזת ציבורית getPayload () {מטען החזר; }}

הצרכן הפשוט שלנו משתמש ב- @KafkaListener ביאור על לְקַבֵּל שיטה להאזנה להודעות בנושא נתון. נראה בהמשך כיצד אנו מגדירים את ה- test.topic מהבדיקות שלנו.

יתר על כן, שיטת הקבלה שומרת את תוכן ההודעה בשעועית שלנו ומקטינה את ספירת ה- בְּרִיחַ מִשְׁתַנֶה. משתנה זה הוא שדה מונה פשוט לבטיחות הברגה, ונשתמש בו מאוחר יותר מהבדיקות שלנו כדי להבטיח שקיבלו בהצלחה הודעה.

עכשיו שיש לנו יישום Kafka הפשוט שלנו באמצעות Spring Boot מיושם בואו נראה איך אנחנו יכולים לכתוב מבחני אינטגרציה.

4. מילה על בדיקה

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

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

4.1. מאפייני יישום

אנו נשתמש במערך קל מאוד של מאפייני תצורת יישומים מהבדיקות שלנו. נגדיר מאפיינים אלה במערכת שלנו src / test / resources / application.yml קוֹבֶץ:

קפיץ: kafka: צרכן: קיזוז אוטומטי-reset: המוקדם מזהה הקבוצה: מבחן baeldung: נושא: embedded-test-topic

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

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

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

5. בדיקה באמצעות קפקא משובץ

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

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

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

@SpringBootTest @DirtiesContext @ EmbeddedKafka (מחיצות = 1, brokerProperties = {"מאזינים = PLAINTEXT: // localhost: 9092", "port = 9092"}) מחלקה EmbeddedKafkaIntegrationTest {@ צרכנית KafkaConsumer פרטית פרטית; @ מפיק KafkaProducer פרטית אוטומטית; @Value ("$ {test.topic}") נושא מחרוזת פרטי; @ מבחן הריק פומבי שניתן EmbeddedKafkaBroker_whenSendingtoSimpleProducer_thenMessageReceived () זורק חריג {producer.send (נושא, "שליחה עם KafkaProducer פשוט משלו"); consumer.getLatch (). ממתינים (10000, TimeUnit.MILLISECONDS); assertThat (consumer.getLatch (). getCount (), equalTo (0L)); assertThat (consumer.getPayload (), containString ("נושא משובץ למבחן")); }}

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

  • ה @ SpringBootTest ביאור יבטיח שהמבחן שלנו מאתחל את הקשר היישום Spring
  • אנו משתמשים גם ב- @DirtiesContext ביאור, אשר יוודא שההקשר הזה מנוקה ומאופס בין בדיקות שונות

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

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

לאחר מכן, אנו מחברים את החוט האוטומטי שלנו צרכן ו יַצרָן וקבע תצורה של נושא שישתמש בערך שלנו application.properties.

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

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

... 12: 45: 35.099 [main] INFO cbkafka.embedded.KafkaProducer - שליחת מטען = "שליחה עם KafkaProducer הפשוט שלנו" לנושא = "embedded-test-topic" ... 12: 45: 35.103 [org .springframework.kafka.KafkaListenerEndpointContainer # 0-0-C-1] INFO cbkafka.embedded.KafkaConsumer - קיבלו מטען = 'ConsumerRecord (topic = embedded-test-topic, partition = 0, leaderEpoch = 0, offset = 1, CreateTime = 1605267935099, גודל מפתח סידורי = -1, גודל ערך סידורי = 41, כותרות = RecordHeaders (כותרות = [], isReadOnly = false),  key = null, value = שליחה עם KafkaProducer הפשוט שלנו) ' 

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

6. בדיקת קפקא עם טסט מיכלים

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

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

בואו נגדיר מבחן אינטגרציה נוסף שיהיה די דומה לזה שראינו בחלק הקודם:

@RunWith (SpringRunner.class) @Import (com.baeldung.kafka.testcontainers.KafkaTestContainersLiveTest.KafkaTestContainersConfiguration.class) @SpringBootTest (שיעורים = KafkaProducerConsumerApplication.class) @DirtiesConka .parse ("confluentinc / cp-kafka: 5.4.3")); @ צרכני KafkaConsumer פרטיים מאוחרים; @ מפיק KafkaProducer פרטית אוטומטית; @Value ("$ {test.topic}") נושא מחרוזת פרטי; @Test הציבור בטל שניתן KafkaDockerContainer_whenSendingtoSimpleProducer_thenMessageReceived () זורק חריג {producer.send (נושא, "שליחה עם בקר משלו"); consumer.getLatch (). ממתינים (10000, TimeUnit.MILLISECONDS); assertThat (consumer.getLatch (). getCount (), equalTo (0L)); assertThat (consumer.getPayload (), containString ("נושא בדיקה מוטבע")); }}

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

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

@Bean מפה ציבורית ציבוריתConfigs () {אביזרי מפה = HashMap חדש (); props.put (ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers ()); props.put (ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "המוקדם ביותר"); props.put (ConsumerConfig.GROUP_ID_CONFIG, "baeldung"); // עוד אביזרי החזרת תצורה סטנדרטיים; } @Bean פומבית ProducerFactory producerFactory () {Map configProps = HashMap חדש (); configProps.put (ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers ()); // תצורה סטנדרטית יותר מחזירה DefaultKafkaProducerFactory חדש (configProps); }

לאחר מכן אנו מתייחסים לתצורה זו באמצעות ה- @יְבוּא ביאור בתחילת המבחן שלנו.

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

bootstrap.servers = [PLAINTEXT: // localhost: 32789]

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

  • בודק את הגדרת ה- Docker המקומית שלנו.
  • מושך את confluentinc / cp-kafka: 5.4.3 תמונת העגינה במידת הצורך
  • מתחיל מיכל חדש ומחכה שהוא יהיה מוכן
  • לבסוף, כבה ומוחק את המיכל לאחר סיום הבדיקה שלנו

שוב, זה אושר על ידי בדיקת תפוקת הבדיקה:

13: 33: 10.396 [main] INFO 🐳 [confluentinc / cp-kafka: 5.4.3] - יצירת מיכל לתמונה: confluentinc / cp-kafka: 5.4.3 13: 33: 10.454 [main] INFO 🐳 [confluentinc / cp -kafka: 5.4.3] - החל מיכל עם ID: b22b752cee2e9e9e6ade38e46d0c6d881ad941d17223bda073afe4d2fe0559c3 13: 33: 10.785 [הראשית] INFO 🐳 [confluentinc / CP-קפקא: 5.4.3] - מיכל confluentinc / CP-קפקא: 5.4.3 מתחיל: b22b752cee2e9e9e6ade38e46d0c6d881ad941d17223bda073afe4d2fe0559c3

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

7. מסקנה

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

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

כמו תמיד, קוד המקור המלא של המאמר זמין באתר GitHub.


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