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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM