如何正确创建带Kerberos委托的CloudSolrClient?相关技术疑问求解
嘿,你的整体思路方向是对的——先通过具备Kerberos认证权限的Solr客户端获取委托令牌,再用这个令牌构建用于实际查询的CloudSolrClient。不过几个细节问题咱们逐个理清楚:
问题1:未初始化的client调用getParser()的写法问题
这个写法肯定有问题,会直接抛出NullPointerException——你要创建的CloudSolrClient client还没完成实例化,此时client是null,根本没法调用getParser()方法。
修正方案:
你有几个选择:
- 使用Solr默认的
ResponseParser,比如XMLResponseParser或者JSONResponseParser,直接实例化传入:
CloudSolrClient client = new CloudSolrClient.Builder() .withZkHost("localhost:2181") // 注意:ZooKeeper地址一般不用http前缀,直接写host:port即可 .withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder() .withResponseParser(new XMLResponseParser()) .withHttpSolrClientBuilder( new HttpSolrClient.Builder() .withKerberosDelegationToken(token) )) .build();
- 如果确实需要复用某个已初始化客户端的解析器,得提前创建一个基础的
HttpSolrClient(比如用来获取令牌的那个solrClient),用它的解析器:
// 复用获取令牌的solrClient的解析器 CloudSolrClient client = new CloudSolrClient.Builder() .withZkHost("localhost:2181") .withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder() .withResponseParser(solrClient.getParser()) .withHttpSolrClientBuilder( new HttpSolrClient.Builder() .withKerberosDelegationToken(token) )) .build();
另外注意:ZooKeeper的地址通常不需要http://前缀,直接写localhost:2181即可,Solr的CloudSolrClient是直接连接ZK的,不是HTTP协议。
问题2:多用户场景的客户端复用问题
完全不需要为每个用户创建两个CloudSolrClient,核心复用逻辑如下:
- 获取令牌的SolrClient(比如你的
HttpSolrClient solrClient)可以全局复用:只要这个客户端本身配置了合法的Kerberos认证信息(比如绑定了有权限申请委托令牌的服务账号keytab),它就可以为任意多个用户请求委托令牌,不需要每个用户都新建一个。 - 带令牌的CloudSolrClient:如果每个用户的令牌不同,你可以考虑用对象池来管理这些客户端实例(避免频繁创建销毁的开销),或者如果你的Solr版本支持,也可以在每次请求时动态设置委托令牌(不过Solr 6.6.0的CloudSolrClient可能需要每个实例绑定一个令牌)。但无论如何,绝对不需要每个用户都重复创建“获取令牌+查询”两套客户端。
问题3:Kerberos委托令牌中renewer的作用机制
我来把这个点拆解清楚:
- renewer的核心作用:它是一个Kerberos主体(Principal),代表被授权可以对这个委托令牌执行**续期(Renew)和撤销(Cancel)**操作的身份。换句话说,只有以这个renewer身份认证的客户端,才能调用Solr的续期令牌API。
- 续期不是自动的:传入renewer字符串只是指定了谁有资格续期,并不会自动触发续期。你需要让renewer对应的客户端主动调用
DelegationTokenRequest.Renew方法来延长令牌的有效期。 - renewer的取值:它必须是一个合法的Kerberos主体名称,比如你的应用服务的Kerberos身份
myapp-service@YOUR-DOMAIN.COM,或者如果是让Solr服务自身来续期,就设置为Solr服务的Kerberos主体(比如solr@YOUR-DOMAIN.COM)。绝对不是"zookeeper",除非你的ZooKeeper服务的Kerberos主体就是这个,并且你打算让ZooKeeper来负责令牌续期——这通常不是常规场景。
举个例子:如果你的后端服务用backend-service@EXAMPLE.COM这个Kerberos身份运行,你希望这个服务能帮用户续期令牌,那renewer就设为这个值。
内容的提问来源于stack exchange,提问作者darkCode
相关产品推荐
相关产品推荐

