关于同一个JVM连接多个加密方式不同的Zookeeper的讨论
场景
本文适用于 Zookeeper 集群版本 3.4.x全部。
有如下场景:
- 连接了需要保持ZK连接的服务(未启SASL,或者开启),例如Dubbo,同时还要连接到另一套集群,但是只有瞬时连接。
- 连接了需要保持ZK连接的服务(开启SASL),例如Yarn,但是同时还要连接到另一套需要保持连接的集群,例如Dubbo。
场景1
是有解决方法的,在启动服务的时候会连接上Dubbo,但是连接另一个集群的时候,原来的认证方式是行不通的,这个时候只能用zookeeper.sasl.client修改为事先准备好的另一个ClientContextName,用完再恢复这个环境变量。
场景2
无法解决,只能放弃连接第二套集群,改用RESTFUL等方式转发服务。
原理
Zookeeper 3.5.2以后增加了ZKClientConfig类,将配置存于父类ZkConfig的Map<String,String>中。
以下是判断SASL方式的逻辑
可以看到Zookeeper 3.4.x 的设计,无法支持多种加密方式的Zk集群。因为环境变量无法动态修改,并且遇到需要保持连接的地方,不可能每次都改。
结论
Zookeeper 3.4.x的用户,如果应用中既有 SASL加密,也有非加密的ZK集群,无法同时支持两个需要保持的连接。
最方便可行的方案就是利用REST等非加密方式的服务进行转发,或者直接查询数据库。
但如果有一个是瞬时连接,则可以在执行前后分别设置一些环境变量,以及复原他们的值。
展望
如果使用3.5.5以上的Zookeeper,则可以通过设置ZKClientConfig实现不同客户端使用不同加密方式,例如zookeeper.sasl.clientconfig(LOGIN_CONTEXT_NAME_KEY)等等这些值。
但是相应的中间件如果用Curator Framework来连接Zk,也需要中间件自身提供对ZkClientConfig的支持,否则仍然需要修改源码,仅仅有这种可能性,但是不推荐。