Ldaptive 实时同步

Ldaptive Sync Repl

openLdap 内容同步协议
Ldaptive 中使用 Sync Repl

简介

LDAP 同步协议通过定义两个相应的同步操作来支持轮询和侦听更改:refreshOnlyrefreshAndPersist

为了提高性能和减少网络传输,ldap数据同步协议要求客户端发起同步请求时,提供一个 cookie (最开始的请求除外)。服务端根据此cookie来决定发送给客户端的数据,客户端根据接收到的数据来处理本地的 ldap 条目。在同步完成之后,客户端必须更新 cookie,用于下次同步。Cookie是服务端计算(查询本地条目)的依据。

在每种模式中,都涉及到如何计算数据的变化,包括:添加的数据、修改的数据以及删除的数据。Ldap的每个条目包含了时间信息,包括生成时间戳(createTimestamp)和修改时间戳(modifyTimestamp)。对于添加和修改的数据,服务端根据客户端传送来的cookie(包含时间信息)计算得到,并将这些数据发送给客户端,每个数据标记是添加的还是修改的。当服务端有修改日志时,服务端可以较容易地根据cookie来计算被删除的条目,并将这些条目的 DN 或者 UUID 发送给客户端。客户端收到后删除本地的条目。此种情况下,删除条目的计算在服务端完成。当服务端无记录修改日志时,服务端无法计算哪些条目被删除,它只能提供当前还存在的数据。服务端将这些还存在的条目 DN 或者 UUID 发送给客户端,由客户端来计算已删除条目。

Refresh Only

在这里插入图片描述

1. Initial Content Request(初始请求)中,客户端不提供cookie,
服务端返回所有符合查询条件的条目,结束时客户端得到一个cookie;

2.Content Refresh Request(内容更新请求)与初始化请求的查询条件必须一致,并且包含一个cookie

3.内容更新阶段,“Changes Entries”包括新添加的条目和修改的条目(基于cookie计算得出);
对于已删除的条目,有两种方式来通知客户端。“Present Messages”用于返回当前还存在的条目;“Deleted?Messages”用于明确告知客户端已删除的条目。这两种消息仅包含条目的名称(DirectoryName)或者UUID。

Refresh and Persist

在这里插入图片描述

1.refreshAndPersist模式包括两个阶段: refresh 和 persist。
Refresh阶段用来保证客户端与服务端内容一致,persist阶段由服务端循环发送数据改变给客户端;

2)persist阶段中,服务端发送改变数据时,发送cookie给客户端(可选)
overlay syncprov:后端使用 syncprov 作为 overlay 组件的扩展
syncprov-checkpoint 100 1: 同步的满足条件,当满足修改 100 个条目或者1分钟主动进行推送一次;
syncprov-sessionlog 100:会话日志条目的最大数量

服务端同步配置

启用添加syncprov模块来实现主从复制功能点,通过ldif文件来增加syncprov模块,无需重启ldap server
cat mod_syncprov.ldif 

dn: cn=module{0},cn=config 
changetype: modify 
add: olcModuleLoad 
olcModuleload: syncprov.la
//添加到 Ldap 配置库中
ldapadd -Y EXTERNAL -H ldapi:/// -f mod_syncprov.ldif

生成 syncprov 配置

dn: olcOverlay=syncprov,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 1 1
olcSpSessionLog: 32767
//同样添加到 Ldap 配置库中
ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov.ldif
//此处注意如果你启动指定的数据库类型 mdb or hdb or bdb;

//当修改1条或者一分钟时,以实现实时同步
olcSpCheckpoint: 1 1

//session log 会话日志条目的最大数量
olcSpSessionLog: 100

//使用访问日志覆盖网络支持基于增量的同步复制支持时,必须将其设置为 TRUE。默认值为 FALSE。
olcSpReloadhint: TRUE

//不存在选项; 此值应仅针对日志数据库(例如由访问日志覆盖管理的列表)之上的 syncprov 实例设置为 TRUE。默认值为 FALSE。
olcSpNopresent <TRUE|FALSE>

Ldaptive 客户端配置

public void ldapTiveTest() throws LdapException, InterruptedException {

        String connectionUrl="ldap://127.0.0.1:389";
        String bindDn="cn=admin,dc=example";
        String bindCredential="123456";
        String baseDn="dc=example";

        SingleConnectionFactory cf = SingleConnectionFactory.builder()
                .config(ConnectionConfig.builder()
                        .url(connectionUrl)
                        .useStartTLS(false)
                        .connectionInitializers(BindConnectionInitializer.builder()
                                .dn(bindDn)
                                .credential(bindCredential)
                                .build())
                        .build())
                .build();

        cf.initialize();

//        执行查询,确保连接建立成功
//        SearchOperation searchOperation=new SearchOperation(cf,baseDn);
//        SearchResponse response = searchOperation.execute("(objectClass=*)");
//        for (LdapEntry entry : response.getEntries()) {
//            // do something useful with the entry
//            System.out.println("Entry:"+entry.toString());
//        }

        //Sync Repl
        SyncReplClient client = new SyncReplClient(cf, true); // true indicates persist
        SearchRequest request = SearchRequest.objectScopeSearchRequest(baseDn);
        request.setSearchScope(SearchScope.SUBTREE);
        request.setFilter("(objectClass=*)");

        client.setOnEntry(e -> {
            // process this entry with the sync state control data
            log.info("************Entry************:e{}",e);
            SyncStateControl ssc = (SyncStateControl) e.getControl(SyncStateControl.OID);
            if (false) { // arbitrary condition
                // stop receiving updates
                log.info("************Stop Update************");
                client.cancel();
            }
        });

        client.setOnMessage(m -> {
            // process a message
            log.info("************Message************:m:{}",m);
        });

        client.setOnResult(r -> {
            // synchronization complete
            log.info("************Result************:r:{}",r);
            SyncDoneControl syncDoneControl = (SyncDoneControl) r.getControl(SyncDoneControl.OID);
        });

        client.setOnException(e -> {
            // handle exception
            log.info("************Exception************:e:{}",e);
        });

        DefaultCookieManager cookieManager=new DefaultCookieManager();
        SearchOperationHandle handle = client.send(request, cookieManager);
        //wait until result is received (or forever)
        handle.await();
        client.close();
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值