17 yıl içinde, dürtü nedeniyle onu kontrol etmedim (tabii ki, son zamanlarda bazı hayranlar benden dürtüsel olmamı ve başka bir dalgayı güncellememi istedi), mülakat sorularıyla birlikte bir dizi Dubbo kaynak kodu analizi yazdım.
Röportaj deneyimime göre özgeçmiş üzerine ilke ve kaynak kodu gibi anahtar kelimeleri yazabilenler oldukça rekabetçidir.Geçen hafta bir kamu hesabı hayranıyla yapılan röportaj şu şekilde:
Gerçekten de, görüşme sırasında bir kaynak kodu analizi dalgası görüşmeciyi kesinlikle şok edebilir! Ancak, sakin bir dönemden sonra, görüşmeci aniden geldi ve olay örgüsünü tersine çevirdi:
"Dubbo kaynak kodunu çok iyi biliyorsunuz, onu kullanırken herhangi bir tuzakla karşılaştınız mı?"
Hazırlıksız, hemen 50K blöf yaptığı bir durumla karşılaştı ve sadece 5K blöf yapabildi, bu yüzden panikledi!
2
Nasıl karşılık verileceğine dair
Görüşmede herkesin benzer sorunlarla karşılaştığına inanıyorum çünkü internette çok sayıda kaynak kodu analizi var ve birçok kişi "ön test" yapıyor. Ancak ayrıntıları sormayı seven bir görüşmeci ile tanıştığınızda, saklanacak hiçbir yer kalmaz.
Bu sorunla karşılaştık, nasıl karşılık vereceğiz? Aşağıda bir dizi gerçek sahneyi anlatacağız. Sonuçta, sadece gerçek sahneye sahip gerçek kaynak kodu (çok önemli), bu tür bir problemle karşılaşırsa, kaplanın ağlamasına neden olmaz.
3
Gerçek sahne açıklaması
Örnek olarak bu sohbet günlüğündeki gerçek sahneyi ele alalım:
Ardından iş ilişkisini kaldırıp en basit modeli çıkarıyoruz. Şirkette genellikle kendi özel istisnalarımız vardır ve daha sonra bu özel istisna, diğer modüllerin güvenmesi için genellikle common.jar'a yerleştirilir. Örneğin, burada bir HelloException tanımlıyorum:
1 halka açık sınıf HelloException genişler Çalışma zamanı istisnası { 2 3 halka açık HelloException () { 4 } 5 6 halka açık HelloException ( Dize İleti) { 7 Süper (İleti); 8 } 9 10 } Ardından aşağıdaki gibi en basit Dubbo demosu yazıyoruz:
arayüz
1 halka açık arayüz DemoService { 2 3 Dize Merhaba de( Dize adı); 4 5 } Sağlayıcı
1 halka açık sınıf DemoServiceImpl uygular DemoService { 2 3 halka açık Dize Merhaba de( Dize isim) { 4 atmak yeni HelloException ( "Resmi Hesap: Fei Chao" ); 5 } 6 7 } tüketici
1 halka açık sınıf DemoAction { 2 3 özel DemoService demoService; 4 5 halka açık geçersiz setDemoService ( DemoService demoService) { 6 bu .demoService = demoService; 7 } 8 9 halka açık geçersiz Başlat() atar İstisna { 10 Deneyin { 11 Dize merhaba = demoService.sayHello ( "Resmi Hesap: Fei Chao" ); 12 } tutmak ( HelloException helloException) { 13 Sistem . dışarı .println ( "HelloException'ı buradan yakalayın" ); 14 } 15 } 16 17 } Sohbet geçmişinin açıklamasına göre:
Şu anda, tüketici sağlayıcıyı arar ve sağlayıcı HelloException oluşturur.
Ancak tüketicinin yakaladığı şey HelloException değildir.
Sonra koşarız ve görürüz:
Beklenildiği gibi. Bu neden böyle? Dubbo kaynak kodu analiz serisini daha önce görmemiş olan öğrenciler, şu anda en etkili çözümü sıklıkla kullanıyorlar, istisna yığınını WeChat grubuna atıyorlar, yardım istiyorlar, ancak çoğu zaman kazanç sağlamıyorlar ve sonra toplumun neden bu kadar kayıtsız olduğuna üzülüyorlar!
Ancak, kamu hesabının eski hayranlarının kaynak kodunu okuma becerilerinde zaten ustalaştığına inanıyorum ve tıpkı Fei Chao gibi, doğrudan kaynak koduna, bir istisna olursa, önce istisna yığınına bakalım:
İlk bakışta bu çizginin Fat Chao gibi anormal olduğuna inanıyorum, karanlıkta bir ateşböceği gibi çok canlı ve olağanüstü:
Öyleyse öğrenelim:
1 halka açık Sonuç çağırmak ( Invoker < ? > invoker , Çağrı çağrı ) atar RpcException { 2 Deneyin { 3 Sonuç sonuç = invoker . çağırmak ( çağrı ); 4 Eğer ( sonuç . hasException () GenericService . sınıf ! = invoker . getInterface ()) { 5 Deneyin { 6 Atılabilir istisna = sonuç . getException (); 7 8 // Kontrol edilen bir istisnaysa, doğrudan at 9 Eğer (! ( istisna örneği Çalışma zamanı istisnası ) ( istisna örneği İstisna )) { 10 dönüş sonuç ; 11 } 12 // Yöntem imzasında bir ifade var, doğrudan at 13 Deneyin { 14 Yöntem yöntem = invoker . getInterface (). getMethod ( çağrı . getMethodName (), çağrı . getParameterTypes ()); 15 Sınıf < ? > exceptionClassses = yöntem . getExceptionTypes (); 16 için ( Sınıf < ? > exceptionClass : exceptionClassses ) { 17 Eğer ( istisna . getClass (). eşittir ( exceptionClass )) { 18 dönüş sonuç ; 19 } 20 } yirmi bir } tutmak ( NoSuchMethodException e ) { yirmi iki dönüş sonuç ; yirmi üç } yirmi dört 25 // Yöntem imzasında tanımlanmayan istisnalar için sunucu tarafındaki HATA günlüğünü yazdırın 26 ağaç kesicisi . hata ( "Tarafından çağırılan, kontrol edilmemiş ve bildirilmemiş istisna var" + RpcContext . getContext (). getRemoteHost () 27 + ". hizmet: " + invoker . getInterface (). getName () + ", yöntem: " + çağrı . getMethodName () 28 + ", istisna:" + istisna . getClass (). getName () + ":" + istisna . getMessage (), istisna ); 29 30 // İstisna sınıfı ve arayüz sınıfı aynı jar paketindedir, doğrudan atın 31 Dize serviceFile = ReflectUtils . getCodeBase ( invoker . getInterface ()); 32 Dize istisna dosyası = ReflectUtils . getCodeBase ( istisna . getClass ()); 33 Eğer ( serviceFile == boş || istisna dosyası == boş || serviceFile . eşittir ( istisna dosyası )) { 34 dönüş sonuç ; 35 } 36 // JDK ile gelen bir istisnadır, doğrudan fırlatılır 37 Dize sınıf adı = istisna . getClass (). getName (); 38 Eğer ( sınıf adı . ile başlar ( "java." ) || sınıf adı . ile başlar ( "javax." )) { 39 dönüş sonuç ; 40 } 41 // Doğrudan fırlatılan Dubbo'nun kendisinin bir istisnasıdır. 42 Eğer ( istisna örneği RpcException ) { 43 dönüş sonuç ; 44 } 45 46 // Aksi takdirde, RuntimeException olarak sarın ve istemciye atın 47 dönüş yeni RpcResult ( yeni Çalışma zamanı istisnası ( StringUtils . toString ( istisna ))); 48 } tutmak ( Atılabilir e ) { 49 ağaç kesicisi . uyarmak ( "Tarafından çağrıldığında ExceptionFilter başarısız oldu" + RpcContext . getContext (). getRemoteHost () 50 + ". hizmet: " + invoker . getInterface (). getName () + ", yöntem: " + çağrı . getMethodName () 51 + ", istisna:" + e . getClass (). getName () + ":" + e . getMessage (), e ); 52 dönüş sonuç ; 53 } 54 } 55 dönüş sonuç ; 56 } tutmak ( Çalışma zamanı istisnası e ) { 57 ağaç kesicisi . hata ( "Tarafından çağırılan, kontrol edilmemiş ve bildirilmemiş istisna var" + RpcContext . getContext (). getRemoteHost () 58 + ". hizmet: " + invoker . getInterface (). getName () + ", yöntem: " + çağrı . getMethodName () 59 + ", istisna:" + e . getClass (). getName () + ":" + e . getMessage (), e ); 60 atmak e ; 61 } 62 } Telefondaki kaynak kodunu okumak dostça olmayabilir, ancak önemli değil, üzerinde tam Çince yorumlar var. İfade etmek istediğim şey şu:
- Kontrol edilen bir istisnaysa, doğrudan atın.
Açıkçası, HelloException, uyumlu olmayan RuntimeException'dır.
- Yöntem imzasında bir ifade varsa, doğrudan atın.
Açıkçası, arayüzümüz uyumsuz olan istisnayı beyan etmiyor.
- İstisna sınıfı ve arayüz sınıfı aynı jar paketindedir ve doğrudan atılır.
Açıkçası, istisna sınıfımız common.jar'da ve arayüz api.jar'da, bu da uyuşmuyor.
- JDK ile gelen ve doğrudan fırlatılan bir istisnadır.
Açıkçası, bu HelloException tarafımızdan özelleştirilmiştir ve uyumlu değildir.
- Doğrudan fırlatılan Dubbo'nun kendi istisnasıdır (RpcException).
Açıkçası, bu HelloException bizim özelliğimizdir ve RpcException ile neredeyse hiçbir ilgisi yoktur.
- Aksi takdirde, RuntimeException olarak sarın ve istemciye atın. Yukarıdaki 5 nokta karşılanmadığından, istisna bir RuntimeException istisnası olarak paketlenecektir (önemli).
Bu nedenle HelloException'ı RuntimeException olarak paketlendiği için yakalayamıyoruz.
4
Dubbo neden bu şekilde tasarlandı?
Belki de burada gördüğünüzde bu yargının çukurlaştığını göreceksiniz. Dubbo neden bu şekilde tasarladı? Kaynak koduna bakıyoruz, En önemli şey, yazarın bunu neden bu şekilde tasarladığını bilmektir. , Sadece bu tasarımın neden derinlemesine düşündüğünü bilerek, aksi takdirde onu ancak okuduktan sonra unutabilirsiniz.Neden tasarlandığını net bir şekilde açıklamak da herkesin Fei Chao resmi hesabına dikkat etmesi için önemli bir neden.
Aslında Dubbo'nun bu düşüncesi serileştirmeye dayanıyor. Bir düşünün, eğer sağlayıcı sadece sağlayıcı tarafından özelleştirilmiş bir istisna atarsa, o zaman istisna tüketiciye ulaşacak ve açık bir şekilde serileştirilemeyecektir, bu yüzden Dubbo'nun yargısına dikkat etmelisiniz.
Yargısına bir göz atalım:
- Kontrol edilen istisna ve RuntimeException farklı türlerdendir. Zorunlu paketleme, tür dönüştürme hatalarına neden olabilir, bu nedenle paketlenmemişlerse bunları doğrudan atın.
- Yöntem imzasında bir ifade vardır.Bu istisna provider.jar'da tanımlanmışsa, tüketici provider.jar yerine api.jar'a bağımlı olduğu için derleme derlenmeyecektir. Derlenebiliyorsa, tüketicinin bu istisnaya güvenebileceği anlamına gelir, bu nedenle serileştirme ile ilgili bir sorun olmaz ve doğrudan atılır.
- İstisna sınıfı ve arayüz sınıfı aynı jar paketindedir. Hem sağlayıcı hem de tüketici API'ye güvenir. İstisna bu API'de ise, serileştirme bir sorun olmayacak ve doğrudan atılacaktır.
- JDK ile gelen ve doğrudan fırlatılan bir istisnadır.
- Hem sağlayıcı hem de tüketici jdk'ye güveniyor, bu nedenle serileştirme ile ilgili bir sorun olmayacak, sadece atın.
- Doğrudan fırlatılan Dubbo'nun kendi istisnasıdır (RpcException).
- Hem sağlayıcı hem de tüketici Dubbo'ya güveniyor, bu nedenle serileştirme ile ilgili herhangi bir sorun olmayacak, bu yüzden onları doğrudan atın.
- Aksi takdirde, RuntimeException olarak sarın ve istemciye atın. Bu noktada, söylediğim türden bir istisna olabilir, bu istisna provider.jar tarafından özelleştirilir, ardından sağlayıcı atıldığında serileştirilir, çünkü tüketici provider.jar'a güvenmez, bu nedenle istisna tüketiciye ulaştığında serileştirilemez.. Ancak, RuntimeException olarak paketlenmişse farklıdır.Bu durumda istisna, JDK'daki bir sınıftır ve herhangi bir yerde serileştirilebilir.
5
Nasıl çözülür
Artık prensibi bildiğinize göre çözmesi kolaydır. Günlük olarak numaralandırmama izin verin, örneğin, iş tarafı arabiriminin belirtimden HelloException'ı bildirmesi gerekir.
6
Sonuna yaz
Tabii ki, Fei Chao ile röportaj yapıldığında kendisine benzer sorular soruldu: XXX ile herhangi bir tuzakla karşılaştınız mı? Bir şiddetli operasyonlar dalgasının analizi altında görüşmeci şunları söyledi:
"Çok yakışıklısın."
Fat Chao bilerek gülümsedi,
Ama dedi ki:
"Gülümsediğinde daha yakışıklı görünüyorsun"!
-
- Istio, gri tonlamalı yayıncılık hiç bu kadar kolay olmamıştı
-
- Nuggets Staking: Kripto para piyasası bir gecede zenginleşiyor
-
- Buffettin öğle yemeği teklifi galibi Justin Sun ve Wang Xiaochuan havada karşılıklı değiş tokuş yaptılar. 100 Bitcoin üzerine bahis oynamak istiyorlar mı?
-
- Piyasa kırılganlığı yavaş yavaş gösteriyor, ayı piyasasının son düzeltmesi mi yoksa gelecek mi?
-
- 2019WWDC'den hemen sonra, Apple iOS geliştiricileri tarafından dava edildi ...
-
- Alipay Karınca Ormanı 2019 Dünya Çevre Günü için pratik bir vaka seçildi
-
- Li Xiaolai, "zengin bir kulüp" veya "pırasaların seçici olarak kesilmesi" için geri dönüyor mu?
-
- Otomobil Finans Platformu Baijindai, Çevrimiçi Kredi İşinden İyi Bir Çıkış Yaptığını Duyurdu
-
- Boğa piyasası çaldığında HODL'yi seçecek misiniz?
-
- Yarı iletken ağır siklet! Infineon Cypress'in 10 milyar dolarlık satın aldığını duyurdu
-
- Bitcoin ETF pazarı soğutmayı erteledi, ana para birimleri sırayla yükselişi telafi etti ve döviz çemberi yeni fırsatları memnuniyetle karşıladı
-
- Bir haftada 4 milyardan fazla depolama patlak verdi ve "kısa ordu" "katledildi"