Zookeeper構成センターサービスガバナンス実装

12266 ワード

Zookeeper構成センターサービスガバナンス実装
背景
前回のブログでは、EurekaではなくZookeeperをサービス発見フレームワークとして選択した理由を詳しく説明しました.このブログを参考にして、どのように実現するかを説明し続けます.中には大量のコードのコピーがあります.具体的なアーキテクチャは前のブログのアーキテクチャの進化図を参考にすることができます.本編では主に実現過程を説明する.
準備作業
  • Spring MavenプロジェクトはZookeeperの依存パッケージを追加し、ZookeeperのSDKを使用することができます.
  •         <dependency>
                <groupId>org.apache.zookeepergroupId>
                <artifactId>zookeeperartifactId>
                <version>3.3.6version>
           dependency>
    

    football-serverサービス登録機能を実現
    Zookeeperを作成します.propertiesはresourcesディレクトリの下にあり、パラメータを書き込みます.
    server.parent.name = football (        )
    server.instance.name = football-server (       )
    server.port = 8081 (        )
    zookeeper.host = Your zookeeper address
    zookeeper.port = Your zookeeper port 

    Zookeeperを作成します.propertiesはファイルのクラスを読み込みます.
    @Component
    public class ZookeeperProperties {
    
        @Value("${zookeeper.host}")
        private String host;
    
        @Value("${zookeeper.port}")
        private String zkPort;
    
        @Value("${server.parent.name}")
        private String parentName;
    
        @Value("${server.port}")
        private String serverPort;
    
        @Value("${server.instance.name}")
        private String instanceName;
    
        public String getZookeeperAddress(){
    
            return String.format("%s:%s",host,zkPort);
        }
    
        public String getParentName() {
            parentName=parentName.replace("/","");
            return parentName;
        }
    
        public String getServerPort() {
            return serverPort;
        }
    
        public String getInstanceName() {
            parentName=parentName.replace("/","");
            return instanceName;
        }
    }
    

    サービス起動に成功した後、Zookeeperを呼び出したJavaSDKはZookeeperに自分を登録する.
    
    @Service
    public class ZookeeperRegistrar implements ApplicationListener {
    
    
        @Autowired
        ZookeeperProperties zookeeperProperties;
    
    
    
        private static Logger log = LoggerFactory.getLogger(ZookeeperRegistrar.class);
    
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
            if(contextRefreshedEvent.getApplicationContext().getParent()==null){
                try {
                    registry();
                } catch (IOException e) {
                    log.error("fooball-server registry to zookeeper fault ,{}",e.getMessage());
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    log.error("fooball-server registry to zookeeper fault ,{}",e.getMessage());
                    e.printStackTrace();
                } catch (KeeperException e) {
                    log.error("fooball-server registry to zookeeper fault ,{}",e.getMessage());
                    e.printStackTrace();
                }
    
            }
        }
    
        public void registry() throws IOException, KeeperException, InterruptedException {
    
            Watcher watcher=new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    log.info("zookeeper watcher ,{}",watchedEvent.toString());
                }
            };
            ZooKeeper zooKeeper = new ZooKeeper(zookeeperProperties.getZookeeperAddress(),200000,watcher);
            initParentPath(zooKeeper,watcher);
            createInstancePath(zooKeeper,watcher);
    
        }
    
        public void initParentPath(ZooKeeper zookeeper,Watcher watcher) throws KeeperException, InterruptedException, UnknownHostException {
            String parentPath = String.format("/%s",zookeeperProperties.getParentName());
            log.info("fooball-server parentPath:{}",parentPath);
            if(zookeeper.exists(parentPath,watcher)==null){
                zookeeper.create(parentPath,null,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
                log.info("create parentPath {} success.",parentPath);
            }
    
        }
    
        public void createInstancePath(ZooKeeper zooKeeper,Watcher watcher) throws KeeperException, InterruptedException, UnknownHostException {
            String instancePath = String.format("/%s/%s",zookeeperProperties.getParentName(),zookeeperProperties.getInstanceName());
            zooKeeper.create(instancePath,instanceInfoToByte(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            log.info("create path {} success.",zookeeperProperties.getInstanceName());
        }
    
    
        public String getHost() throws UnknownHostException {
            InetAddress address = InetAddress.getLocalHost();
            return address.getHostAddress();
        }
    
        public InstanceInfo createInstanceInfo() throws UnknownHostException {
            String host = String.format("%s:%s",getHost(),zookeeperProperties.getServerPort());
            log.info("current instance host {}",host);
            return new InstanceInfo(zookeeperProperties.getInstanceName(),host);
        }
    
        public byte[] instanceInfoToByte() throws UnknownHostException {
            Gson gson=new Gson();
            InstanceInfo instanceInfo = createInstanceInfo();
            return gson.toJson(instanceInfo).getBytes();
        }
    
    
    
    }
    
    
    

    fooball-metaサービス発見機能の実現
    Zookeeperを作成します.propertiesと読み取りの作成propertiesファイルのクラスはfootball-serverと一致しています.
    Zookeeperから登録サービスのパラメータを取得する
    @Service
    public class MetaService implements IMetaService {
    
        @Autowired
        ZooKeeper zooKeeper;
    
        @Autowired
        ZookeeperProperties zookeeperProperties;
    
        @Autowired
        Watcher watcher;
    
        private static Logger log = LoggerFactory.getLogger(MetaService.class);
    
        @Override
        public List getServiceInfo() {
            try {
                String parentPath = String.format("/%s",zookeeperProperties.getParentName());
                List childs = zooKeeper.getChildren(parentPath,false);
                return getInstancesByName(childs);
            } catch (KeeperException e) {
                log.error("Zookeeper getChildren error!");
                e.printStackTrace();
            } catch (InterruptedException e) {
                log.error("Zookeeper getChildren error!");
                e.printStackTrace();
            }
            return Collections.emptyList();
        }
    
        public List getInstancesByName(List childs) throws KeeperException, InterruptedException {
            List instanceInfos =new ArrayList();
            for(String childName:childs){
                String childPath = String.format("/%s/%s",zookeeperProperties.getParentName(),childName);
                instanceInfos.add(getInstanceFromZK(childPath));
            }
            return instanceInfos;
        }
    
        public InstanceInfo getInstanceFromZK(String path) throws KeeperException, InterruptedException {
    
            byte[] data = zooKeeper.getData(path,watcher,null);
            String instanceJson = new String(data);
            return new Gson().fromJson(instanceJson,InstanceInfo.class);
        }
    
    }