ZooKeeper 权限管理
这其中一个显而易见的问题就是权限:如果我的数据被别人动了怎么办?
方案一:采用ZooKeeper支持的ACL digest方式,用户自己定义节点的权限
这种方案将zookeeper的acl和digest授权认证模式相结合。具体操作流程如下:
可以把这个访问授权过程看作是用户注册,系统给你一个密码,每次操作使用这个用户名(appName)和密码. 于是就可以对应有这样权限管理系统,专门是负责进行节点的创建申请:包含“申请私有节点”和“申请公有节点”。这样一来,节点的创建都是由这个权限管理系统来负责了,每次申请完后,系统都会返回给你的一个key,格式通常是“{appName}:{password}”,以后你的任何操作都要在zk session 中携带上这个key,这样就能进行权限控制。当然,用户自己通过zk客户端进行path的创建也是可以的,只是要求他们要使用授权方式来进行zk节点的创建。(注意,如果使用zkclient,请使用
https://github.com/nileader/zkclient )
整个权限控制流程的代码测试,如下图所示,点击查看大图:(测试代码在这里)
- package org.I0Itec.zkclient;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.zookeeper.WatchedEvent;
- import org.apache.zookeeper.Watcher;
- import org.apache.zookeeper.ZooDefs.Ids;
- import org.apache.zookeeper.data.ACL;
- /**
- * Description: ZooKeepre ACL权限控制 测试
- * @author nileader / nileader@gmail.com
- * @Date Feb 2, 2012
- */
- public class DemoAuth implements Watcher {
- final static String SERVER_LIST = “127.0.0.1:4711″;
- final static String PATH = “/yinshi_auth_test”;
- final static String PATH_DEL = “/yinshi_auth_test/will_be_del”;
- final static String authentication_type = “digest”;
- final static String correctAuthentication = “taokeeper:true”;
- final static String badAuthentication = “taokeeper:errorCode”;
- static ZkClient zkClient = null;
- public static void main( String[] args ) throws Exception {
- List< ACL > acls = new ArrayList< ACL >( 1 );
- for ( ACL ids_acl : Ids.CREATOR_ALL_ACL ) {
- acls.add( ids_acl );
- }
- try {
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() );
- } catch ( Exception e ) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- try {
- zkClient.createPersistent( PATH, acls, “init content” );
- System.out.println( “使用授权key:” + correctAuthentication + “创建节点:” + PATH + “, 初始内容是: init content” );
- } catch ( Exception e ) {
- e.printStackTrace();
- }
- try {
- zkClient.createPersistent( PATH_DEL, acls, “待删节点” );
- System.out.println( “使用授权key:” + correctAuthentication + “创建节点:” + PATH_DEL + “, 初始内容是: init content” );
- } catch ( Exception e ) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- // 获取数据
- getDataByNoAuthentication();
- getDataByBadAuthentication();
- getDataByCorrectAuthentication();
- // 更新数据
- updateDataByNoAuthentication();
- updateDataByBadAuthentication();
- updateDataByCorrectAuthentication();
- // 获取数据
- getDataByNoAuthentication();
- getDataByBadAuthentication();
- getDataByCorrectAuthentication();
- //删除数据
- deleteNodeByBadAuthentication();
- deleteNodeByNoAuthentication();
- deleteNodeByCorrectAuthentication();
- deleteParent();
- zkClient.close();
- }
- /** 获取数据:采用错误的密码 */
- static void getDataByBadAuthentication() {
- String prefix = “[使用错误的授权信息]“;
- try {
- System.out.println( prefix + “获取数据:” + PATH );
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, badAuthentication.getBytes() );
- System.out.println( prefix + “成功获取数据:” + zkClient.readData( PATH ) );
- } catch ( Exception e ) {
- System.err.println( prefix + “获取数据失败,原因:” + e.getMessage() );
- }
- }
- /** 获取数据:不采用密码 */
- static void getDataByNoAuthentication() {
- String prefix = “[不使用任何授权信息]“;
- try {
- System.out.println( prefix + “获取数据:” + PATH );
- zkClient = new ZkClient( SERVER_LIST, 50000);
- System.out.println( prefix + “成功获取数据:” + zkClient.readData( PATH ) );
- } catch ( Exception e ) {
- System.err.println( prefix + “获取数据失败,原因:” + e.getMessage() );
- }
- }
- /** 采用正确的密码 */
- static void getDataByCorrectAuthentication() {
- String prefix = “[使用正确的授权信息]“;
- try {
- System.out.println( prefix + “获取数据:” + PATH );
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() );
- System.out.println( prefix + “成功获取数据:” + zkClient.readData( PATH ) );
- } catch ( Exception e ) {
- System.out.println( prefix + “获取数据失败,原因:” + e.getMessage() );
- }
- }
- /**
- * 更新数据:不采用密码
- */
- static void updateDataByNoAuthentication() {
- String prefix = “[不使用任何授权信息]“;
- System.out.println( prefix + “更新数据: ” + PATH );
- try {
- zkClient = new ZkClient( SERVER_LIST, 50000);
- if( zkClient.exists( PATH ) ){
- zkClient.writeData( PATH, prefix );
- System.out.println( prefix + “更新成功” );
- }
- } catch ( Exception e ) {
- System.err.println( prefix + “更新失败,原因是:” + e.getMessage() );
- }
- }
- /**
- * 更新数据:采用错误的密码
- */
- static void updateDataByBadAuthentication() {
- String prefix = “[使用错误的授权信息]“;
- System.out.println( prefix + “更新数据:” + PATH );
- try {
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, badAuthentication.getBytes() );
- if( zkClient.exists( PATH ) ){
- zkClient.writeData( PATH, prefix );
- System.out.println( prefix + “更新成功” );
- }
- } catch ( Exception e ) {
- System.err.println( prefix + “更新失败,原因是:” + e.getMessage() );
- }
- }
- /**
- * 更新数据:采用正确的密码
- */
- static void updateDataByCorrectAuthentication() {
- String prefix = “[使用正确的授权信息]“;
- System.out.println( prefix + “更新数据:” + PATH );
- try {
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() );
- if( zkClient.exists( PATH ) ){
- zkClient.writeData( PATH, prefix );
- System.out.println( prefix + “更新成功” );
- }
- } catch ( Exception e ) {
- System.err.println( prefix + “更新失败,原因是:” + e.getMessage() );
- }
- }
- /**
- * 不使用密码 删除节点
- */
- static void deleteNodeByNoAuthentication() throws Exception {
- String prefix = “[不使用任何授权信息]“;
- try {
- System.out.println( prefix + “删除节点:” + PATH_DEL );
- zkClient = new ZkClient( SERVER_LIST, 50000);
- if( zkClient.exists( PATH_DEL ) ){
- zkClient.delete( PATH_DEL );
- System.out.println( prefix + “删除成功” );
- }
- } catch ( Exception e ) {
- System.err.println( prefix + “删除失败,原因是:” + e.getMessage() );
- }
- }
- /**
- * 采用错误的密码删除节点
- */
- static void deleteNodeByBadAuthentication() throws Exception {
- String prefix = “[使用错误的授权信息]“;
- try {
- System.out.println( prefix + “删除节点:” + PATH_DEL );
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, badAuthentication.getBytes() );
- if( zkClient.exists( PATH_DEL ) ){
- zkClient.delete( PATH_DEL );
- System.out.println( prefix + “删除成功” );
- }
- } catch ( Exception e ) {
- System.err.println( prefix + “删除失败,原因是:” + e.getMessage() );
- }
- }
- /**
- * 使用正确的密码删除节点
- */
- static void deleteNodeByCorrectAuthentication() throws Exception {
- String prefix = “[使用正确的授权信息]“;
- try {
- System.out.println( prefix + “删除节点:” + PATH_DEL );
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() );
- if( zkClient.exists( PATH_DEL ) ){
- zkClient.delete( PATH_DEL );
- System.out.println( prefix + “删除成功” );
- }
- } catch ( Exception e ) {
- System.out.println( prefix + “删除失败,原因是:” + e.getMessage() );
- }
- }
- /**
- * 使用正确的密码删除节点
- */
- static void deleteParent() throws Exception {
- try {
- zkClient = new ZkClient( SERVER_LIST, 50000);
- zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() );
- if( zkClient.exists( PATH ) ){
- zkClient.delete( PATH );
- }
- } catch ( Exception e ) {
- e.printStackTrace();
- }
- }
- @Override
- public void process( WatchedEvent event ) {
- // TODO Auto-generated method stub
- }
- }
方案二、对zookeeper的AuthenticationProvider进行扩展,和内部其它系统A打通,从系统A中获取一些信息来判断权限
这个方案大致是这样:
1. A系统上有一份IP和appName对应的数据本地。
2. 将这份数据在ZK服务器上缓存一份,并定时进行缓存更新。
3. 每次客户端对服务器发起请求的时候,获取客户端ip进行查询,判断是否有对应appName的权限。限制指定ip只能操作指定 /appName znode。
4. 其它容灾措施。
个人比较两个方案:
1.方案一较方案二,用户的掌控性大,无论线上,日常,测试都可以由应用开发人员自己决定开启/关闭权限。 (方案一的优势)
2.方案二较方案一,易用性强,用户的使用和无权限基本一致。 (方案二的优势)
3.方案一较方案二更为纯洁。因为我觉得zk本来就应该是一个底层组件,让他来依赖其它上层的另一个系统?权限的控制精度取决于系统A上信息的准确性。 (方案一的优势)
另外附上 方案一 有权限和无权限对比压测TPS情况
测试条件:三台ZK服务器:8核 JDK 1.6.0-06 四台zk客户端机器:5核 JDK1.6.0-21
测试场景:800个发布者,对应800个path,每个path 3个订阅者,共2400个订阅者。发布者发布数据,通知订阅者。
结论:权限控制对zk的TPS有一定的影响,但是还是保持在较高的水准(1.3w+),如图(点击查看大图):
ZooKeeper 权限管理的更多相关文章
- Zookeeper权限管理与Quota管理
Zookeeper的ACL机制和Quota机制网上资料较少,这里做一个总结,以供大家参考. 1 Zookeeper ACL ZooKeeper的权限管理亦即ACL控制功能通过Server.Client ...
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- Android权限管理之Android 6.0运行时权限及解决办法
前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...
- Android权限管理之Permission权限机制及使用
前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...
- SpringMVC+Shiro权限管理【转】
1.权限的简单描述 2.实例表结构及内容及POJO 3.Shiro-pom.xml 4.Shiro-web.xml 5.Shiro-MyShiro-权限认证,登录认证层 6.Shiro-applica ...
- Android6.0运行时权限管理
自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,而是更加的注重用户的隐私和体验,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装 ...
- Oracle 表空间和用户权限管理
一. 表空间 Oracle数据库包含逻辑结构和物理结构. 数据库的物理结构指的是构成数据库的一组操作系统文件. 数据库的逻辑结构是指描述数据组织方式的一组逻辑概念以及它们之间的关系. 表空间是数据库逻 ...
- [Django]用户权限学习系列之权限管理界面实现
本系列前三章: http://www.cnblogs.com/CQ-LQJ/p/5604331.htmlPermission权限基本操作指令 http://www.cnblogs.com/CQ-LQJ ...
- [Django]用户权限学习系列之设计自有权限管理系统设计思路
若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ- ...
随机推荐
- Android自定义处理崩溃异常
用过安卓手机的用户以及安卓开发者们会时长碰到程序异常退出的情况,普通用户遇到这种情况,肯定非常恼火,甚至会骂一生垃圾软件,然后卸载掉.那么开发者们在开发过程中遇到这种情况给怎么办呢,当然,你不可能世界 ...
- ubuntu mysql表名大小写区分
近期开发线上操作系统用的ubuntu,数据库用的mysql,突然发现mysql表名大写报错,找一下原因,看了下mysql的配置,果真可以设置,窃喜. 先找到你MySQL的my.cnf配置文件并修改,当 ...
- 3.Lucene3.x API分析,Director 索引操作目录,Document,分词器
1 Lucene卡发包结构分析 包名 功能 org.apache.lucene.analysis Analysis提供自带的各种Analyzer org.apache.lucene.colla ...
- 详解EBS接口开发之采购申请导入
更多内容可以参考我的博客 详解EBS接口开发之采购订单导入 http://blog.csdn.net/cai_xingyun/article/details/17114697 /*+++++++ ...
- 如何在SpriteBuilder中设置对象的通用属性
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在SpriteBuilder中可以为对象设置自定义类从 ...
- Oracle使用游标查询指定数据表的所有字段名称组合而成的字符串
应用场合:参考网上查询数据表的所有字段名代码,使用游标生成指定单个表的所有字段名跟逗号组成的用于select 逗号隔开的字段名列表 from字符串等场合. 查询结果输出如下: 当前数据表TB_UD_ ...
- BFS与DFS总结
最近一直在看DFS和BFS,感觉要晕的GJ. DFS思想: 一直往深处走,直到找到解或者走不下去为止 DFS框架: DFS(dep,-) //dep代表目前DFS的深度 { if (找到 ...
- CCM和GCM
分组密码链接-消息认证码--CCM Counter with CBC-MAC 组成CCM的关键算法是AES加密算法.CTR工作模式和CMAC认证算法,在加密和MAC算法中共用一个密钥K. CCM ...
- 北大青鸟Asp.net之颗粒归仓
自从小编走进编程的世界以来,学习的编程知识都是和C/S这个小伙伴握手,直到做完牛腩老师的新闻发布系统,才开始了小编的B/S学习生涯,和B/S初次谋面,小宇宙瞬间爆发了,看着自己的第一个B/S系统,牛腩 ...
- 偏置方差分解Bias-variance Decomposition
http://blog.csdn.net/pipisorry/article/details/50638749 偏置-方差分解(Bias-Variance Decomposition) 偏置-方差分解 ...