Skip to content

zh_userguide

Ray edited this page Nov 10, 2022 · 19 revisions

基本介绍

Motan是一套基于java开发的RPC框架,除了常规的点对点调用外,Motan还提供服务治理功能,包括服务节点的自动发现、摘除、高可用和负载均衡等。Motan具有良好的扩展性,主要模块都提供了多种不同的实现,例如支持多种注册中心,支持多种rpc协议等。

架构概述

Motan中分为服务提供方(RPC Server),服务调用方(RPC Client)和服务注册中心(Registry)三个角色。

  • Server提供服务,向Registry注册自身服务,并向注册中心定期发送心跳汇报状态;
  • Client使用服务,需要向注册中心订阅RPC服务,Client根据Registry返回的服务列表,与具体的Sever建立连接,并进行RPC调用。
  • 当Server发生变更时,Registry会同步变更,Client感知后会对本地的服务列表作相应调整。

三者的交互关系如下图:

模块概述

Motan框架中主要有register、transport、serialize、protocol几个功能模块,各个功能模块都支持通过SPI进行扩展,各模块的交互如下图所示:

register

用来和注册中心进行交互,包括注册服务、订阅服务、服务变更通知、服务心跳发送等功能;Server端会在系统初始化时通过register模块注册服务,Client端在系统初始化时会通过register模块订阅到具体提供服务的Server列表,当Server 列表发生变更时也由register模块通知Client。

protocol

用来进行RPC服务的描述和RPC服务的配置管理,这一层还可以添加不同功能的filter用来完成统计、并发限制等功能。

serialize

将RPC请求中的参数、结果等对象进行序列化与反序列化,即进行对象与字节流的互相转换;默认使用对java更友好的hessian2进行序列化。

transport

用来进行远程通信,默认使用Netty nio的TCP长链接方式。

cluster

Client端使用的模块,cluster是一组可用的Server在逻辑上的封装,包含若干可以提供RPC服务的Server,实际请求时会根据不同的高可用与负载均衡策略选择一个可用的Server发起远程调用。

在进行RPC请求时,Client通过代理机制调用cluster模块,cluster根据配置的HA和LoadBalance选出一个可用的Server,通过serialize模块把RPC请求转换为字节流,然后通过transport模块发送到Server端。

配置概述

Motan框架中将功能模块抽象为四个可配置的元素,分别为:

  • protocol:服务通信协议。服务提供方与消费方进行远程调用的协议,默认为Motan协议,使用hessian2进行序列化,netty作为Endpoint以及使用Motan自定义的协议编码方式。

  • registry:注册中心。服务提供方将服务信息(包含ip、端口、服务策略等信息)注册到注册中心,服务消费方通过注册中心发现服务。当服务发生变更,注册中心负责通知各个消费方。

  • service:服务提供方提供的服务。使用方将核心业务抽取出来,作为独立的服务。通过暴露服务并将服务注册至注册中心,从而使调用方调用。

  • referer:服务消费方对服务的引用,即服务调用方。

Motan推荐使用spring配置rpc服务,目前Motan扩展了6个自定义Spring xml标签:

  • motan:protocol
  • motan:registry
  • motan:basicService
  • motan:service
  • motan:basicReferer
  • motan:referer

每种标签的详细含义请参考后文配置说明部分。全部参数清单请参考配置清单

使用Motan

Motan主要使用Spring进行配置,业务代码无需修改。关于在项目中使用Motan框架的具体步骤,请参考:快速入门

在使用Motan框架时,除了配置之外还需要注意工程依赖及Motan框架本身的异常处理。

工程依赖

Motan框架采用模块化设计,使用时可以按需依赖。目前的模块有:

  • motan-core Motan核心框架
  • motan-transport-netty
    基于Netty协议的长连接传输协议
  • motan-registry-consul
    Consul服务发现组件
  • motan-registry-zookeeper
    Zookeeper服务发现组件
  • motan-springsupport
    Spring标签解析相关功能

处理调用异常

  • 业务代码异常
    当调用的远程服务出现异常时,Motan会把Server业务中的异常对象抛出到Client代码中,与本地调用逻辑一致。

    注意:如果业务代码中抛出的异常类型为Error而非Exception(如OutOfMemoryError),Motan框架不会直接抛出Error,而是抛出包装了Error的MotanServiceException异常。

  • MotanServiceException
    使用Motan框架将一个本地调用改为RPC调用后,如果出现网络问题或服务端集群异常等情况,Motan会在Client调用远程服务时抛出MotanServiceException异常,业务方需要自行决定后续处理逻辑。

  • MotanFrameworkException
    框架异常,比如系统启动、关闭、服务暴露、服务注册等非请求情况下出现问题,Motan会抛出此类异常。

配置说明

协议与连接

介绍

Protocol用来配置Motan服务的协议。不同的服务适用不同的协议进行传输,可以自行扩展协议。

Motan协议

<motan:protocol name="motan" />

Motan默认的rpc协议为Motan协议,使用tcp长连接模式,基于netty通信。

负载均衡

Motan 在集群负载均衡时,提供了多种方案,缺省为 ActiveWeight,并支持自定义扩展。 负载均衡策略在Client端生效,因此需在Client端添加配置

目前支持的负载均衡策略有:

  • ActiveWeight(缺省)

    <motan:protocol ... loadbalance="activeWeight"/>
    

    低并发度优先: referer 的某时刻的 call 数越小优先级越高
    由于 Referer List 可能很多,比如上百台,如果每次都要从这上百个 Referer 获得最低并发的几个,性能有些损耗,因此 random.nextInt(list.size()) 获取一个起始的 index,然后获取最多不超过 MAX_REFERER_COUNT 的状态是 isAvailable 的 referer 进行判断 activeCount.

  • Random

    <motan:protocol ... loadbalance="random"/>
    

    随机选择。
    在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

  • RoundRobin

    <motan:protocol ... loadbalance="roundrobin"/>
    

    轮循选择,调用比较均匀

  • LocalFirst

    <motan:protocol ... loadbalance="localFirst"/>
    

    本地服务优先获取策略,对referers根据ip顺序查找本地服务,多存在多个本地服务,获取Active最小的本地服务进行服务。
    当不存在本地服务,但是存在远程RPC服务,则根据ActivWeight获取远程RPC服务
    当两者都存在,所有本地服务都应优先于远程服务,本地RPC服务与远程RPC服务内部则根据ActiveWeight进行

  • Consistent

    <motan:protocol ... loadbalance="consistent"/>
    

    一致性 Hash,相同参数的请求总是发到同一提供者

  • ConfigurableWeight

    <motan:protocol ... loadbalance="configurableWeight"/>
    

    权重可配置的负载均衡策略

容错策略

Motan 在集群调用失败时,提供了两种容错方案,并支持自定义扩展。 高可用集群容错策略在Client端生效,因此需在Client端添加配置 目前支持的集群容错策略有:

  • Failover 失效切换(缺省)

    <motan:protocol ... haStrategy="failover"/>
    

    失败自动切换,当出现失败,重试其它服务器。

  • Failfast 快速失败

    <motan:protocol ... haStrategy="failfast"/>
    

    快速失败,只发起一次调用,失败立即报错。

连接控制

  • 限制服务端连接池工作线程数

    <motan:protocol id="demoMotan" name="motan" maxWorkerThread="800" minWorkerThread="20"/>
    
  • 限制客户端对每个服务建立的连接数

    <motan:protocol name="motan" maxClientConnection="10" minClientConnection="2"/>
    

本地调用

<motan:protocol name="injvm" />

Injvm 协议是一个伪协议,它不开启端口,不发起远程调用,只在 JVM 内直接关联,但执行 Motan 的 Filter 链。

注册中心与服务发现

介绍

注册中心配置。用于配置注册中心的注册协议、地址端口、超时时间等。motan:registry包含以下常用属性:

  • name:标识配置名称
  • regProtocol:标识注册中心协议
  • address:标识注册中心地址

Motan支持使用多种Registry模块,使用不同注册中心需要依赖对应jar包。

使用Consul作为注册中心

<motan:registry regProtocol="consul" name="my_consul" address="consul_port:port"/>

使用Zookeeper作为注册中心

zookeeper为单节点

```xml
<motan:registry regProtocol="zookeeper" name="my_zookeeper" address="zookeeper_ip1:port"/>
```

zookeeper多节点集群  

```xml
<motan:registry regProtocol="zookeeper" name="my_zookeeper" address="zookeeper_ip1:port1,zookeeper_ip2:port2,zookeeper_ip3:port"/>
```

不使用注册中心

在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直联方式:

<motan:registry regProtocol="direct" name="directRegistry" port="8002" address="192.168.1.2" />

or

<motan:registry regProtocol="direct" name="directRegistry" address="192.168.1.2:8002,192.168.1.3:8002" />

使用Motan Mesh作为注册中心

详见使用MeshRegistry

服务提供方

介绍

定义提供给外部调用的接口,motan:service包含以下常用属性:

  • interface:标识服务的接口类名
  • ref:标识服务的实现类,引用具体的spring业务实现对象
  • export:标识服务的暴露方式,格式为“protocolId:port”(使用的协议及对外提供的端口号),其中protocolId:应与motan:protocol中的id一致
  • group:标识服务的分组
  • module:标识模块信息
  • basicService:标识使用的基本配置,引用motan:basicService对象

Motan在注册中心的服务是以group的形式保存的,一般推荐一个分组以机房+业务线进行命名,如yf-user-rpc。一个分组中包含若干的Service,一个Service即是java中的一个接口类名,每个Service下有一组能够提供对应服务的Server。

使用basicService简化配置

<motan:basicService .../>

rpc服务的通用配置,用于配置所有服务接口的公共配置,减少配置冗余。basicService包含以下常用属性:

  • id:标识配置项
  • export:标识服务的暴露方式,格式为“protocolId:port”(使用的协议及对外提供的端口号),其中protocolId:应与motan:protocol中的id一致
  • group:标识服务的分组
  • module:标识模块信息
  • registry:标识service使用的注册中心,与motan:registry中的name对应

motan:service可以通过以下方式引用基本配置。

<!-- 通用配置,多个rpc服务使用相同的基础配置. group和module定义具体的服务池。export格式为“protocol id:提供服务的端口” -->
<motan:basicService id="serviceBasicConfig" export="demoMotan:8002" group="motan-demo-rpc" module="motan-demo-rpc" registry="registry"/>
<!-- 通用配置,多个rpc服务使用相同的基础配置. group和module定义具体的服务池。export格式为“protocol id:提供服务的端口” -->
<motan:service interface="com.weibo.motan.demo.service.MotanDemoService" ref="demoServiceImpl" basicService="serviceBasicConfig"/>

motan:service中的basicService属性用来标识引用哪个motan:basicService对象,对于basicService中已定义的内容,service不必重复配置。

服务调用方

介绍

调用方对象,motan:referer包含以下常用属性:

  • id:标识配置项
  • group:标识服务的分组
  • module:标识模块信息
  • protocol:标识referer使用的协议,与motan:protocol中的name对应,默认为Motan协议
  • registry:标识referer使用的注册中心,与motan:registry中的name对应
  • basicReferer:标识使用的基本配置,引用motan:basicReferer对象

Client端订阅Service后,会从Registry中得到能够提供对应Service的一组Server,Client把这一组Server看作一个提供服务的cluster。当cluster中的Server发生变更时,Client端的register模块会通知Client进行更新。

使用basicReferer简化配置

调用方基础配置。用于配置所有服务代理的公共属性。

  • id:标识配置项
  • group:标识服务的分组
  • module:标识模块信息
  • protocol:标识referer使用的协议,与motan:protocol中的name对应,默认为Motan协议
  • registry:标识referer使用的注册中心,与motan:registry中的name对应

motan:referer可以通过以下方式引用基本配置。

<!-- 通用referer基础配置 -->
<motan:basicReferer id="clientBasicConfig" group="motan-demo-rpc" module="motan-demo-rpc"  registry="registry" protocol="motan"/>

<!-- 具体referer配置。使用方通过beanid使用服务接口类 -->
<motan:referer id="demoReferer" interface="com.weibo.motan.demo.service.MotanDemoService"  basicReferer="clientBasicConfig"/>

motan:referer中的basicService属性用来标识引用哪个motan:basicReferer对象,对于basicReferer中已定义的内容,service不必重复配置。

配置清单

详细内容请参考配置清单

全局配置文件

从1.2.1版本后motan支持通过resource根路径下的motan.properties文件来设置一些全局级别的配置,motan内部主要用来指定全局开关的默认值。

常用功能介绍

mock测试

Motan提供两种mock方式,一种是通过Filter机制进行mock,另一种是在protocol协议层进行mock,两种方式都可以分别在server端和client端生效。

使用ServiceMockFilter进行mock

ServiceMockFilter使用方式为

1、配置filter="mock" , 加载ServiceMockFilter

2、设置mock="***",其中的值类型

1)、false:不使用mock

2)、return某个类型值: 包括returnempty、returnnull、returntrue、returnfalse、return***,其中***代表string类型的值。

3)、mock类全名:mock类必须为声明的interface的实现类,并且有默认构造函数。

3、client进行mock时,只对请求进行mock,服务发现必须能找到至少一个server,可以通过directUrl配置一个不存在的服务,例如,check=false,directUrl="127.0.0.1:8002“

具体实现可以参考ServiceMockFilter类

使用mock协议

方式如下:

1、实现自定义mock协议类,继承AbstractMockRpcProtocol,实现processRequest方法(自定义mock逻辑)。

2、添加spi声明 @SpiMeta(name = "your_mock_protocol") ,在META-INF/services/com.weibo.api.motan.rpc.Protocol文件中添加mock协议类的类全名。spi扩展方式见编写Motan扩展

3、配置motan:protocol 为SpiMeta中声明的名字,即name=your_mock_protocol,如果在client端mock,就在basicReferer或Referer中设置对应protocl;如果在server端mock,则在export中配置${mock协议的id}:port

具体实现可以参考AbstractMockRpcProtocol类

使用MeshRegistry

Mesh Registry是把Motan Mesh的Agent当作注册中心来使用的一种RPC姿势,通过Mesh Agent来提供服务的注册、发现能力。主要应用在Java Motan服务切换到Mesh服务的场景。

使用Mesh Registry可以简单的通过更换Motan的registry配置,来方便的切换到Mesh体系,并且提供backup降级能力,可以支持手动、自动降级为非mesh的模式。

Mesh Registy可以提供以下功能:

  • 动态注册、订阅能力
  • 手动、自动降级能力
  • agent存活探测能力

动态注册、订阅能力

当Mesh Registry配置了dynamic=true参数时,支持通过 Mesh Agent进行动态服务注册、订阅。

动态注册、订阅时,agent可以不用提前配置好对应服务,java服务在启动时,会调用agent的管理端口,动态进行服务的注册与订阅。 动态注册、订阅的能力需要agent相应版本支持。如果agent不支持动态能力,则该功能无效。

手动、自动降级能力

当Mesh Registry配置了proxy Registry时,能够支持降级能力,降级后将使用proxy registy注册、订阅能力。

降级分为手动降级和自动降级,手动降级可以在任意时刻操作开关来回退到使用proxy registry的状态。自动降级则会开启针对agent的存活探测,当检测到agent不可用时,自动切换到使用proxy registry。

自动降级只针对client侧使用,防止agent挂掉时,所有调用请求都失败带来的影响。server侧如果agent挂掉时,一般会触发client的熔断机制,因此不需要进行自动降级。

agent存活探测能力

与自动降级功能相配合,MeshRegistry支持对agent进行存活探测,探测的方式为针对agent 转发端口定期进行心跳请求探活,当心跳请求连续失败3次时会自动降级为使用proxy registry发现回来的服务节点。

只有正确配置了proxy registry的情况下,才会开启agent存活探测。

存活探测能力提供了单独的降级开关,降级后会认为agent持续可用,不会在进行心跳探测。

Java项目使用MeshRegistry

1、使用Mesh Registry 首先需要引入对应依赖。

        <dependency>
            <groupId>com.weibo</groupId>
            <artifactId>motan-registry-weibomesh</artifactId>
            <version>1.1.10</version>
        </dependency>

2、在Motan配置中增加Mesh Registry配置 Mesh Registry的配置项中,regProtocol必须为weibomesh, address为mesh agent的转发端口。

如果需要配置proxy registry,可以配置参数proxyRegistry值为被代理的registry的bean id。

如果需要支持agent动态注册、订阅能力,可以配置参数dynamic值为true。

3、在motan service或者referer中配置registry为上面配置 Mesh Registry。

样例:

    <motan:registry regProtocol="vintage" id="ori_registry" name="registry" address="xxx.vintage.com:80"/>
    <motan:registry regProtocol="weibomesh" id="mesh_registry" address="localhost:9981?copy=3&amp;mport=8002" proxyRegistry="ori_registry" dynamic="true"/>

    <motan:referer id="motanDemoReferer" registry="mesh_registry" .../>
    
    <motan:service id="motanDemoService" registry="mesh_registry" .../>

参数配置说明

Mesh Registry配置项中,address参数中支持配置一些特定参数,这些参数会在Mesh registry中生效。需要特别注意,当需要传递的参数中包括,&;等有特殊意义的字符时,需要进行url encode编码,比如,需要写成%2C

包括xml中可以直接配置的proxyRegistrydynamic参数也可以通过address 参数来进行设置,方便使用占位符方式配置的服务进行Mesh Registry切换。

常用的参数有:

  • proxyRegistry:同配置项中的同名参数。指定backup时要使用的代理注册中心
  • dynamic:同配置项中的同名参数。为true时会通过agent管理端口动态注册、订阅服务。
  • mport:mesh agent的管理端口。未设置此参数时,Mesh Registry会使用默认的8002作为agent的管理端口。只有在agent使用非默认管理端口时需要配置此参数。
  • copy:使用agent 节点作为服务可用节点通知时,返回的agent节点副本数。默认值为3,即通过mesh registry订阅服务时,默认会通知给订阅Listener 3个agent节点URL。副本数量影响java服务于agent建立的连接数以及吞吐量。
  • fusingThreshold:client侧针对agent节点的熔断阈值。agent节点与一般的服务节点不同,一般agent节点副本数会比较少,当出现异常请求时,默认的10次熔断阈值并不适合,因此默认情况下会自动将agent节点熔断阈值调整为100,如果此值不满足业务需求时,可以通过这个参数进行配置。
  • filter:指定agent中代理的节点需要使用哪些filter。参数的值为af_加上agent中的filter的name。例如agent配置中,filter名为accessLog,则词参数配置的值应为af_accessLog。另外只有agent中支持的filter才能生效。
  • meshRegistryName:指定mesh agent配置中要使用的registry的名称。如果没有指定此参数,会用proxy registry的protocol、host、port来匹配

最佳实践

  1. 调试时可以使用动态注册、订阅能力,一般上线前建议在agent配置中配置好对应service,线上不使用动态注册、订阅能力。

  2. 如果需要使用动态注册、订阅时,agent中需要配置好对应的registry,agent目前暂不支持动态添加registry

分组混打功能

分组混打的使用场景

一个service可以有多个分组(group),当使用指令进行流量切换时,切换的比例是分组间流量比例,比如group0:2,group1:3表示group0分组与group1分组收到的流量是2:3。

但是很多时候分组内的服务节点数量并不均衡,比如,group0有10台server节点,而group1只有5台,那么从单节点上看,每个server收到的流量并不均匀。虽然可以通过调整分组比例来达到均匀,比如流量指令调整为group0:2,group1:1,但是当其中一个分组进行动态扩容时,又会导致节点维度的不均匀。

为了满足业务方单节点流量均匀的需求,增加了分组混打功能,所谓分组混打功能是指多个分组内节点实例获得的流量基本均匀。

分组混打的使用方式

分组混打可以分为静态和动态两种方式,

所谓静态,是指业务方希望常态进行多个分组间的流量混打,因此静态混打是通过启动时的配置声明的;

所谓动态,是指业务方不希望常态进行多个分组混打,日常时仍然各分组间独立调用,但是当出现网络异常等情况希望在分组间切换流量时,临时使用分组混打来应对流量高峰。动态混打是通过流量切换指令系统来动态控制的。

静态流量混打

静态流量混打在motan referer配置中增加了一个mixGroups参数,用来指定需要和哪些分组进行混打。比如:

   <motan:basicReferer group="group0" mixGroups="group1,group2" ... />

这个配置表明,这个refer是属于group0分组,混打group1和group2分组,也就是这3个分组的所有节点会当做一个cluster来使用。由于自身分组是group0,因此会受group0分组的指令控制,在需要改变默认流量行为时,可以通过针对group0的流量指令来进行。动态流量指令的优先级大于静态的mixGroups。

动态流量混打

动态流量混打就是利用现有的流量控制指令,为便于理解以及为了保证与现有流量指令的兼容性,当需要流量指令进行分组混打时,指定分组而不指定分组间比例,就视为分组混打。

比如,给group0分组下达如下的流量指令

{
	"clientCommandList" : [
		{
			"index": 1,
			"version": "1.0",
			"dc": "yf",
			"commandType": 0,
			"pattern": "*",
			"mergeGroups": [
				"group0",
				"group1"
			],
			"routeRules": [],
			"remark": "group0,group1流量混打"
		}
	]
}

表示针对group0分组下的所有service都进行group0和group1分组的分组混打。需要注意,必须所有分组都不指定权重时,才会被视为分组混打。如果只有个别分组没有指定权重,则没指定权重的分组会使用默认权重1。

如果不想使用分组混打,仍然想使用分组间比例1:1,则可以显示指定分组权重,如下

"mergeGroups": [
	"group0:1",
	"group1:1"
]

运维及监控

优雅的停止服务

Motan支持在Consul、ZooKeeper集群环境下优雅的关闭节点,当需要关闭或重启节点时,可以先将待上线节点从集群中摘除,避免直接关闭影响正常请求。

待关闭节点需要调用以下代码,建议通过servlet或业务的管理模块进行该调用。

MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, false)

管理后台

管理后台主要包括RPC服务查询、流量切换、Motan指令设置等功能,需使用ZooKeeper作为注册中心

管理后台独立于Motan其他部分,可单独部署

管理后台安装

  1. 配置

    修改配置文件application.properties,配置注册中心类型(zookeeper, consul)及注册中心地址,默认不使用数据库

    默认的登录用户及权限如下:

     管理员:用户名admin 密码admin
     访客:用户名guest 密码guest
    

    若需使用历史操作查询功能,则需配置数据库:

  • 数据库表结构位于motan-manager.sql,可直接导入

  • 数据库配置地址位于application.properties

  • 修改 MotanManagerApp 注解 @ImportResource(locations = {"classpath:spring-security.xml"}) 为 +@ImportResource(locations = {"classpath:spring-mybatis.xml", "classpath:spring-security.xml"})

  1. 启动

    motan/motan-manager/ 下执行 mvn package, 然后 java -jar target/motan-manager.jar

管理后台使用

RPC服务查询

查询指定group的所有service状态,包括正常提供服务的Server和正在调用的Client

注:Consul注册中心暂不支持Client查询

步骤:

  • 在导航栏选择RPC服务查询,进入RPC服务查询页面

  • 下拉列表中选择要查询的服务所在的分组,如motan-demo-rpc,点击查询按钮

流量切换(需要管理员权限)

对指定服务根据分组或ip地址进行动态流量调整

步骤:

以下示例演示将来自motan-demo-rpc分组中所有服务的流量切换到motan-demo-rpc2分组中

  • 在导航栏选择流量切换,进入流量切换页面

  • Step1:

    来源流量的RPC分组列表中选择需要切换流量的Service所在的分组,如motan-demo-rpc

    服务列表中*表示所有服务,也可输入服务名称,语法见服务名语法,点击Next

  • Step2:

    目标流量的RPC分组列表中选择目标流量分组,如motan-demo-rpc2

    流量权重分配中根据需要按比例分配(可选范围是[0,100]),这里输入01,表示将来自motan-demo-rpc的流量全部转入motan-demo-rpc2,点击Next

  • Step3:(可选)若需根据具体IP调整流量,可在此配置

    RPC Client中输入来源流量的ip,RPC Server中输入目标流量的ip,点击添加后将在路由规则结果中显示

    也可在路由规则结果中手动输入路由规则,路由规则见路由规则语法,点击Next

  • Step4:指令预览

    功能暂未启用,点击Finish完成流量切换操作

服务名语法
  • 类名支持[a-zA-Z0-9_$.*]

  • 运算符支持 () ! & |,优先级由高到低

  • 复杂示例如下

    (com.weibo.User* & !com.weibo.UserMapping) | com.weibo.Status*
    # 匹配com.weibo下以User开头的不包括UserMapping的所有服务,或以Status开头的所有服务
    
路由规则语法
  • 必须包含to关键字,to左右两边分别为rpc client和rpc server的ip表达式,示例如下

    * to 10.75.1.*
    10.75.2.* to 10.73.1.*
    * to !10.75.1.1
    

指令管理

对注册中心下的所有指令信息进行增删改查操作

步骤:

  • 在导航栏选择指令查询,进入指令查询页面

  • 指令修改删除操作需要管理员权限

操作记录查询(需要管理员权限)

查询指令增删改查记录

步骤:

  • 在导航栏选择操作记录查询,进入操作记录查询

日志说明

Motan会打印三种类型的日志,帮助运维人员监控系统状态。

请求类日志

通过motan:service或motan:referer的accessLog属性来配置,基本格式如下:

"accesslog" - date - side - local_application_module - localip - interface - method_name - parameter_name - to_ip - remote_application_module - result - request_id - process_time_mills (分隔符为"|")

异常类日志

请参考 错误码及异常日志说明

统计类日志

所有请求的统计:

[motan-totalAccessStatistic] total_count: 32565 slow_count: 26 biz_excp: 0 other_excp: 2 avg_time: 1.93ms biz_time: 0.94ms avg_tps: 1085
total_count: 30s 内总请求数
slow_count:30s 内慢请求数(超过 50ms 算 slow)
biz_excp: 30s 内业务处理异常的总数
other_excp: 30s 其他异常的总数
avg_time: 所有接口的平均响应时间(网络传输+序列化+service 端处理)
biz_time: 所有接口的 service 端的业务处理时间(不包含序列化和网络传输)
avg_tps:平均 tps
注:上面是基于 client 端为维度的统计,service 端也有,其中 avg_time 便是业务处理时间,biz_time 为 0。

单方法的统计:

[motan-accessStatistic] item: injvm://cn.sina.api.data.service.GroupService.getGroupMemberCounters(long,long) total_count: 0 slow_count: 0 biz_excp: 0 other_excp: 0 avg_time: 0.00ms biz_time: 0.00ms avg_tps: 0 max_tps: 0 min_tps: 0
total_count: 30s 该接口的请求数,
slow_count: 30s 内该接口的慢请求数 (超过 50ms 的算 slow) ,
biz_excp: 30s 内该接口业务处理异常的总数,
other_excp: 30s 该接口其他异常的总数,
avg_time: 平均响应时间(网络传输+序列化+service 端处理),
biz_time: service 端的业务处理时间(不包含序列化和网络传输) ,
avg_tps:平均 tps,
max_tps: 最大的 TPS,
min_tps: 最小的 TPS

内存统计:

[motan-memoryStatistic] 1954.67MB of 7987.25 MB (24.5%) used

性能测试

Motan源码中提供了性能测试框架,便于使用者进行性能评估,源码请参考https://github.com/weibocom/motan/tree/master/motan-benchmark

以下是我们测试的结果:

测试环境

硬件配置

 Server端:
 CPU:model name:Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz,cache size: 15360 KB,processor_count : 24
 内存:16G
 网络:千兆网卡
 硬盘:300GB
 
 Client端:
 CPU:model name: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz,cache size:15360 KB,processor_count : 24
 内存:16G
 网络:千兆网卡
 硬盘:300GB

软件配置

 JDK版本:
 java version "1.7.0_75"
 OpenJDK Runtime Environment (rhel-2.5.4.2.el7_0-x86_64 u75-b13)
 OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)
 
 JVM参数:
 java -Djava.net.preferIPv4Stack=true -server -Xms1g -Xmx1g -XX:PermSize=128m

测试脚本

Server测试场景:

并发多个Client,连接数50,并发数100,测试Server极限性能

Client测试场景:

单客户端,10连接,在并发数分别为1,10,20,50的情况下,分别进行如下场景测试:
- 传入空包,不做任何处理,原样返回
- 传入Pojo嵌套对象,不做任何处理,原样返回
- 传入1kString,不做任何处理,原样返回
- 传入5kString,不做任何处理,原样返回
- 传入10kString,不做任何处理,原样返回
- 传入20kString,不做任何处理,原样返回
- 传入30kString,不做任何处理,原样返回
- 传入50kString,不做任何处理,原样返回。

测试结果

Server测试结果:

请求空包:单Server极限TPS:18W
请求1KString:单Server极限TPS:8.4W
请求5KString:单Server极限TPS:2W

Client测试结果:

对比图:

原始数据:

并发数 测试场景 平均TPS 平均响应时间(ms)
1 Empty 5601 0.178
1 Pojo 3556 0.281
1 1KString 2657 0.376
1 5KString 1100 0.908
1 10KString 949 1.052
1 20KString 600 1.664
1 30KString 512 1.95
1 50KString 253 3.939
10 Empty 39181 0.255
10 Pojo 27314 0.365
10 1KString 19968 0.5
10 5KString 11236 0.889
10 10KString 5875 1.701
10 20KString 4493 2.224
10 30KString 3387 2.951
10 50KString 1499 6.668
20 Empty 69061 0.289
20 Pojo 47226 0.423
20 1KString 34754 0.575
20 5KString 18883 1.058
20 10KString 9032 2.214
20 20KString 5471 3.654
20 30KString 3724 5.368
20 50KString 1973 10.133
50 Empty 69474 0.719
50 Pojo 64022 0.78
50 1KString 58937 0.848
50 5KString 20703 2.414
50 10KString 10761 4.645
50 20KString 5614 8.904
50 30KString 3782 13.214
50 50KString 2285 21.869

Documents

中文文档

Clone this wiki locally