Apollo報錯找不到apollo.meta的問題解決方案

問題描述

Apollo報錯,找不到apoll.meta,可是明明配置了apollo-env.properties到apollo-client內了。html

apollo-env.propertiesnginx

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

問題分析

因公司內部使用的 ctrip Apollo用了較早的版本,期間通過一次升級,而我算是Apollo的忠實用戶,使用時間超過兩年。
所以,我剛好知道,Apollo稍早的版本,沒有將Apollo-client發佈到 中央倉庫,由於 Apollo-client的內部包含了編譯期間指定的apollo-env.properties文件,
而爲了發佈到中央倉庫,不能使用此方式將本身公司的meta地址放入其中,所以Apollo增長了一種配置方式:經過JVM參數等方式指定 apollo 的meta Server地址。spring

公司Maven倉庫內的apollo-client內是含有apollo-env.properties。所以原則上Apollo不須要再配置。dom

而爲何報錯呢?maven

問題緣由

Apollo的 Meta 地址獲取邏輯,採用JAVA的SPI實現ide

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);
}

而該接口有兩個實現spring-boot

默認實現:工具

public class DefaultMetaServerProvider implements MetaServerProvider

第二個實現:(舊版本)url

public class LegacyMetaServerProvider implements MetaServerProvider

正常狀況下,apollo應該使用兩者之一的Provider。code

若是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的問題

相關文章
相關標籤/搜索