爬虫類の実現のZooKeeperのクラスタベースの監視

ZooKeeperの

zookeeper.png

ZooKeeperのは、オープンソースの分散コーディネーションサービス、自社のアプリケーションにアクセスするためのシンプルかつ堅牢な方法のために構築された「ヤフー」の元々のZooKeeperフレームワークです。その後、ApacheのZooKeeperのは、組織的なサービスのHadoop、HBaseの、使用する他の分散フレームワークの標準となって。たとえば、ApacheのHBaseがZooKeeperの追跡状態を使用してデータを分散しました。ZooKeeperのの目標は、プリミティブの高効率で信頼性の高いセットを形成するために一緒にサービスパッケージの複雑でエラーが発生しやすい分散型の一貫性を設計することで、簡単な一連のユーザーにインターフェイスを使用します。

ZooKeeperのは、一般的に使用されています。サービス、構成管理、クラスタ管理、分散協調/通知、分散ロックと分散キューなどに名前を付けます。

爬虫類のZooKeeperクラスタを達成するために、管理に登録された各クローラ・ノード。NetDiscoveryは爬虫類のクラスタを監視するためのZooKeeperの特性を使用することです。

NetDiscoveryを達成するためにVert.x、爬虫類共通フレームワークRxJava 2と他のフレームワークに基づいています。それは豊富含まれてい特性を

爬虫類のクラスタを監視

NetDiscoveryはスパイダーとSpiderEngineが含まれています。スパイダーは、爬虫類のためのビジネスロジックを実装し、スパイダーは、それぞれがSpiderEngineスパイダーのライフサイクルで管理し、SpiderEngineに追加することができます。

しかし、後にSpiderEngineはそれを監視および管理する方法、各ノードにSpiderEngineを展開しましたか?

あなたはのZooKeeperに登録するには、実行時にSpiderEngineことができます。(事前のZooKeeperクラスタの作成/ netdiscoveryノードに必要)


    /**
     * 启动SpiderEngine中所有的spider,让每个爬虫并行运行起来。
     *
     */
    public void run() {

        if (Preconditions.isNotBlank(spiders)) {

            registerZK();
            ......  
        }
    }

    /**
     * 将当前 SpiderEngine 注册到 zookeeper 指定的目录 /netdiscovery 下
     */
    private void registerZK() {

        if (Preconditions.isNotBlank(zkStr) && useZk) {
            log.info("zkStr: {}", zkStr);

            RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
            CuratorFramework client = CuratorFrameworkFactory.newClient(zkStr, retryPolicy);
            client.start();
            try {
                String ipAddr = InetAddress.getLocalHost().getHostAddress() + "-" + defaultHttpdPort + "-" + System.currentTimeMillis();
                String nowSpiderEngineZNode = "/netdiscovery/" + ipAddr;
                client.create().withMode(CreateMode.EPHEMERAL).forPath(nowSpiderEngineZNode,nowSpiderEngineZNode.getBytes());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
复制代码

また、必要が使用するNetDiscoveryモニターCuratorManagerクラス。そのウォッチャーメカニズム飼育係では、モニタは親のznodeのznodeの下にそれぞれの子/ netdiscoveryに登録されている、それは、各SpiderEngineです。

ウォッチャーメカニズムは、ZooKeeperのサーバへの同時登録ウォッチャーのZooKeeperクライアントを指し、ウォッチャーオブジェクトは、クライアントのWatchManagerに格納されます。ZooKeeperのサーバがウォッチャーのイベントをトリガした後、通知がクライアントに送信され、クライアントスレッドのコールバックWatcherは中WatchManagerから関数を実行します。

    /**
     * 当前所监控的父的 zNode 下若是子 zNode 发生了变化:新增,删除,修改
     * <p>
     * 下述方法都会触发执行
     *
     * @param event
     */
    @Override
    public void process(WatchedEvent event) {

        List<String> newZodeInfos = null;
        try {
            newZodeInfos = client.getChildren().usingWatcher(this).forPath("/netdiscovery");
            //根据初始化容器的长度与最新的容器的长度进行比对,就可以推导出当前 SpiderEngine 集群的状态:新增,宕机/下线,变更...
            //哪个容器中元素多,就循环遍历哪个容器。
            if (Preconditions.isNotBlank(newZodeInfos)) {
                if (newZodeInfos.size()>allZnodes.size()){
                    //明确显示新增了哪个 SpiderEngine 节点
                    for (String nowZNode:newZodeInfos) {
                        if (!allZnodes.contains(nowZNode)){
                            log.info("新增 SpiderEngine 节点{}", nowZNode);
                        }
                    }
                }else if (newZodeInfos.size()<allZnodes.size()){
                    // 宕机/下线
                    // 明确显示哪个 SpiderEngine 节点宕机/下线了
                    for (String initZNode : allZnodes) {
                        if (!newZodeInfos.contains(initZNode)) {
                            log.info("SpiderEngine 节点【{}】下线了!", initZNode);

                            // 如果有下线的处理,则处理(例如发邮件、短信等)
                            if (serverOfflineProcess!=null) {
                                serverOfflineProcess.process();
                            }
                        }
                    }
                }else {
                    // SpiderEngine 集群正常运行;
                    // 宕机/下线了,当时马上重启了,总的爬虫未发生变化
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        allZnodes = newZodeInfos;
    }
复制代码

だから我々は、次のような、別のプロセスを実行する必要があります。

public class TestCuratorManager {

    public static void main(String[] args) {

        CuratorManager curatorManager = new CuratorManager();
        curatorManager.start();
    }
}
复制代码

次の図は、SpiderEngineクラスタを監視する方法のZooKeeperを反映しています。

SpiderEngine + ZK.png

概要

爬虫類のフレームワークのgithubの住所:github.com/fengzhizi71 ...

この記事では、爬虫類のクラスタを監視するためのZooKeeperを使用する方法について説明します。将来、NetDiscoveryは、より一般的な機能を増加します。


AndroidとJavaのテクノロジ・スタック:プッシュ毎週更新独自の技術記事、国民はあなたの共通の開発と進歩を楽しみにして、2次元コードの下の数字と懸念をスキャンするために歓迎されています。

おすすめ

転載: juejin.im/post/5ceb44486fb9a07eed34dcce