Magpie2._ 用戶手冊 - 中間件&公共組件文檔中心

Magpie2.* 用戶手冊
Magpie簡介¶
Magpie框架是一款分佈式通訊框架,既可用於Java與Java之間的RPC調用,也可用於Java與C之間的byte[]調用。其主要特點如下:

Magpie通訊框架是銀聯自主研發的分佈式系統間通訊框架。
Magpie可單獨使用,也可集成進中間件。
可用於java應用與c應用,java應用與java應用之間的通訊。
具有長鏈接、心跳、自動重連、負載均衡、容錯、服務調用統計監控等特點。
系統間調用是網狀結構,無F5單點,原理上可替代F5。
可替代WTC,由於是embeddable的,所以無java應用服務器的限制。
Summary

目前Weblogic應用與Tuxedo應用的通訊方式有兩種:WTC與Webservice

WTC缺點

WTC爲Oracle專有,如Weblogic更換爲UPJAS,則無法使用WTC
WTC閉源,有無法快速解決問題的風險。
WTC不滿足個性化需求
Webservice缺點

要實現負載均衡需經過F5,隨着調用越來越頻繁,F5成爲單點,並壓力越來越大。
c應用要開發Webservice較麻煩,不像java那麼容易。
webservice協議本身較複雜
Magpie2 工作原理¶
Magpie2.* 版本中引入了“配置中心”與“監控中心”。

相比Magpie 1.*,配置項更多地集中到provider端,精簡了consumer端的配置。

consumer不在需要配置provider的地址和端口,通過zookeeper的註冊和監聽機制,動態的獲取可用的provider列表和provider的配置信息;
當有provider上線或是下線,consumer也可以動態的感知,更新自己調用的provider列表和信息。
Magpie2 的工作原理如下圖:

節點角色說明

Provider: 暴露服務方稱之爲“服務提供者”
Consumer: 調用遠程服務方稱之爲“服務消費者”
Registry: 服務註冊與發現的中心目錄服務稱之爲“服務註冊中心”
Monitor: 統計服務的調用次數和調用時間的日誌服務稱之爲“服務監控中心”
調用關係說明

①: 服務提供者在啓動時,向註冊中心註冊自己提供的服務
②: 服務消費者在啓動時,向註冊中心訂閱自己所需的服務
③:服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用
④:服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
⑤:註冊中心的服務如果有變更(新增或是宕機),註冊中心將基於長連接推送變更數據給消費者
連通性說明

註冊中心負責服務地址的註冊,查找和服務變更通知,註冊中心不轉發請求,壓力較小
監控中心負責統計各服務調用次數,調用時間等,統計先在內存彙總後每分鐘一次發送到監控中心服務器,並以報表展示
服務提供者向註冊中心註冊其提供的服務
服務消費者向註冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者
註冊中心,服務提供者,服務消費者三者之間均爲長連接
註冊中心通過長連接感知服務提供者的存在,服務提供者宕機,註冊中心將立即推送事件通知消費者
註冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
註冊中心和監控中心都是可選的,服務消費者可以直連服務提供者
健壯性說明

監控中心宕掉不影響使用,只是丟失部分採樣數據
註冊中心對等集羣,任意一臺宕掉後,將自動切換到另一臺
註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地緩存通訊
服務提供者無狀態,任意一臺宕掉後,不影響使用
服務提供者全部宕掉後,服務消費者應用將無法使用
伸縮性說明

註冊中心爲對等集羣,可動態增加機器部署實例,所有客戶端將自動發現新的註冊中心
服務提供者無狀態,可動態增加機器部署實例,註冊中心將推送新的服務提供者信息給消費者
Quote

magpie2.*的代碼示例:http://172.17.249.122/magpie-team/magpie-quickstarts/tree/master

安裝Magpie(Maven)¶
強烈建議升級到magpie2.0.7.Final以及之後的版本 ! ! !

通過Maven安裝magpie步驟如下:

  1. 首先在~/.m2/setting.xml中配置nexus服務器信息(因爲magpie的jar都放在nexus中)

    nexus * http://172.18.64.96:8080/nexus/content/groups/public/
  2. 在pom.xml中添加magpie的依賴:

    com.unionpay.magpie magpie ${magpie.release.version}

    上述命令中的${magpie.release.version}表示magpie最新的發佈版本號。請查詢[Nexus開發庫]
    (http://172.18.64.96:8080/nexus/index.html),使用最新的magpie版本號
    安裝Magpie(非Maven)¶
    對於非Maven工程,請下載:Binary發佈版

日誌組件依賴¶
Magpie框架本身使用公共組件 upcommon-log 作爲log facade,日誌默認實現是jul,如果想把log4j或者logback作爲後端日誌實現的話,需要依賴相應的橋接。

<!-- upcommon-log到log4j的橋接 -->
<dependency>
  <groupId>com.unionpay.common.upcommon-log</groupId>
  <artifactId>uplog-bridge-log4j1.X</artifactId>
  <version>1.1.0</version>
</dependency>

<!-- upcommon-log到logback的橋接 -->
<dependency>
  <groupId>com.unionpay.common.upcommon-log</groupId>
  <artifactId>uplog-bridge-logback</artifactId>
  <version>1.1.0</version>
</dependency>

日誌級別設置¶
在log4j.properties中加入 log4j.logger.com.unionpay.magpie=DEBUG,可以打印出詳細的magpie日誌。

在log4j.properties中加入 log4j.logger.org.jboss.netty=DEBUG,可以打印出完整的網絡報文、鏈路的詳細日誌。

magpie.xml中設置變量¶
參考如下配置片段:

<magpie xmlns='uri:unionpay:magpie:1.0'>
    <application name="SYS_C" heartbeatInterval="60000"/>
    <reference serviceId="ServiceD" version="1.0" urls="${myUrl=127.0.0.1:6666}"
        loadbalanceStrategy="random" failStrategy="failover" retries="2" oneway="false" 
        timeout="5000" weights="100" codec="magpie" interfaceClass="aa.binaryserver.Hello" />
</magpie>

其中: urls 中的${myUrl=127.0.0.1:6666}表示先從system property中取myUrl 的值,如果沒有設置,則默認爲 127.0.0.1:6666。

System property可以統一設置到$CLASSPATH/appCfg/magpie.properties 或者 $CLASSPATH/magpie.properties中,magpie.properties示例如下:

myUrl=127.0.0.1:7777

Magpie2使用¶
server暴露服務步驟¶

  1. 在 log4j.properties 中爲magpie設置日誌級別,示例:

       log4j.rootLogger=INFO
       log4j.logger.org.jboss.netty=INFO, stdout, R
       log4j.logger.com.unionpay.magpie=INFO, stdout, R
       log4j.appender.stdout=org.apache.log4j.ConsoleAppender
       log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
       log4j.appender.stdout.layout.ConversionPattern=%d [%t]() %-5p %c - %m%n
       log4j.appender.R=org.apache.log4j.RollingFileAppender
       log4j.appender.R.File=/tmp/magpie2-quickstarts-provider.log
       log4j.appender.R.MaxFileSize=20MB
       log4j.appender.R.MaxBackupIndex=20
       log4j.appender.R.layout=org.apache.log4j.PatternLayout
       log4j.appender.R.layout.ConversionPattern=%d [%t]() %-5p %c - %m%n
    
  2. 新建magpie.xml,放入CLASSPATH/appCfg/CLASSPATH/appCfg/中或者CLASSPATH/中,請參考示例中的註釋:

     <?xml version="1.0" encoding="UTF-8"?>
       <magpie xmlns='uri:unionpay:magpie:2.0'>
       <!-- 應用基本信息
        name:                    (必填)provider所屬的應用名 注意:使用protocol的magpie_binary協議,verion爲1.0時, name長度上限爲8
        heartbeatInterval:       (選填)發送心跳包的間隔,單位:millisecond,默認爲60000(要與consumer心跳保持一致)
        description:             (選填)用戶自定義的應用描述
        dc:                      (選填)provider所在的數據中心,默認爲sh   (目前只有 sh和bj兩種)
        contact:                 (必填)provider的聯繫人,注意電話和郵箱的格式
        nettyWorkerCount:        (選填)nettyWorker的線程數, 不建議用戶自己配置
        nettyBossCount:          (選填)nettyBoss的線程數, 不建議用戶自己配置
       -->
       <application name="APP" heartbeatInterval="60000"
       description="unionpay's provider" dc="sh" contact="name;phone;email" />
    
       <!-- 註冊中心的cluster 
        type:                    (選填) 註冊中心類型,默認爲zookeeper
        sessionTimeoutMs:        (選填) 與註冊中心的session超時時間,單位:millisecond,默認:60000(即1分鐘)
        connectionTimeoutMs:     (選填) 與註冊中心建鏈超時時間,單位:millisecond,默認:10000(即10秒)
        addresses:               (必填) 註冊中心的配置地址,以下是開發環境zookeeper地址
        注:   註冊中心的地址請聯繫公共組件室 
       -->
       <registry addresses="172.18.*.*:2181,172.18.*.*:2181,172.18.*.*:2181" />
    
       <!-- 遠程監控cluster ,monitor地址從zk動態獲取
        monitorInterval          (選填)統計信息發送的間隔時間,單位:millisecond,默認:60000
       <monitor  />  -->
    
       <!-- 不同種協議,應使用不同的端口 支持協議級別的心跳設置, 支持magpie 2.0協議
        version:                 (選填) 默認爲1.0 協議, magpie2.0.5之後的版本兼容1.0和2.0協議;協議區別參見後文的協議介紹
        heartbeatInterval:       (選填) 默認使用的是application中設置的心跳,如果此處有設置,則使用當前設置的
        maxMsgSize:              (選填) 允許的報文最大長度
       -->
       <protocol id="magpieBinaryProtocol" codec="magpie_binary" heartbeatInterval="10000"
       serializationType="binary" ip="127.0.0.1" port="5555" maxMsgSize=“100000”
       listener="com.magpie.quickstarts.v2.binary.MagpieBinaryPayloadListener" version="2.0"/>
    
       <protocol id="magpieRpcProtocol" codec="magpie_rpc" version="2.0"
       serializationType="hessian2" ip="127.0.0.1" port="6666" />
    
       <protocol id="upHeadProtocol" codec="uphead" ip="127.0.0.1"
       serializationType="binary" port="7777"
       listener="com.magpie.quickstarts.v2.binary.UpheadPayloadListener" />
    
       <!--service配置項部分變化
       新增:
        throttleType      (選填)爲遏流類型 ,qps爲訪問1s內訪問次數的限制,flow爲1s內訪問報文大小的限制 (注: 需要在protocol中指定 version="2.0")
        throttleValue     (選填)爲遏流的閾值,qps模式下單位爲次/s,flow模式下單位爲bytes/s (注: 需要在protocol中指定 version="2.0")
        serviceVersion    (選填) 同一個服務名可以設置多個版本,不同版本的實現類不同 (注: 需要在protocol中指定 version="2.0")
        local              (選填) 在zk環境下,啓動時是否使用本地的配置內容。 默認爲false 即使用zk上修改過的數據。
        oneway            (選填)在zk環境下,客戶端不需要配置此項,以服務端配置的爲準
        weight            (選填)在zk環境下,客戶端不需要配置此項,以服務端指定自己的權重
        timeout           (選填)在zk環境下,如果客戶端想使用服務端設置的timeout,則將自己的timeout設置爲-1即可,否則以客戶端定義的爲準
       更新:
        serviceId          在protocol中指定 version="2.0" 時,支持變長
        注意:  在使用zookeeper時,非rpc服務的serviceId請以appName_serviceId的形式命名,以防止在zookeeper中註冊時產生衝突。
       -->
    
       <!-- 暴露magpie-binary服務A -->
       <service serviceId="appname_binaryServiceA" protocol="magpieBinaryProtocol" throttleType="qps" throttleValue="10000"
       oneway="false" timeout="5000" weight="100" description="this is binaryServiceA" />
    
       <!-- 暴露magpie-binary服務A的2.0版本服務,需要maogpie2.0協議支持-->
       <service serviceId="appname_binaryServiceA" protocol="magpieBinaryProtocol" throttleType="qps" throttleValue="10000"
       oneway="false" timeout="5000" weight="100" description="this is binaryServiceA" serviceVersion="2.0" />
    
       <!-- 暴露magpie-binary服務B -->
       <service serviceId="appname_binaryServiceB" protocol="magpieBinaryProtocol"
       oneway="false" timeout="5000" weight="100" description="this is binaryServiceB" />
    
       <!-- 暴露uphead服務 -->
       <service serviceId="appname_upheadService" protocol="upHeadProtocol"
       oneway="false" timeout="5000" weight="100" description="this is upheadService" />
    
       <!-- 暴露magpie-rpc服務 -->
       <service serviceId="fooService" protocol="magpieRpcProtocol"
       interfaceClass="com.magpie.quickstarts.v2.rpc.Foo" implClass="com.magpie.quickstarts.v2.rpc.FooImpl"
       oneway="false" timeout="5000" weight="100" description="this is foo rpc service" />
    
  3. 啓動magpie

    public class Main {
    public static void main(String args) {
    // 調用Magpie API啓動
    // 啓動後,magpie框架會自動讀取並解析magpie.xml,並讀取其中的<protocol>,隨後綁定到ip:port
    // 如果是web應用,則start動作可以寫到ServletContextListener中,隨中間件一起啓動。
    MagpieBootStrap.getBootStrap().start();
    }
    }

  4. 編寫MagpieBinaryPayloadListener

定義回調函數,供magpie框架調用。

注:僅magpie binary服務需要,RPC服務不用,RPC中接口和實現類的配置請參考magpie1.0中的RPC配置。

public class MagpieBinaryPayloadListener extends AbstractServerPayloadListener {
      @Override
      public byte[] handle(String serviceId, String serviceVersion, byte[]() requestBytes, DcType sourceDc) {
          System.out.println("serviceId:" + serviceId + ", serviceVersion:" + serviceVersion + ", from" + sourceDc.getText());

          if ("appname_binaryServiceA".equals(serviceId)) {
          // do with binaryServiceA
          } else if ("appname_binaryServiceB".equals(serviceId)) {
          // do with binaryServiceB
          }

          return ("magpie_binary" + "|" + serviceId + "|" + serviceVersion + "|" + new String(requestBytes)).getBytes();
      }
}

Client引用一個遠端服務步驟¶

  1. 新建magpie.xml,放入$CLASSPATH/appCfg/中或者$CLASSPATH/中,請看下面的示例中的註釋:

       <?xml version="1.0" encoding="UTF-8"?>
       <magpie xmlns='uri:unionpay:magpie:2.0'>
       <!-- 應用基本信息 -->
       <application name="APP" description="unionpay's consumer" />
    
       <!-- 註冊中心的cluster  開發環境zookeeper地址請聯繫公共組件室獲取-->
       <registry addresses="172.18.*.*:2181,172.18.*.*:2181,172.18.*.*:2181" />
    
       <!-- 遠程監控cluster monitor地址從zk中動態獲取  選填
       <monitor monitorInterval="5000" /> -->
    
        <!--
        其他屬性請參考 magpie 1.* 配置文件
        新增:
           dc: 指定調用的數據中心,優先使用配置在前面的數據中心,後面的爲災備中心,該配置對應server端application中配置的dc,默認爲只訪問sh 
           dcAutoSwitch: 默認爲false。true表示,在以上dc配置中,主中心的配置不可用時可自動切換到災備中心;false表示不自動切換到災備中心。該配置項的優先級低於monitor中的配置,當monitor中指定災備切換時,該配置項將不起作用。
        -->
       <reference serviceId="appname_binaryServiceA" failStrategy="failover"
       retries="2" dc="sh,bj"/>
    
       <reference serviceId="appname_binaryServiceB" failStrategy="failover"
       retries="2" />
    
       <reference serviceId="appname_upheadService" failStrategy="failover"
       retries="2" />
    
       <reference retries="2" serviceId="fooService" failStrategy="failover" interfaceClass="com.magpie.quickstarts.v2.rpc.Foo" />
       </magpie>
    
  2. 啓動magpie並調用:(RPC客戶端調用方法請參考magpie1.0)

       public static void main(String[]() args) {
           System.setProperty(Constants.WAIT_ALL_URLS_CONNECTED, "true");
           // 調用Magpie API啓動
           // 啓動後,magpie框架會自動讀取並解析magpie.xml,並讀取其中的<reference>,隨後主動與<reference>中指定的ip:port建立長鏈接
           // 如果是web應用,則start動作可以寫到ServletContextListener中,隨中間件一起啓動。
           MagpieBootStrap.getBootStrap().start();
           try {
               System.out.println(new String(ServiceRegistry.getService("appname_binaryServiceA","2.0").call("hi".getBytes())));
               System.out.println(new String(ServiceRegistry.getService("appname_binaryServiceB").call("hi".getBytes())));
               System.out.println(new String(ServiceRegistry.getService("appname_upheadService").call("hi".getBytes())));
           } catch (RemotingException e) {
               e.printStackTrace();
           }
               System.out.println(ServiceRegistry.getService(Foo.class).sayHello("xx"));
       }
    

Magpie2與spring framework集成¶
server暴露服務步驟¶

  1. 在 log4j.properties 中爲magpie設置日誌級別,示例:

     log4j.rootLogger=INFO
    
     log4j.logger.org.jboss.netty=INFO, stdout, R
     log4j.logger.com.unionpay.magpie=INFO, stdout, R
    
     log4j.appender.stdout=org.apache.log4j.ConsoleAppender
     log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
     log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
    
     log4j.appender.R=org.apache.log4j.RollingFileAppender
     log4j.appender.R.File=/tmp/magpie2-quickstarts-provider.log
     log4j.appender.R.MaxFileSize=20MB
     log4j.appender.R.MaxBackupIndex=20
     log4j.appender.R.layout=org.apache.log4j.PatternLayout
     log4j.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
    
  2. 新建spring的配置文件,應用的$CLASSPATH/中,請看下面的示例中的註釋:

     <?xml version="1.0" encoding="UTF-8"?>
    
     <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:magpie="http://www.unionpay.com/schema/magpie"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.unionpay.com/schema/magpie
                http://www.unionpay.com/schema/magpie/magpie.xsd"
         default-lazy-init="false">
    
         <magpie:magpie>
    
             <!-- 應用基本信息 -->
             <magpie:application name="test" heartbeatInterval="60000"
                 description="我是應用y,我是provider" dc="sh" contact="name;phone;email"/>
    
             <!-- 遠程監控cluster -->
             <magpie:registry addresses="172.18.*.*:2181,172.18.*.*:2181,172.18.*.*:2181" />
    
             <!-- 遠程監控cluster  收集調用的實時狀態, 選填
             <magpie:monitor  />
             -->
             <!-- 不同種協議,應使用不同的端口 -->
             <magpie:protocol id="magpieBinaryProtocol" codec="magpie_binary"
                 serializationType="binary" ip="127.0.0.1" port="5555"
                 listener="com.magpie.quickstarts.v2.binary.MagpieBinaryPayloadListener" />
    
             <magpie:protocol id="magpieRpcProtocol" codec="magpie_rpc"
                 serializationType="hessian2" ip="127.0.0.1" port="6666" />
    
             <magpie:protocol id="upHeadProtocol" codec="uphead"
                 ip="127.0.0.1" serializationType="binary" port="7777"
                 listener="com.magpie.quickstarts.v2.binary.UpheadPayloadListener" />
    
    
             <!-- 暴露magpie-binary服務A -->
             <magpie:service serviceId="binaryServiceA"
                 serviceVersion="1.0" protocol="magpieBinaryProtocol" oneway="false"
                 timeout="5000" weight="100" description="this is binaryServiceA" />
    
             <!-- 暴露magpie-binary服務B -->
             <magpie:service serviceId="binaryServiceB" protocol="magpieBinaryProtocol" serviceVersion="1.0"
                 oneway="false" timeout="5000" weight="100" description="this is binaryServiceB" />
    
             <!-- 暴露uphead服務 -->
             <magpie:service serviceId="upheadService" protocol="upHeadProtocol"
                 oneway="false" timeout="5000" weight="100" description="this is upheadService" />
    
             <!-- 暴露magpie-rpc服務 -->
             <magpie:service serviceId="fooService" protocol="magpieRpcProtocol"
                 interfaceClass="com.magpie.quickstarts.v2.rpc.Foo"
                 implClass="com.magpie.quickstarts.v2.rpc.FooImpl"
                 oneway="false" timeout="5000" weight="100" description="this is foo rpc service" />
    
         </magpie:magpie>
    
     </beans>
    
  3. 啓動Magpie

     public class SpringMain {
    
         public static void main(String[] args) {
             // 調用Spring applicationcontext初始化來啓動magpie
             // 啓動後,magpie框架會自動讀取並解析spring-applicationcontext.xml中的magpie配置項來完成初始化,並讀取其中的<protocol>,隨後綁定到ip:port
             // 如果是web應用,則啓動可以使用spring框架提供的listener來初始化spring的applicationcontext容器。
             ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-applicationcontext.xml");
         }
     }
    
  4. 僅magpie binary服務需要,RPC服務不用編寫MagpieBinaryPayloadListener,定義回調函數,供magpie框架調用。

     public class MagpieBinaryPayloadListener extends AbstractServerPayloadListener {
    
         @Override
         public byte[] handle(String serviceId, String serviceVersion, byte[] requestBytes) {
    
             System.out.println("serviceId:" + serviceId + ", serviceVersion:" + serviceVersion);
    
             if ("binaryServiceA".equals(serviceId)) {
                 // do with binaryServiceA
    
             } else if ("binaryServiceB".equals(serviceId)) {
                 // do with binaryServiceB
             }
    
             return ("magpie_binary" + "|" + serviceId + "|" + serviceVersion + "|" + new String(requestBytes)).getBytes();
         }
     }
    

client引用一個遠端服務步驟¶

  1. 新建spring配置文件,放入應用的$CLASSPATH中,請看下面的示例中的註釋:

     <?xml version="1.0" encoding="UTF-8"?>
    
     <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:magpie="http://www.unionpay.com/schema/magpie"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.unionpay.com/schema/magpie
                http://www.unionpay.com/schema/magpie/magpie.xsd">
    
    
    
         <magpie:magpie>
    
             <!-- 應用基本信息 -->
             <magpie:application name="spring" heartbeatInterval="-1"
                 description="spring's provider" dc="sh" />
    
             <!-- 註冊中心的cluster -->
             <magpie:registry addresses="172.18.*.*:2181,172.17.*.*:2181,172.17.*.*:2181" />
    
             <!-- 遠程監控cluster  選填
             <magpie:monitor />-->
    
             <magpie:reference serviceId="binaryServiceA"
                 failStrategy="failover" retries="2" />
             <magpie:reference serviceId="binaryServiceB"
                 failStrategy="failover" retries="2" />
             <magpie:reference serviceId="upheadService" 
                 failStrategy="failover" retries="2" />
             <magpie:reference serviceId="fooService"
                 failStrategy="failover" retries="2" interfaceClass="com.magpie.quickstarts.v2.rpc.Foo" />
    
         </magpie:magpie>
    
         <!-- 可以通過applicationcontext來獲取bean供業務邏輯調用 -->
         <bean id="binaryServiceA"
             class="com.unionpay.magpie.config.spring.factory.ServiceReferenceFactoryBean">
             <property name="serviceId" value="binaryServiceA" />
         </bean>
    
         <bean id="binaryServiceB"
             class="com.unionpay.magpie.config.spring.factory.ServiceReferenceFactoryBean">
             <property name="serviceId" value="binaryServiceB" />
         </bean>
    
         <bean id="upheadService"
             class="com.unionpay.magpie.config.spring.factory.ServiceReferenceFactoryBean">
             <property name="serviceId" value="upheadService" />
         </bean>
    
         <bean id="fooService"
             class="com.unionpay.magpie.config.spring.factory.ServiceReferenceFactoryBean">
             <property name="interfaceName"
                 value="com.magpie.quickstarts.v2.rpc.Foo" />
         </bean>
     </beans>
    
  2. 啓動magpie並調用

     public static void main(String[] args) {    
    
         // 調用Spring applicationcontext初始化來啓動magpie
         // 啓動後,magpie框架會自動讀取並解析spring-applicationcontext.xml中的magpie配置項來完成初始化
         // 如果是web應用,則啓動可以使用spring框架提供的listener來初始化spring的applicationcontext容器。
         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-applicationcontext.xml");
    
         try {
             System.out.println(new String(((ServiceController)applicationContext.getBean("binaryServiceA")).call("hi".getBytes())));
    
             System.out.println(new String(((ServiceController)applicationContext.getBean("binaryServiceB")).call("hi".getBytes())));
    
             System.out.println(new String(((ServiceController)applicationContext.getBean("upheadService")).call("hi".getBytes())));
    
             System.out.println(((Foo)applicationContext.getBean("fooService")).sayHello("hi"));
         } catch (RemotingException e) {
             e.printStackTrace();
         }        
    
     }
    

災備說明¶
災備配置方法¶
服務需標識自己所在的數據中心

配置方法:在服務端的標籤中,添加屬性dc。dc可設置爲sh或是bj(sh爲上海數據中心,bj爲北京數據中心;必須且只能設置一個數據中心,默認爲dc=“sh”)。

客戶端在引用服務時,需要指定所調用服務的數據中心

配置方法:在標籤中,添加屬性dc。dc可以設置爲sh或是bj或是sh,bj(先後順序指定了誰做主數據中心,誰做災備數據中心。 默認dc=“sh”)。

災備切換方式相關說明和解釋¶
災備切換存在兩種方式 1. 無console 2. 有console

無magpie-console
中 dc=“sh,bj” dcAutoSwitch=false 這種方式,sh爲主中心,bj爲災備中心,且不允許自動切換中心,即當上海中心不可用時,也不會自動切換到北京中心。
中 dc=“sh,bj” dcAutoSwitch=true 這種方式,sh爲主中心,bj爲災備中心,且允許自動切換中心,即當上海中心不可用時,自動切換到北京中心,上海中心可用時,自動切換回上海中心
使用mapgie-console (dcAutoSwitch失效)
切至北京:將服務調用切換到北京
切至上海:將服務調用切換到上海
全部啓用:上海不可用時,北京接替;上海可用時,切回上海
全部禁用:上海北京都不能調用
應用及服務命名規範¶
問題¶
Magpie2 新增了服務的註冊和發現功能。 服務端在zookeeper上將自己的服務實例註冊在節點上,客戶端watch該節點的變化,從而達到服務實例的動態上下線。 但是由於服務的註冊和發現是開放性的,如果當兩個無關項目的服務出現重名,則會同時將自己的實例註冊在該服務節點下,而訂閱該服務的客戶端並不能區分該服務下的實例哪個是正確的,從而在調用時出現錯誤。

規範準則¶
RPC 服務名 RPC 在命名時請遵從以下規範:

com.unionpay.系統名.子系統名.應用名.子應用名.服務名
命名舉例:

com.unionpay.sysName.subSysName.appName.subAppName.***.service.HelloService
Magpie不對該命名進行校驗, 命名最好根據實際情況,儘量豐富服務的層級結構以示區分

非RPC服務名

因爲不存在包名約束, binary服務名的重名情況可能比較嚴重,會同時出現很多名如LoginService或是UserService的服務,導致相互影響。 magpie目前在啓動時會對binary的服務進行簡單的約束檢查即需要爲 ****_serviceName 。 至少需要一個下劃線區分,根據系統或應用的實際情況,層級越多越好。

同時由於magpie c的組件 MGW 對服務名的長度存在長度限制(31字節),所以在命名時需合理安排長度。
非RPC 在命名時請遵從以下規範:

系統_子系統_項目_子項目_服務名
命名舉例:

tsm_sys_helloService
tsm_sys_app_helloService
注: 爲了兼容未升級的客戶端通過配置url調用, 命名校驗不通過的服務依然可以正常啓動,但是會有error提示,且不能在zookeeper註冊和訂閱服務。

Application 命名
Mgpie中application標籤中的 name 爲必填項, 此項目對服務的集成管理和災備切換具有意義,命名時需要注意規範。 APP命名可以採取如下方式:

系統名_子系統名_應用名_子應用名
如:

SYS_APP_SUBAPP
儘量豐富自身的層級便於區分和管理

Contact 聯繫方式 請填寫application標籤中的contact屬性,格式爲 name;phone;email 此項爲必填項,方便通過控制檯對註冊的服務進行管理和維護。
申請與檢查¶
在開發階段 我們會部署開發環境的zk集羣, 在獲取集羣地址前,請先向公共組件團隊提出申請進行檢查,或者使用我們提供的工具(後期會部署在開發環境)在線進行檢查。 1.自身的APP命名 2.發佈的RPC的服務包名 3.發佈的binary服務名 檢查確認該APP或是服務名是否存在!! 檢查已存在服務的contact是否是提交人本人!!

聯調與性能測試報告¶
點擊 這裏 下載

統計信息¶
最新統計可參考:http://172.17.254.218:3000/documents/88

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章