apollo1.5配置zuul动态路由不能保证有序性的问题解决方案

背景

系统使用的是zuul作为网关,我们的zuul规则是/api/{service-id}但是其中有个规则/api/*转发到指定服务,
我们把转发规则配置到yml文件中,后面系统接入apollo版本是1.5.1,发现拉回来配置的是混乱的,但是我们的zuul路由规则是要求有序的。

1.解决问题

首先上apollo的github查找是否存在同样的问题,结果果然搜索到一个有相同问题的,附上github链接:
https://github.com/ctripcorp/apollo/issues/2451 查找到问题解决思路,再继续看后面发现已经提交
代码结局了这个问题,如下图进一步去查看源码这一问题是怎么解决的。我们在我们引入的1.5版本的apollo是没有这个的,所以我们需要引入1.6版本的apollo

如图

2.源码

在github找到修改当前问题提交的代码链接: https://github.com/songdragon/apollo/pull/2/commits/6f4d3e56a2466c8ef23ba89b5facc4751dca1ce8
 List<ConfigChange> calcPropertyChanges(String namespace, Properties previous,
                                         Properties current) {
    if (previous == null) {
      previous = new Properties();
      previous =  PropertiesFactory.getPropertiesObject();
    }

    if (current == null) {
      current = new Properties();
      current =  PropertiesFactory.getPropertiesObject();
    }

    Set<String> previousKeys = previous.stringPropertyNames();
从上面可以发现使用PropertiesFactory.getPropertiesObject()替代了Properties,
因为Properties是继承Hashtable是无序的这个就是问题所在。下面我们去查看下PropertiesFactory
public interface PropertiesFactory {

  /**
   * Configuration to keep properties order as same as line order in .yml/.yaml/.properties file.
   */
  String APOLLO_PROPERTY_ORDER_ENABLE = "apollo.property.order.enable";

  /**
   * <pre>
   * Default implementation:
   * 1. if {@link APOLLO_PROPERTY_ORDER_ENABLE} is true return a new
   * instance of {@link com.ctrip.framework.apollo.util.OrderedProperties}.
   * 2. else return a new instance of {@link Properties}
   * </pre>
   *
   * @return
   */
  public Properties getPropertiesInstance();
看到apollo.property.order.enable这个配置,从描述上看,是保证配置文件的顺序那就是这里了。进一步
看一下PropertiesFactory的实现
public class DefaultPropertiesFactory implements PropertiesFactory {

  private ConfigUtil m_configUtil;

  public DefaultPropertiesFactory() {
    m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
  }

  @Override
  public Properties getPropertiesInstance() {
    if (m_configUtil.isPropertiesOrderEnabled()) {
      return new OrderedProperties();
    } else {
      return new Properties();
    }
  }
}
我们看到这里做了一个判断,是实例化OrderedProperties还是Properties,我们看到OrderedProperties是
继承Properties,其中就是对有序做了一些处理,可以去研究一下,我们现在看下
m_configUtil.isPropertiesOrderEnabled()是做了什么操作,只要这个为true,
那就实例化OrderedProperties那就能保证有序了。

继续看ConfigUtil可以看到isPropertiesOrderEnabled方法只是读取了ConfigUtil的一个属性
propertiesOrdered,那么这个是在哪里设值的呢?我们从ConfigUtil的构造函数中找到了答案
  public ConfigUtil() {
    warnLogRateLimiter = RateLimiter.create(0.017); // 1 warning log output per minute
    initRefreshInterval();
    initConnectTimeout();
    initReadTimeout();
    initCluster();
    initQPS();
    initMaxConfigCacheSize();
    initLongPollingInitialDelayInMills();
    initAutoUpdateInjectedSpringProperties();
    initPropertiesOrdered();
  }
  private void initPropertiesOrdered() {
    String enablePropertiesOrdered = System.getProperty(APOLLO_PROPERTY_ORDER_ENABLE);

    if (Strings.isNullOrEmpty(enablePropertiesOrdered)) {
      enablePropertiesOrdered = Foundation.app().getProperty(APOLLO_PROPERTY_ORDER_ENABLE, "false");
    }

    if (!Strings.isNullOrEmpty(enablePropertiesOrdered)) {
      try {
        propertiesOrdered = Boolean.parseBoolean(enablePropertiesOrdered);
      } catch (Throwable ex) {
        logger.warn("Config for {} is invalid: {}, set default value: false",
            APOLLO_PROPERTY_ORDER_ENABLE, enablePropertiesOrdered);
      }
    }
  }

initPropertiesOrdered这个方法是读取了一个这个配置APOLLO_PROPERTY_ORDER_ENABLE,找到问题了,
我们只需要把这个设置为true就ok了,所以终极解决方案是在jvm启动参数中加上
apollo.property.order.enable=true。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值