报错现象:Java SpringBoot连接zookeeper超时报错
连本地localhost时正常,连接外网服务器时报错:zookeeper not connected

调试:CuratorZookeeperClient.java调试可发现timeout=3000

方案一:增加config-center.timeout配置

#dubbo配置
dubbo:
  application:
    name: his-system-web-service
  registry:
    address: zookeeper://#.#.#.#:2181
    #address: zookeeper://localhost:2181
    #like12 find,bug,(此处设置无效),连接外网zookeeper时一般需要10秒左右才能完毕,默认的3秒将导致系统启动不成功(zookeeper not connected)
    #timeout: 20000
  #like12 find,bug,(设在这里才生效),连接外网zookeeper时一般需要10秒左右才能完毕,默认的3秒将导致系统启动不成功(zookeeper not connected)
  config-center:
    address: ${dubbo.registry.address} #不配address走的是RegistryService,设置的timeout不会进到url 导致无效,配后依然走ConfigCenterConfig
    timeout: 20000
  consumer:
    check: false

方案二:直接强改jar包源代码

新增org.apache.dubbo.config.ConfigCenterConfig.java

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.apache.dubbo.config;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.config.support.Parameter;

public class ConfigCenterConfig extends AbstractConfig {
    private AtomicBoolean inited = new AtomicBoolean(false);
    private String protocol;
    private String address;
    private String cluster;
    private String namespace = "dubbo";
    private String group = "dubbo";
    private String username;
    private String password;
    //like12 find,bug,连接外网zookeeper时一般需要10秒左右才能完毕,默认的3秒将导致系统启动不成功(zookeeper not connected)
    //设置在application.yml的dubbo.registry.timeout中无效
    private Long timeout = 20000L;
    //private Long timeout = 3000L;
    private Boolean highestPriority = true;
    private Boolean check = true;
    private String configFile = "dubbo.properties";
    private String appConfigFile;
    private Map<String, String> parameters;
    private Map<String, String> externalConfiguration;
    private Map<String, String> appExternalConfiguration;

    public ConfigCenterConfig() {
    }

    public URL toUrl() {
        Map<String, String> map = new HashMap();
        appendParameters(map, this);
        if (StringUtils.isEmpty(this.address)) {
            this.address = "0.0.0.0";
        }

        map.put("path", ConfigCenterConfig.class.getSimpleName());
        if (StringUtils.isEmpty((String)map.get("protocol"))) {
            map.put("protocol", "zookeeper");
        }

        return UrlUtils.parseURL(this.address, map);
    }

    public boolean checkOrUpdateInited() {
        return this.inited.compareAndSet(false, true);
    }

    public Map<String, String> getExternalConfiguration() {
        return this.externalConfiguration;
    }

    public Map<String, String> getAppExternalConfiguration() {
        return this.appExternalConfiguration;
    }

    public void setExternalConfig(Map<String, String> externalConfiguration) {
        this.externalConfiguration = externalConfiguration;
    }

    public void setAppExternalConfig(Map<String, String> appExternalConfiguration) {
        this.appExternalConfiguration = appExternalConfiguration;
    }

    public String getProtocol() {
        return this.protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    @Parameter(
            excluded = true
    )
    public String getAddress() {
        return this.address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCluster() {
        return this.cluster;
    }

    public void setCluster(String cluster) {
        this.cluster = cluster;
    }

    public String getNamespace() {
        return this.namespace;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    public String getGroup() {
        return this.group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public Boolean isCheck() {
        return this.check;
    }

    public void setCheck(Boolean check) {
        this.check = check;
    }

    @Parameter(
            key = "highest-priority"
    )
    public Boolean isHighestPriority() {
        return this.highestPriority;
    }

    public void setHighestPriority(Boolean highestPriority) {
        this.highestPriority = highestPriority;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Long getTimeout() {
        return this.timeout;
    }

    public void setTimeout(Long timeout) {
        this.timeout = timeout;
    }

    @Parameter(
            key = "config-file"
    )
    public String getConfigFile() {
        return this.configFile;
    }

    public void setConfigFile(String configFile) {
        this.configFile = configFile;
    }

    @Parameter(
            excluded = true,
            key = "app-config-file"
    )
    public String getAppConfigFile() {
        return this.appConfigFile;
    }

    public void setAppConfigFile(String appConfigFile) {
        this.appConfigFile = appConfigFile;
    }

    public Map<String, String> getParameters() {
        return this.parameters;
    }

    public void setParameters(Map<String, String> parameters) {
        this.parameters = parameters;
    }

    @Parameter(
            excluded = true
    )
    public boolean isValid() {
        if (StringUtils.isEmpty(this.address)) {
            return false;
        } else {
            return this.address.contains("://") || StringUtils.isNotEmpty(this.protocol);
        }
    }
}

java连接zookeeper测试

package com.qyj.test;

import cn.hutool.core.date.DateUtil;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.Date;

public class ZKClient {
    String connectString ="#.#.#.#:2181"; //ZKip地址+客户端通信端口号
    //String connectString ="localhost:2181"; //ZKip地址+客户端通信端口号
    int sessionTimeOut = 20000; //会话超时时间,该时间内,如果没有连接成功,则超时
    ZooKeeper zkClient;

    @Test
    public void createZnode() throws KeeperException, InterruptedException, IOException {
        zkClient = new ZooKeeper(connectString, sessionTimeOut, (watchedEvent) -> {  });
        System.out.println(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        String s = zkClient.create("/lol5", "league of lengend".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(s);
    }
}

application.yml引用前面定义的变量

address: ${dubbo.registry.address}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐