dubbo如何设置连接zookeeper权限

 更新时间:2024年05月28日 15:37:58   作者:一屁小肥咩  
这篇文章主要介绍了dubbo如何设置连接zookeeper权限问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

最近自己的技术栈项目,再升级dubbo为2.7.5,zookeeper为3.5.6,curator-recipes升级为4.2.0的时候一直出现zookeeper not connected和Connection lost for ***的错误。

之前未升级前还是好的...随手查看报错源码信息并百度,终于再stackflow上面找到原因。

设置环境参数ZKClientConfig.ENABLE_CLIENT_SASL_KEY=false,默认未true

System.setProperty(ZKClientConfig.ENABLE_CLIENT_SASL_KEY,Constant.IS_FALSE.toString());

大概意思是zookeeper作为外部应用需要向系统申请资源,申请资源的时候需要通过认证,而sasl是一种认证方式,添加以上那一句来绕过sasl认证。避免等待,来提高效率。

随后继续深进,了解到zookeeper的sasl认证相关(试了下,效果不大好,可能我姿势不大对? 这里就不介绍zk的sasl介绍和相关配置了,有兴趣的可以自行百度),并附加的深入学习了zk的ACL 权限,以及dubbo以zk未注册中心的,权限认证!下面开始相关介绍。

zookeeper设置ACL权限

查阅dubbo的官方文档dubbo-registry发现连接注册中心的时候是可以选择是否需要用户名密码,接下来就是要如何设置zookeeper的用户名跟密码

进入zookeeper的bin文件夹运行客户端

./zkCli.sh

help 查看指令

[zk: localhost:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
    stat path [watch]
    set path data [version]
    ls path [watch]
    delquota [-n|-b] path
    ls2 path [watch]
    setAcl path acl
    setquota -n|-b val path
    history 
    redo cmdno
    printwatches on|off
    delete path [version]
    sync path
    listquota path
    rmr path
    get path [watch]
    create [-s] [-e] path data acl
    addauth scheme auth
    quit 
    getAcl path
    close 
    connect host:port

如果在dubbo中没有指定分组的话,dubbo会默认生成一个分组dubbo,也就是在zookeeper下面会有个子节点dubbo

也可以自己手动创建

create /dubbo

Zookeeper的ACL通过scheme:username:password:permissions来构成权限

scheme这边主要用到2种方式,另外还有设置ip和host,这几个没用到的这边就先不细说

1.auth方式(密码明文)

添加用户名和密码

addauth digest admin:13871500871

授予/dubbo auth权限

setAcl /dubbo auth:admin:13871500871:rwadc

配置dubbo连接zookeeper配置文件

<dubbo:registry protocol ="zookeeper" address="127.0.0.1:2181"  username="admin" password="13871500871" client="curator" />

2.digest授权方式(方式跟auth差不多)

授予/dubbo digest权限

addauth digest admin:jI+oJfxCaWyh/3Zw/r+fwhbZVRY=
setAcl /dubbo digest:admin:jI+oJfxCaWyh/3Zw/r+fwhbZVRY=:cdrwa

配置zookeeper配置文件

<dubbo:registry protocol ="zookeeper" address="127.0.0.1:2181"  username="admin" password="13871500871" client="curator" />

digest 密码生成方式:把密码进行sha1编码然后对结果进行base64编码

BASE64(SHA1(password))

查看zookeeper源码发现,其实包里面已经有现成的方法,直接调用这个类生成就行,

idPassword字符串格式:username:password

org.apache.zookeeper.server.auth.DigestAuthenticationProvider
static public String generateDigest(String idPassword) throws NoSuchAlgorithmException {
        String parts[] = idPassword.split(":", 2);
        byte digest[] = MessageDigest.getInstance("SHA1").digest(
                idPassword.getBytes());
        return parts[0] + ":" + base64Encode(digest);
}

还有一个点就是要设置client="curator"

通过ZookeeperRegistry发现zookeeper的连接是通过zookeeperTransporter进行创建,

zookeeperTransporter接口分别由CuratorZookeeperTransporterZkclientZookeeperTransporter实现,这2个分别创建

CuratorZookeeperClient和ZkclientZookeeperClient

public class ZkclientZookeeperTransporter implements ZookeeperTransporter {
    public ZookeeperClient connect(URL url) {
        return new ZkclientZookeeperClient(url);
    }
}
public class CuratorZookeeperTransporter implements ZookeeperTransporter {
    public ZookeeperClient connect(URL url) {
        return new CuratorZookeeperClient(url);
    }
}

查看源码发现ZkclientZookeeperClient是没有进行设置zookeeper的auth的账号和密码,

CuratorZookeeperClient有去获取配置的相关用户信息。

    public ZkclientZookeeperClient(URL url) {
        super(url);
        client = new ZkClient(url.getBackupAddress());
        client.subscribeStateChanges(new IZkStateListener() {
            public void handleStateChanged(KeeperState state) throws Exception {
                ZkclientZookeeperClient.this.state = state;
                if (state == KeeperState.Disconnected) {
                    stateChanged(StateListener.DISCONNECTED);
                } else if (state == KeeperState.SyncConnected) {
                    stateChanged(StateListener.CONNECTED);
                }
            }
            public void handleNewSession() throws Exception {
                stateChanged(StateListener.RECONNECTED);
            }
        });
    }
    public CuratorZookeeperClient(URL url) {
        super(url);
        try {
            Builder builder = CuratorFrameworkFactory.builder()
                    .connectString(url.getBackupAddress())
                    .retryPolicy(new RetryNTimes(Integer.MAX_VALUE, 1000))  
                    .connectionTimeoutMs(5000);
            String authority = url.getAuthority();
            if (authority != null && authority.length() > 0) {
                builder = builder.authorization("digest", authority.getBytes());
            }
            client = builder.build();
            client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
                public void stateChanged(CuratorFramework client, ConnectionState state) {
                    if (state == ConnectionState.LOST) {
                        CuratorZookeeperClient.this.stateChanged(StateListener.DISCONNECTED);
                    } else if (state == ConnectionState.CONNECTED) {
                        CuratorZookeeperClient.this.stateChanged(StateListener.CONNECTED);
                    } else if (state == ConnectionState.RECONNECTED) {
                        CuratorZookeeperClient.this.stateChanged(StateListener.RECONNECTED);
                    }
                }
            });
            client.start();
        } catch (IOException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

cdrwa表示zookeeper的五种权限

  • CREATE: 创建子节点
  • READ: 获取节点数据或者当前节点的子节点列表
  • WRITE: 节点设置数据
  • DELETE: 删除子节点
  • ADMIN: 节点设置权限

如果用户名密码错误,或者没设置,会报KeeperErrorCode = NoAuth错误

注:停止zookeeper,清除zookeeper文件夹下面的logs,或者用delete 删除节点 就可以清除权限

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java中toString()、String.valueOf()、(String) 强转的区别

    java中toString()、String.valueOf()、(String) 强转的区别

    在实际开发中,少不了使用这三种方法对某一个类型的数据进行转 String 的操作,本文就来介绍了java中toString()、String.valueOf()、(String) 强转的区别,感兴趣的可以了解一下
    2024-06-06
  • Jackson自定义序列化与反序列化注解详解

    Jackson自定义序列化与反序列化注解详解

    这篇文章主要介绍了Jackson自定义序列化与反序列化注解详解,某些场景下,我们使用Jackson对数据进行序列化或反序列化的时候,需要对某些数据进行特殊处理,需要的朋友可以参考下
    2023-11-11
  • struts1登录示例代码_动力节点Java学院整理

    struts1登录示例代码_动力节点Java学院整理

    这篇文章主要介绍了struts1登录示例代码,需要的朋友可以参考下
    2017-08-08
  • Java线程的6种状态及切换教程

    Java线程的6种状态及切换教程

    这篇文章主要给大家介绍了关于Java线程的6种状态及切换教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • 启用Spring事务管理@EnableTransactionManagement示例解析

    启用Spring事务管理@EnableTransactionManagement示例解析

    这篇文章主要为大家介绍了启用Spring事务管理@EnableTransactionManagement示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 浅谈Maven安装及环境配置出错的解决办法

    浅谈Maven安装及环境配置出错的解决办法

    这篇文章主要介绍了浅谈Maven安装及环境配置出错的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • idea中如何去掉不想commit的文件

    idea中如何去掉不想commit的文件

    这篇文章主要介绍了idea中如何去掉不想commit的文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 解析SpringSecurity自定义登录验证成功与失败的结果处理问题

    解析SpringSecurity自定义登录验证成功与失败的结果处理问题

    这篇文章主要介绍了SpringSecurity系列之自定义登录验证成功与失败的结果处理问题,本文通过实例给大家讲解的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-11-11
  • 浅析JPA分类表的操作函数

    浅析JPA分类表的操作函数

    这篇文章主要介绍了JPA分类表的操作函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-02-02
  • Java日常练习题,每天进步一点点(27)

    Java日常练习题,每天进步一点点(27)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07

最新评论