zoukankan      html  css  js  c++  java
  • Apollo报错找不到apollo.meta的问题解决方案

    问题描述

    Apollo报错,找不到apoll.meta,但是明明配置了apollo-env.properties到apollo-client内了。

    apollo-env.properties

    pro.meta=http://apollo.xxxx.com:81
    

    问题分析

    因公司内部使用的 ctrip Apollo用了较早的版本,期间经过一次升级,而我算是Apollo的忠实用户,使用时间超过两年。
    因此,我恰好知道,Apollo稍早的版本,没有将Apollo-client发布到 中央仓库,因为 Apollo-client的内部包含了编译期间指定的apollo-env.properties文件,
    而为了发布到中央仓库,不能使用此方式将自己公司的meta地址放入其中,因此Apollo增加了一种配置方式:通过JVM参数等方式指定 apollo 的meta Server地址。

    公司Maven仓库内的apollo-client内是含有apollo-env.properties。因此原则上Apollo不需要再配置。

    而为什么报错呢?

    问题原因

    Apollo的 Meta 地址获取逻辑,采用JAVA的SPI实现

    package com.ctrip.framework.apollo.core.spi;
    
    import com.ctrip.framework.apollo.core.enums.Env;
    
    /**
     * @since 1.0.0
     */
    public interface MetaServerProvider extends Ordered {
    
      /**
       * Provide the Apollo meta server address, could be a domain url or comma separated ip addresses, like http://1.2.3.4:8080,http://2.3.4.5:8080.
       * <br/>
       * In production environment, we suggest using one single domain like http://config.xxx.com(backed by software load balancers like nginx) instead of multiple ip addresses
       */
      String getMetaServerAddress(Env targetEnv);
    }
    
    

    而该接口有两个实现

    默认实现:

    public class DefaultMetaServerProvider implements MetaServerProvider
    

    第二个实现:(旧版本)

    public class LegacyMetaServerProvider implements MetaServerProvider
    

    正常情况下,apollo应该使用二者之一的Provider。

    如果JVM启动的时候,使用了DefaultMetaServerProvider,这种情况没有配置JVM参数 apollo.meta,那么将报错,找不到meta server。

    那为什么公司的仓库内 apollo-client 有apollo-env.properties 但是没有使用LegacyMetaServerProvider ?

    问题解决

    因为踩坑次数多了,自然想到去jar包内看看,经过检查发现 jar内的META-INF确实有apollo-env.properties。
    问题就出在,apollo-core-1.3.0-xxx.jar!/META-INF/services/com.ctrip.framework.apollo.core.spi.MetaServerProvider内是:

    com.ctrip.framework.apollo.internals.DefaultMetaServerProvider
    


    apollo-client-1.3.0-xxx.jar!/META-INF/services/com.ctrip.framework.apollo.core.spi.MetaServerProvider内是:

    com.ctrip.framework.apollo.core.internals.LegacyMetaServerProvider
    

    最终原因在于,maven打包工具有 maven-jar-plugin,maven-assembly-plugin, maven-shaded-plugin。

    如果使用spring-boot-maven-plugin,虽然内置有maven-shaded-plugin,但是他根本不知道apollo的。

    这些情况最终导致了不确定性,JVM加载的Jar包顺序不一样,或者打包的顺序,导致一个SPI文件被另一个文件覆盖掉了,因此丢失了一个provider实现。

    但是只有maven-shaded-plugin,可以经过配置TRANSFORMER,将这两种合并到一个com.ctrip.framework.apollo.core.spi.MetaServerProvider文件内。

    最终解决方案

    保持apollo-client和apollo-core包内 的/META-INF/services/com.ctrip.framework.apollo.core.spi.MetaServerProvider
    有两个Provider,分别写一行。
    或者联系相关人员,将这两个文件的内容保持一致,并给出适用的使用方案。例如jar包内附带了pro.meta等变量的时候,提供LegacyMetaServerProvider。
    如果没有附带,则要求使用人员自行配置 apollo.meta。

    刚好这篇文章解决了我另一篇同样是关于Apollo和Dubbo集成的文章中遇到的问题。

    解决Dubbo 2.7.3版本使用ConfigCenterConfig集成Apollo No Provider found的问题

  • 相关阅读:
    hash和history的区别帮助向我一样迷的人弄明白,history和hash
    调用谷歌浏览器的打印所遇到的困难,回流重绘
    webpack简单搭建基础感悟
    linux
    介绍一下call,apply,bind方法实现,源于MDN中的bind
    二进制流转base64加快速度
    手写一个instanceof
    青蛙跳台阶问题
    Django中vue的使用
    pip install 出现 timeout 时的两个临时解决办法
  • 原文地址:https://www.cnblogs.com/slankka/p/11777271.html
Copyright © 2011-2022 走看看