Otomasyon QAKıdemli Otomasyon QA Mühendisi

Kafka tabanlı olay şemalarının birden fazla tüketici sürümünün bir mikro hizmet ekosisteminde bir arada var olduğu durumlarda bozulmaların önüne geçecek bir sözleşme testi iş akışı tasarlama süreciniz nasıl olur?

Hintsage yapay zeka asistanı ile mülakatları geçin

Soruya Cevap

Soru Tarihçesi

Asenkron mesajlaşma için sözleşme testleri, organizasyonların mikro hizmetleri birbirinden ayırmak ve gerçek zamanlı veri akışı sağlamak için Kafka tabanlı olay odaklı mimariler benimsemesiyle ortaya çıkmıştır. Sözleşme testi erken uygulamaları, öncelikle REST API'lerine odaklanmış, bu da mesajlaşma entegrasyonlarının, üreticilerin olay yüklerini tüketicilerin bilgisizliğiyle değiştirdiğinde sessiz bozulmalara karşı savunmasız kalmasına yol açmıştır. Çoklu sürüm tüketici desteği konusunda özel zorluk, ekiplerin Kafka konularının genellikle farklı dağıtım döngüleri ve yükseltme döngülerine sahip birden fazla tüketici uygulaması hizmet ettiğini fark etmesiyle ortaya çıkmıştır. Bu soru, bir ödeme hizmetindeki tek bir olay şeması değişikliğinin, analiz, bildirim ve denetim hizmetlerinde aynı anda arızalara yol açtığı gerçek dünya senaryolarını yansıtır. Bu, dağıtık akış platformlarındaki şema kayıt doğrulaması ile davranışsal sözleşme güvenceleme arasındaki kritik boşluğu ele almaktadır.

Problem

Temel zorluk, bir Kafka üreticisinin olay şemalarını, tüm aşağı akış tüketicilerinin eşzamanlı dağıtımını zorlamadan evrimleştirebilmesidir; bu durum mikro hizmet bağımsızlığı ilkelerini ihlal eder. Geleneksel şema kayıtları, Confluent gibi, serileştirme seviyesinde geriye dönük uyumluluğu doğrularken, bir alanın opsiyonelden zorunluya değiştirilmesi veya tarih formatlarının değiştirilmesi gibi tüketici iş mantığını bozan anlamsal değişiklikleri algılayamaz. Üretim ortamında birden fazla tüketici sürümü beraber var olduğunda, üretici en eski desteklenen tüketici ile uyumluluğu sürdürmek zorundadır, oysa yeni tüketiciler ek alanlar beklemekte ve bu, manuel koordinasyonun ölçekli bir şekilde yönetemeyeceği bir sürümlendirme matrisine neden olmaktadır. Bu, üretim olaylarının serileştirmenin başarısız olması veya eski tüketicilerde yanlış işlenmesi durumunda "şema kayması" ile sonuçlanarak mesaj işleme gecikmelerine ve potansiyel veri kaybına yol açar. Problem daha da artar çünkü Kafka'nın yayın-abone modeli, bir bozulmanın tüm aboneleri aynı anda etkilemesi anlamına gelir; REST'te yönlendirme, uç noktaları bağımsız bir şekilde sürümlendirebilir.

Çözüm

Çözüm, yeni tüketici sürümleri için beklenen olay yüklerini tanımlayan mesaj sözleşmeleri üreten ve gerçek serileştirme mantığına karşı doğrulanan, Confluent Şema Kayıt entegrasyonu ile bir araya getirilmiş tüketici odaklı sözleşme testleri uygulamayı gerektirir. Üreticiler, her tüketici sürümü için beklenen olay yüklerini tanımlayan mesaj sözleşmeleri oluşturur ve bunlar çalışan bir Kafka aracısı gerektirmeden, gerçek serileştirme mantığına karşı doğrulanır. Pact Broker, tüketici sürüm etiketleri kullanarak sözleşme sürümlerini yönetir ve "yeni kod değişikliklerinin yayına hazır olup olmadığını" kontrol eden bir kontrol mekanizması sağlar; bu, yeni bir üretici kod değişiminin, eski ve mevcut tüketiciler için sözleşmeleri karşıladığını doğrular. Şema evrimi için iş akışı, üreticilerin önce yeni alanlar eklerken eski alanları koruduğu, daha sonra tüm tüketiciler güncellenip sözleşmelerini güncelledikten sonra yalnızca geçersiz alanları kaldırmaları gerektiğini belirten "sözleşmeyi genişlet" modelini uygular. Bu, Pact doğrulama sürecinde etiketli herhangi bir tüketici sürümüne karşı başarısız olduğunda yapıların başarısız olduğu CI kapılarıyla otomatik hale getirilir, bu da davranışsal uyumluluğu basit şema yapısının ötesinde sağlar.

@PactTestFor(providerName = "payment-service", providerType = ProviderType.ASYNCH) public class PaymentEventContractTest { @Pact(consumer = "analytics-service", consumerVersion = "v2.1.0") public MessagePact paymentProcessedPactV2(MessagePactBuilder builder) { return builder .expectsToReceive("analiz için bir ödeme işlenmiş olayı") .withContent(new PactDslJsonBody() .uuid("paymentId") .decimalType("amount") .stringType("currency", "USD") .stringType("status") // v2 tarafından gerekli olan yeni alan .date("timestamp", "yyyy-MM-dd'T'HH:mm:ss")) .toPact(); } @Pact(consumer = "notification-service", consumerVersion = "v1.0.0") public MessagePact paymentProcessedPactV1(MessagePactBuilder builder) { return builder .expectsToReceive("bildirimler için bir ödeme işlenmiş olayı") .withContent(new PactDslJsonBody() .uuid("paymentId") .decimalType("amount") .stringType("currency", "USD")) .toPact(); } @Test @PactTestFor(pactMethod = "paymentProcessedPactV2") public void verifyV2Contract(List<Interaction> interactions) { byte[] messageBytes = interactions.get(0).getContents().getValue(); PaymentEvent event = deserialize(messageBytes); assertThat(event.getStatus()).isNotNull(); analyticsProcessor.process(event); } }

Bu kod, üreticinin hem eski hem de mevcut gereksinimleri sürekli olarak karşılayacağından emin olmak için farklı şema sürümleriyle birden fazla tüketici sözleşmesini test etmeyi göstermektedir.

Hayattan Bir Durum

Bir e-ticaret platformu, ödeme işleme ekibinin Kafka ödeme olaylarına "indirim Uygulandı" boolean alanını eklemesi ve bunu zorunlu yapmasıyla kritik bir kesinti yaşadı. Analiz ekibi bu alanı işlemek için tüketicilerini güncelledi, ancak eski bildirim servisi, bilinmeyen alanları reddeden sıkı serileştirme kullandığından dolayı çöktü ve bu da sipariş tamamlama hattında zincirleme hatalara yol açtı. Kesinti, olay otobüsü üzerinden dağıldığı için iki saat sürdü ve ödeme olaylarına bağımlı üç hizmette mesaj işleme gecikmelerine ve uyarı fırtınalarına neden oldu. Ekip başlangıçta tüm tüketicilerin esnek serileştirme şemalarını kullanmasını zorlamayı düşündü, ancak bunun gelecekteki kırıcı değişiklikleri gizleyeceğini ve entegrasyon uyumsuzluklarının gözlemlenmesini üretim hataları meydana gelene kadar erteleyebileceğini fark ettiler.

Tekrar oluşumunu önlemek için üç potansiyel çözüm değerlendirildi. İlk yaklaşım, her hizmet sürümünün aynı anda dağıtıldığı özel bir entegrasyon test ortamı oluşturmaktı, ancak bu, pahalı altyapı gerektiriyordu ve testlerin yürütülmesi kırk dakika sürdü, bu da sürekli dağıtım boru hattını önemli ölçüde yavaşlattı. İkinci seçenek, yalnızca Confluent Şema Kayıtlarının geriye dönük uyumluluk kontrollerini kullanmayı öneriyordu, ancak bu sadece şemanın Avro seviyesinde geriye dönük uyumlu olduğunu doğruladı, yani belirli bir tüketici için veri ile sözleşmelerin birebir uyumlu olduğu veya gerekli alanların bulunduğu doğrulanmadı. Üçüncü çözüm, Pact sözleşme testlerini mevcut Şema Kaydı ile birleştirdi, bu da her tüketicinin bekledikleri alanları ve bu alanların beklenen veri formatlarını kesin bir şekilde belirttiği bağımsız sözleşmeler yayımlamasına olanak tanıyordu, bu da genel şema yapısından bağımsızdır.

Organizasyon, üçüncü çözümü seçti çünkü bu, genel yapısal uyumluluktan ziyade tüketici özelinde davranışsal doğrulama sağlıyordu. Pact Broker'ı, tüketici sürümlerini anlamsal etiketlerle izlemek üzere yapılandırdılar ve ödeme hizmetinin herhangi bir dağıtımın ilerleyebilmesi için hem bildirim hizmeti- v1 hem de analiz hizmeti-v2 sözleşmelerini doğrulamasını gerektirdiler. Ödeme ekibi, yeni gerekli alanı eklemeyi tekrar denediklerinde, CI boru hattı hemen başarısız oldu çünkü v1 sözleşme doğrulaması başarısız olmuştu ve bu, onlardan önce alanı başlangıçta opsiyonel hale getirme ve ekipleri gelecek değişiklik hakkında bilgilendirme yolunu izlemelerini zorladı. Takip eden çeyrekte, entegrasyona bağlı üretim olayları yüzde seksen beş oranında düştü ve ekip, her bir aşağı akış ekibiyle koordinasyonu gerektirmeden günde üç kez üretici değişikliklerini güvenle dağıtabilme yeteneğini kazanarak dağıtım hızı ve sistem istikrarını önemli ölçüde artırdı.

Adayların Genellikle Göz Ardı Ettiği Noktalar


Neden şema kaydı doğrulaması, Kafka üreticileri ve tüketicileri arasında olay uyumluluğunu sağlamak için yetersizdir ve hangi belirli hataları gözden kaçırır?

Adaylar genellikle Confluent Şema Kaydının geriye dönük uyumluluk modlarının üretim ortamlarındaki kırıcı değişikliklere karşı yeterli koruma sağladığını varsayarlar. Ancak, şema kayıtları yalnızca verinin Avro veya JSON Şemasına uygun yapısına uyduğunu doğrular, değerlerin tüketici beklentilerini karşıladığını veya anlamsal anlamların sürümler arasında tutarlı kaldığını doğrulamaz. Örneğin, bir şema zaman damgası alanı için bir dizeyi kabul edebilir, ancak tüketici ISO8601 formatı beklerken üretici aniden Unix epoch'a geçiş yaparsa; kayıt her ikisini de geçerli dizeler olarak kabul eder, ancak tüketici çalışma zamanında ayrıştırma istisnalarıyla başarısız olur. Sözleşme testleri, gerçek tüketici kodunu gerçek üretici çıktılarıyla çalıştırarak bu anlamsal ve değer düzeyindeki uyumsuzlukları yakalar ve yapılandırma doğrulamasının ötesinde davranışsal uyumluluğu güvence altına alır.


Birden fazla üretici aynı Kafka konusuna yayın yaptığında ve tüketiciler tüm kaynaklardan tutarlı şemalar beklediğinde "elmas problemi"ni nasıl ele alırsınız?

Bu soru, bir konunun birden fazla üretici hizmetinden olayları topladığı karmaşık olay kaynakları senaryolarını anlama yeteneğini test eder; bu da tek bir kaynaktan ziyade birden fazla üretici hizmetinin olayları yayınladığıdurumlarda geçerlidir. Adaylar genellikle Pact'in genellikle bire bir sağlayıcı-tüketici ilişkilerini modellerken, Kafka konularının genellikle farklı kod tabanlarına sahip birden fazla yayıncısı olduğunu gözden kaçırırlar. Çözüm, konuyu kendisinin sağlayıcı arayüzü olarak ele almak; her üreticinin olaylarının bu konunun birleşik sözleşmesini karşıladığından emin olmak için bir "meta-sağlayıcı" oluşturmaktır; böylece tüketiciler, hangi üretici örneği olayları yayımlarsa yaymıyor olsunlar, tutarlı mesaj yapıları alırlar. Bu, her üreticinin olaylarının konu için birleşik sözleşmeyi karşıladığını doğrulamak için Pact Broker'ın özelliğini kullanarak - veya alternatif olarak, bir ekip bekçiliği olan genelleştirilmiş bir şema sahipliği modeli kabul etmek gerektirir; bu modelde bir takım tüm üreticiler arasındaki değişiklikleri koordine eder.


Kafka şema evrimi bağlamında "sözleşmeyi genişlet" modeli nedir ve sözleşme testi bu iş akışını CI/CD sırasında nasıl uygular?

Birden fazla aktif tüketici sürümüne sahip mesajlaşma sistemlerinde sıfır dumanlı şema değişikliklerinin pratik mekaniklerini açıklamakta birçok aday zorlanmaktadır. Genişletme-sözleşme modeli, üreticilerin önce yeni alanlar ekleyen değişiklikleri dağıttıkları, eski alanların yerinde kaldığı (genişleme aşaması) ve ardından yalnızca tüm tüketiciler yeni alanları kullanacak şekilde yükseldiğinde eski alanların kaldırıldığı (sözleşme aşaması) gerektirir. Sözleşme testi, Pact Broker'da her tüketici için ayrı sözleşme sürümleri koruyarak bunu uygular; üreticinin CI boru hattı, tüm aktif tüketici sürümlerine karşı uyumluluğu doğrulamak zorundadır; bu, bir dağıtım yetkilisi olabilmesi için. Eğer bir üretici, v1 tüketicilerin hala gerekli olduğu bir alanı kaldırmaya çalışırsa, yayına hazır olma kontrolü hemen başarısız olur ve bozulmanın Kafka'ya ulaşmasını engeller. Adaylar genellikle bunun, brokerda açık sürüm etiketlemesi gerektirdiğini ve boru hattının yalnızca en son olanı değil, tüm etiketli tüketici sürümleri için sorgulama yapılması gerektiğini gözden kaçırırlar; bu, tüm tüketici nüfusu için kapsamlı uyumluluğu sağlamak üzere gereklidir.