当前位置:首页 > 技术 > 正文内容

消除 Curator 连接 ZooKeeper 时的 SASL 认证告警

访客 技术 2026年6月12日 1

在使用 Curator 作为 ZooKeeper 客户端进行分布式配置管理时,控制台会持续输出 "Will not attempt to authenticate using SASL (unknown error)" 的警告信息。该问题在 ZooKeeper 3.5.5 与 Curator 4.2.0 的组合环境下尤为常见,严重影响日志可读性。

问题根因

ZooKeeper 客户端在建立连接时会检查 SASL 认证开关。相关逻辑位于 org.apache.zookeeper.ClientCnxnstartConnect 方法中:

private void startConnect(InetSocketAddress addr) throws IOException {
    saslLoginFailed = false;
    if (!isFirstConnect) {
        try {
            Thread.sleep(r.nextInt(1000));
        } catch (InterruptedException e) {
            LOG.warn("Unexpected exception", e);
        }
    }
    state = States.CONNECTING;
    
    String hostPort = addr.getHostString() + ":" + addr.getPort();
    MDC.put("myid", hostPort);
    setName(getName().replaceAll("\\(.*\\)", "(" + hostPort + ")"));
    
    if (clientConfig.isSaslClientEnabled()) {
        try {
            if (zooKeeperSaslClient != null) {
                zooKeeperSaslClient.shutdown();
            }
            zooKeeperSaslClient = new ZooKeeperSaslClient(
                SaslServerPrincipal.getServerPrincipal(addr, clientConfig),
                clientConfig);
        } catch (LoginException e) {
            LOG.warn("SASL configuration failed: " + e 
                + " Will continue connection to Zookeeper server without "
                + "SASL authentication, if Zookeeper server allows it.");
            eventThread.queueEvent(new WatchedEvent(
                Watcher.Event.EventType.None,
                Watcher.Event.KeeperState.AuthFailed, null));
            saslLoginFailed = true;
        }
    }
    
    logStartConnect(addr);
    clientCnxnSocket.connect(addr);
}

其中 clientConfig.isSaslClientEnabled() 的默认返回值为 true,由以下配置决定:

public boolean isSaslClientEnabled() {
    return Boolean.valueOf(getProperty(ENABLE_CLIENT_SASL_KEY, ENABLE_CLIENT_SASL_DEFAULT));
}

而 Curator 的默认工厂类 DefaultZookeeperFactory 在构建 ZooKeeper 实例时,并未覆盖此配置:

package org.apache.curator.utils;

public class DefaultZookeeperFactory implements ZookeeperFactory {
    @Override
    public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, 
            Watcher watcher, boolean canBeReadOnly) throws Exception {
        return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly);
    }
}

解决思路

核心在于将 ENABLE_CLIENT_SASL_KEY 设为 false。可通过自定义 ZookeeperFactory 实现,在创建客户端实例时注入关闭 SASL 的配置。

具体实现

自定义工厂类,显式构造带配置的 ZooKeeper 实例:

import org.apache.curator.utils.ZookeeperFactory;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.client.ZKClientConfig;

public class NoSaslZookeeperFactory implements ZookeeperFactory {
    
    @Override
    public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, 
            Watcher watcher, boolean canBeReadOnly) throws Exception {
        
        ZKClientConfig cfg = new ZKClientConfig();
        cfg.setProperty(ZKClientConfig.ENABLE_CLIENT_SASL_KEY, "false");
        
        return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly, cfg);
    }
}

构建 CuratorFramework 时应用该工厂:

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;

public class ZkClientBuilder {
    
    public CuratorFramework build(String connectionString) {
        return CuratorFrameworkFactory.builder()
                .connectString(connectionString)
                .zookeeperFactory(new NoSaslZookeeperFactory())
                .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                .build();
    }
}

注意事项

  • 此方案仅适用于未启用 SASL 认证的场景。若生产环境依赖 Kerberos 等 SASL 机制,需排查认证配置而非简单关闭。
  • 也可考虑在 ZooKeeper 服务端调整配置,但涉及集群变更,需评估影响范围。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。