十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
17年的時候,因為一時沖動沒把持住(當然最近也有粉絲叫我再沖動一把再更新一波),結(jié)合面試題寫了一個系列的Dubbo源碼解析.目前公眾號大部分粉絲都是之前的粉絲,這里不過多介紹.
成都創(chuàng)新互聯(lián)主要為客戶提供服務(wù)項目涵蓋了網(wǎng)頁視覺設(shè)計、VI標志設(shè)計、營銷型網(wǎng)站建設(shè)、網(wǎng)站程序開發(fā)、HTML5響應(yīng)式網(wǎng)站建設(shè)、手機網(wǎng)站制作、微商城、網(wǎng)站托管及網(wǎng)頁維護、WEB系統(tǒng)開發(fā)、域名注冊、國內(nèi)外服務(wù)器租用、視頻、平面設(shè)計、SEO優(yōu)化排名。設(shè)計、前端、后端三個建站步驟的完善服務(wù)體系。一人跟蹤測試的建站服務(wù)標準。已經(jīng)為成都iso認證行業(yè)客戶提供了網(wǎng)站營銷推廣服務(wù)。
根據(jù)我的面試經(jīng)驗而言,能在簡歷上寫上原理、源碼等關(guān)鍵詞的,是非常具備核心競爭力的.上周和一個公眾號粉絲交流面試情況如下
面試的時候,把源碼一波分析,令面試官虎軀一震!在一陣前戲過后,以為接下來無非就是身體的一頓抽搐一切變得索然無味,不料面試官來了句令劇情發(fā)生了反轉(zhuǎn)
"你對Dubbo源碼這么熟悉,那請問你使用的時候,有沒有遇到什么坑"
我擦,毫無準備的他,菊花頓時一緊!此時就面臨唬住了50K,唬不住就只能5K的局面,慌了!
論如何反殺
相信大家面試都遇到過類似問題,因為源碼解析網(wǎng)上很多,很多人"考前突擊"一下,但是遇到喜歡問細節(jié)的面試官,終究難逃法眼,無處遁形.遇到這個問題,我們?nèi)绾畏礆⒁徊?那么我就從一次聊天記錄說起,畢竟只有關(guān)注肥朝公眾號,擁有真實場景的源碼實戰(zhàn)(非常重要),遇到這類問題,才不至于出現(xiàn)猛虎落淚的情形
真實場景描述
那么我們把業(yè)務(wù)相關(guān)去掉,抽取一個最簡模型.我們在公司,一般都會有自己的自定義異常,然后這個自定義異常一般放在common.jar給其他模塊依賴,比如我這里定義一個HelloException
1public class HelloException extends RuntimeException {23 public HelloException() {4 }56 public HelloException(String message) {7 super(message);8 }910}
然后我們寫一個最簡單的Dubbo的demo,如下
interface
1public interface DemoService {23 String sayHello(String name);45}
provider
1public class DemoServiceImpl implements DemoService {23 public String sayHello(String name) {4 throw new HelloException("公眾號:肥朝");5 }67}
consumer
1public class DemoAction {23 private DemoService demoService;45 public void setDemoService(DemoService demoService) {6 this.demoService = demoService;7 }89 public void start() throws Exception {10 try {11 String hello = demoService.sayHello("公眾號:肥朝");12 } catch (HelloException helloException) {13 System.out.println("這里捕獲helloException異常");14 }15 }1617}
按照聊天記錄的描述,此時consumer調(diào)用provider,provider拋出HelloException.但是consumer捕獲到的,卻不是HelloException.
那么我們運行看看
果然如該同事所言.為什么會這樣呢?之前沒看過肥朝Dubbo源碼解析系列的同學這種時候往往采用最低效的解決辦法,把異常棧往微信群一丟,各種求助.但是往往毫無收獲,然后感嘆社會為何如此冷漠!
但是相信公眾號的老粉絲們早已掌握閱讀源碼的技能,和肥朝一樣坐懷不亂,九淺一深直入源碼.出現(xiàn)異常我們首先看一下異常棧
除非擼多了看不清(建議戒擼),否則這行異常和肥朝一樣,就像漆黑中的螢火蟲一樣,那么鮮明,那么出眾
1com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:108)
那么我們一探究竟
1 public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {2 try {3 Result result = invoker.invoke(invocation);4 if (result.hasException() && GenericService.class != invoker.getInterface()) {5 try {6 Throwable exception = result.getException();78 // 如果是checked異常,直接拋出9 if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {10 return result;11 }12 // 在方法簽名上有聲明,直接拋出13 try {14 Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());15 Class>[] exceptionClassses = method.getExceptionTypes(); 16 for (Class> exceptionClass : exceptionClassses) {17 if (exception.getClass().equals(exceptionClass)) {18 return result;19 }20 }21 } catch (NoSuchMethodException e) {22 return result;23 }2425 // 未在方法簽名上定義的異常,在1.如果是checked異常,直接拋出.很明顯,我們的HelloException是RuntimeException,不符合2.在方法簽名上有聲明,直接拋出.很明顯,我們接口并未聲明該異常,不符合3.異常類和接口類在同一jar包里,直接拋出.很明顯,我們的異常類是在common.jar的,接口是在api.jar的,不符合4.是JDK自帶的異常,直接拋出.很明顯,這個HelloException是我們自定義的,不符合5.是Dubbo本身的異常(RpcException),直接拋出.很明顯,這個HelloException是我們自定義的,和RpcException幾乎沒有半毛錢關(guān)系.6.否則,包裝成RuntimeException拋給客戶端.因為以上5點均不滿足,所以該異常會被包裝成RuntimeException異常拋出(重要)這也就是為什么我們catchHelloException是catch不到的,因為他包裝成RuntimeException了
Dubbo為什么這么設(shè)計
也許你看到這里會覺得這個判斷好坑.Dubbo為什么要這么設(shè)計?我們看源碼,最重要的是知道作者為什么這么設(shè)計,只有知道為什么這么設(shè)計才是經(jīng)過了深度的思考,否則看時高潮,看后就忘.講清楚為什么這么設(shè)計,也是大家關(guān)注肥朝公眾號的一個重要原因.
其實Dubbo的這個考慮,是基于序列化來考慮的.你想想,如果provider拋出一個僅在provider自定義的一個異常,那么該異常到達consumer,明顯是無法序列化的.所以你注意看Dubbo的判斷.我們來看下他的判斷
1.如果是checked異常,直接拋出.很明顯,我們的HelloException是RuntimeException,不符合2.在方法簽名上有聲明,直接拋出.很明顯,我們接口并未聲明該異常,不符合3.異常類和接口類在同一jar包里,直接拋出.很明顯,我們的異常類是在common.jar的,接口是在api.jar的,不符合4.是JDK自帶的異常,直接拋出.很明顯,這個HelloException是我們自定義的,不符合5.是Dubbo本身的異常(RpcException),直接拋出.很明顯,這個HelloException是我們自定義的,和RpcException幾乎沒有半毛錢關(guān)系.6.否則,包裝成RuntimeException拋給客戶端.因為以上5點均不滿足,所以該異常會被包裝成RuntimeException異常拋出(重要)如何解決
既然都知道了原理了,那么很好解決,我隨便列舉一下,比如從規(guī)范上要求業(yè)務(wù)方接口聲明HelloException
寫在最后
當然肥朝面試的時候,也曾經(jīng)被問過類似問題,你用XXX有沒有遇到過什么坑.在一波操作猛如虎的分析下,面試官說
"你真帥".
肥朝會心一笑
結(jié)果他卻說
"你笑起來更帥"!
免費Java資料領(lǐng)取,涵蓋了Java、redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并發(fā)分布式、大數(shù)據(jù)、機器學習等技術(shù)。 傳送門: https://jq.qq.com/?_wv=1027&k=5F79bMq
網(wǎng)頁題目:面試官問我,使用Dubbo有沒有遇到一些坑?我笑了。
轉(zhuǎn)載來源:http://m.jiaotiyi.com/article/giejoe.html