1. 程式人生 > >dubbo&&zookeeper面試題

dubbo&&zookeeper面試題

  1. 什麼是dubbo
    Dubbo是阿里巴巴SOA服務化治理方案的核心框架,是一個分散式服務框架,致力於提供高效能和透明化的RPC遠端服務呼叫方案,以及SOA服務治理方案。
  2. 測試和生產公用一套zookeeper,怎麼保證消費不衝突
  • dubbo白名單(Filter過濾器)
  • 服務分組
<!--服務-->
<dubbo:service group="feedback" interface="com.xxx.IndexService" />
<dubbo:service group="member" interface="com.xxx.IndexService"
/>
<!--引用--> <dubbo:reference id="feedbackIndexService" group="feedback" interface="com.xxx.IndexService" /> <dubbo:reference id="memberIndexService" group="member" interface="com.xxx.IndexService" />
  • 多版本
<dubbo:service interface="com.foo.BarService" version="1.0.0" />

第一種方案:
實現com.alibaba.dubbo.rpc.Filter介面:

public class AuthorityFilter implements Filter {  
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityFilter.class);  

    private IpWhiteList ipWhiteList;  

    //dubbo通過setter方式自動注入  
    public void setIpWhiteList(IpWhiteList ipWhiteList) {  
        this.ipWhiteList = ipWhiteList;  
    }  

    @Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { if (!ipWhiteList.isEnabled()) { LOGGER.debug("白名單禁用"); return invoker.invoke(invocation); } String clientIp = RpcContext.getContext().getRemoteHost(); LOGGER.debug("訪問ip為{}", clientIp); List<String> allowedIps = ipWhiteList.getAllowedIps(); if (allowedIps.contains(clientIp)) { return invoker.invoke(invocation); } else { return new RpcResult(); } } }

注意:只能通過setter方式來注入其他的bean,且不要標註註解!dubbo自己會對這些bean進行注入,不需要再標註@Resource讓Spring注入

在resources目錄下新增純文字檔案META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,內容如下: xxxFilter=com.xxx.AuthorityFilter
修改dubbo的provider配置檔案,在dubbo:provider中新增配置的filter, 內容如下:

    <dubbo:provider filter="xxxFilter" />  

這樣就可以實現dubbo介面的IP白名單功能了。
出自https://www.cnblogs.com/wangzhongqiu/archive/2017/09/22/7575759.html
3. zookeeper是如何保證事務的順序一致性的
zookeeper採用了遞增的事務Id來標識,所有的proposal都在被提出的時候加上了zxid,zxid實際上是一個64位的數字,高32位是epoch用來標識leader是否發生改變,如果有新的leader產生出來,epoch會自增,低32位用來遞增計數。當新產生proposal的時候,會依據資料庫的兩階段過程,首先會向其他的server發出事務執行請求,如果超過半數的機器都能執行並且能夠成功,那麼就會開始執行
4. zookeeper的leader選舉
要進行leader選舉,zookeeper叢集至少需要兩臺機器。
(myid(伺服器id),ZXID(事務id))表示推舉的伺服器。

  • 啟動時期的leader選舉

每個server發出一個投票給叢集中的其他機器;

伺服器接受來自其他各個伺服器的投票,並判斷投票的有效性(包括檢查是否是本輪投票、是否來自LOOKING狀態的伺服器);

處理投票(伺服器將自己的投票和收到的投票進行對比,先檢查ZXID,大的伺服器作為leader;如果ZXID相同,檢查myid,myid大的作為leader;更新投票),將最終的投票重新發出去;

統計投票:每次投票後,伺服器統計所有投票,判斷是否有過半的伺服器收到相同的投票資訊;如果是,則選舉出了新的leader,如果不是,重新開始投票;

改變伺服器狀態:follower將自己的狀態改為FOLLOWING,leader將自己的狀態改為LEADING。

  • 執行期間的leader選舉

變更狀態:leader掛了以後,餘下的非Observer伺服器將自己的狀態改為LOOKING,然後進入leader選舉流程;
發出投票:每個server發出一個投票;
接收投票
處理投票:和啟動時期的leader選舉一樣。
統計投票
改變伺服器狀態
5. leader選舉過程
當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的Server都恢復到一個正確的狀態。Zk的選舉演算法使用ZAB協議:

  1. 選舉執行緒由當前Server發起選舉的執行緒擔任,其主要功能是對投票結果進行統計,並選出推薦的Server;
  2. 選舉執行緒首先向所有Server發起一次詢問(包括自己);
  3. 選舉執行緒收到回覆後,驗證是否是自己發起的詢問(驗證zxid是否一致),然後獲取對方的id(myid),並存儲到當前詢問物件列表中,最後獲取對方提議的leader相關資訊(id,zxid),並將這些資訊儲存到當次選舉的投票記錄表中;
  4. 收到所有Server回覆以後,就計算出zxid最大的那個Server,並將這個Server相關資訊設定成下一次要投票的Server;
  5. 執行緒將當前zxid最大的Server設定為當前Server要推薦的Leader,如果此時獲勝的Server獲得n/2 + 1的Server票數, 設定當前推薦的leader為獲勝的Server,將根據獲勝的Server相關資訊設定自己的狀態,否則,繼續這個過程,直到leader被選舉出來。

通過流程分析我們可以得出:要使Leader獲得多數Server的支援,則Server總數最好是奇數2n+1,且存活的Server的數目不得少於n+1
6. 客戶端對serverList的輪詢機制
隨機,客戶端在初始化( new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) )的過程中,將所有Server儲存在一個List中,然後隨機打散,形成一個環。之後從0號位開始一個一個使用。
兩個注意點:

  • Server地址能夠重複配置,這樣能夠彌補客戶端無法設定Server權重的缺陷,但是也會加大風險。(比如: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181).

  • 如果客戶端在進行Server切換過程中耗時過長,那麼將會收到SESSION_EXPIRED. 這也是上面第1點中的加大風險之處。

7.ZK為什麼不提供一個永久性的Watcher註冊機制
不支援用持久Watcher的原因很簡單,ZK無法保證效能。
使用watch需要注意的幾點

  • Watches通知是一次性的,必須重複註冊.
  • 發生CONNECTIONLOSS之後,只要在session_timeout之內再次連線上(即不發生SESSIONEXPIRED),那麼這個連線註冊的watches依然在。
  • 節點資料的版本變化會觸發NodeDataChanged,注意,這裡特意說明了是版本變化。存在這樣的情況,只要成功執行了setData()方法,無論內容是否和之前一致,都會觸發NodeDataChanged。
  • 對某個節點註冊了watch,但是節點被刪除了,那麼註冊在這個節點上的watches都會被移除。
    同一個zk客戶端對某一個節點註冊相同的watch,只會收到一次通知。
  • Watcher物件只會儲存在客戶端,不會傳遞到服務端。

8.建立的臨時節點什麼時候會被刪除,是連線一斷就刪除嗎?延時是多少?
連線斷了之後,ZK不會馬上移除臨時資料,只有當SESSIONEXPIRED之後,才會把這個會話建立的臨時資料移除。因此,使用者需要謹慎設定Session_TimeOut
9. 是否可以拒絕單個IP對ZK的訪問,操作
ZK本身不提供這樣的功能,它僅僅提供了對單個IP的連線數的限制。你可以通過修改iptables來實現對單個ip的限制;當然,你也可以通過這樣的方式來解決。https://issues.apache.org/jira/browse/ZOOKEEPER-1320
10. ZooKeeper叢集中伺服器之間是怎樣通訊的?
Leader伺服器會和每一個Follower/Observer伺服器都建立TCP連線,同時為每個F/O都建立一個叫做LearnerHandler的實體。LearnerHandler主要負責Leader和F/O之間的網路通訊,包括資料同步,請求轉發和Proposal提議的投票等。Leader伺服器儲存了所有F/OLearnerHandler
11. 出現呼叫超時com.alibaba.dubbo.remoting.TimeoutException異常怎麼辦?
通常是業務處理太慢,可在服務提供方執行:jstack PID > jstack.log 分析執行緒都卡在哪個方法呼叫上,這裡就是慢的原因。如果不能調優效能,請將timeout設大。
12. 出現java.util.concurrent.RejectedExecutionException或者Thread pool exhausted怎麼辦?
RejectedExecutionException表示執行緒池已經達到最大值,並且沒有空閒連,拒絕執行了一些任務。
Thread pool exhausted通常是min和max不一樣大時,表示當前已建立的連線用完,進行了一次擴充,建立了新執行緒,但不影響執行。
原因可能是連線池不夠用,請調整dubbo.properites中的:

// 設成一樣大,減少執行緒池收縮開銷  
dubbo.service.min.thread.pool.size=200  
dubbo.service.max.thread.pool.size=200