同一個應用連接兩個Zookeeper集群的方法


背景

  1. 因為應用服務用到了Dubbo,Dubbo 依賴了 Zookeeper作為注冊中心。
  2. 應用服務同時還需要連接到KAFKA,且Kafka開啟了SASL認證。

問題

對於一個開源中間件來說,集群安全是很重要的,但是在實現上,認證方式就那么幾種:

  1. GSSAPI (唯一實現:Kerberos,Java可以使用JAAS對其進行支持)
  2. SASL (Java可以使用JAAS對其進行支持)
  3. PLAIN_TEXT (沒認證)
  4. SSL
    那么如果全局指定了JAAS,訪問兩個SASL配置賬戶不同的集群,就會必然有一個失敗。

分析

對於Zookeeper,它使用了JAAS,它僅僅簡單粗暴的通過讀取zookeeper.sasl.clientjava.security.auth.login.config這兩個全局環境變量來判斷要不要使用SASL認證,無法通過其他方式來改變這種行為。

對於Kafka,它巧妙地實現了javax.security.auth.login.Configuration,也就是org.apache.kafka.common.security.JaasConfig。可以通過代碼中直接指定 sasl.jaas.config(slankka:0715.2020) 來表示此Topic的連接認證方式,十分靈活。

此外,Apache Flume 也收益於此,Flume如果同時連接加密和不加密的 多套Kafka集群,可以按照單個Kafka Source/Sink 進行Topic級別細粒度的配置認證方式,而不是通過JVM參數直接全局固定。

那么解決方案就有好幾種:

  1. 修改使用Zookeeper的客戶端連接器。
  2. 修改Zookeeper源碼。
  3. 運行時指定Jaas,啟動時不指定。
  4. 通過創建單獨的進程指定JAAS參數
  5. 通過Java調用Linux命令,訪問Kafka/Zookeeper配置好的客戶端來執行某些操作。

額外技術細節

Zookeeper 本身的連接是極為困難的,現在開源社區總共有兩種Zookeeper Java Client(暫且稱為Zookeeper連接器):

  1. zkclient(zk101tec)
  2. Curator

具體區別不在這里詳述。

對於 Dubbo 2.7.1 以后的版本,我通過檢查源碼,發現 Dubbo已經去除 zkclient(zk101tec)依賴,已經完全切換到 Apache Curator。
如果修改 Zookeeper連接器,那就要確定項目中,引入的框架使用的是哪一種連接器。

解決方案

解決辦法正如前文指出,有三種,最便宜實用的方法就是方案三: 在運行時指定jaas配置。運行完畢再恢復上次的配置。在切換期間可能會存在幾毫秒的其他Zookeeper集群訪問的問題,但是這已經是極小的影響了。

另外,Zookeeper社區,有人指出這種設計的不足:

ZOOKEEPER-2139:Support multiple ZooKeeper client, with different configurations, in a single JVM

通過查看提交記錄發現,社區已經針對Zookeeper的構造函數提供了 ZkClientConfig這個參數類,可以實現自定義的配置。
Github 2139 Commit

可以看出,這些版本以后才能支持:release-3.6.1 release-3.6.1-1 release-3.6.1-0 release-3.6.0 release-3.6.0-4 release-3.6.0-3 release-3.6.0-2 release-3.6.0-1 release-3.6.0-0

當Zookeeper支持了以后,就可以用方案1,或者類似於Kafka的方式來更好的解決。

總結

Kafka的這種設計值得我們學習,減少具體配置對環境變量的依賴。
涉及到的技術有:JAAS,Kafka, Zookeeper


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM