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

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