概述

Motan 是一套高性能、易于使用的分布式远程服务调用(RPC)框架。

功能

简单调用示例

同步调用

  1. 在pom中添加依赖

<dependency> <groupId>com.weibo</groupId> <artifactId>motan-core</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>com.weibo</groupId> <artifactId>motan-transport-netty</artifactId> <version>RELEASE</version> </dependency> <!-- only needed for spring-based features --> <dependency> <groupId>com.weibo</groupId> <artifactId>motan-springsupport</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency>

  1. 为调用方和服务方创建公共接口。
  2. src/main/java/quickstart/FooService.java

package quickstart; public interface FooService { public String hello(String name); }

  1. 编写业务接口逻辑、创建并启动RPC Server。
  2. src/main/java/quickstart/FooServiceImpl.java

package quickstart; public class FooServiceImpl implements FooService { public String hello(String name) { System.out.println(name " invoked rpc service"); return "hello " name; } }

  1. src/main/resources/motan_server.xml

<?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:motan="http://api.weibo.com/schema/motan" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://api.weibo.com/schema/motan http://api.weibo.com/schema/motan.xsd"> <!-- service implemention bean --> <bean id="serviceImpl" class="quickstart.FooServiceImpl" /> <!-- exporting service by Motan --> <motan:service interface="quickstart.FooService" ref="serviceImpl" export="8002" /> </beans> `src/main/java/quickstart/server.java` package quickstart; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Server { public static void main(String[] args) throws InterruptedException { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:motan_server.xml"); System.out.println("server start..."); } }

  1. 执行Server类中的main函数将会启动Motan服务,并监听8002端口.
  2. 创建并执行RPC Client。
  3. src/main/resources/motan_client.xml

<?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:motan="http://api.weibo.com/schema/motan" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://api.weibo.com/schema/motan http://api.weibo.com/schema/motan.xsd"> <!-- reference to the remote service --> <motan:referer id="remoteService" interface="quickstart.FooService" directUrl="localhost:8002"/> </beans>

  1. src/main/java/quickstart/Client.java

package quickstart; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) throws InterruptedException { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:motan_client.xml"); FooService service = (FooService) ctx.getBean("remoteService"); System.out.println(service.hello("motan")); } }

  1. 执行Client类中的main函数将执行一次远程调用,并输出结果。

异步调用

异步调用与同步调用基本配置完全一样,只需要在接口类中加上@MotanAsync注解,然后client端稍作修改。server端不需要做任何修改。具体步骤如下:

  1. 在接口类上加@MotanAsync注解

package quickstart; @MotanAsync public interface FooService { public String hello(String name); }

  1. 编译时,Motan自动生成异步service类,生成路径为target/generated-sources/annotations/,生成的类名为service名加上Async,例如service类名为FooService.java,则自动生成的类名为FooServiceAsync.java。 另外,需要将motan自动生产类文件的路径配置为项目source path,可以使用maven plugin或手动配置。pom.xml配置如下:

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>RELEASE</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.build.directory}/generated-sources/annotations</source> </sources> </configuration> </execution> </executions> </plugin>

  1. 在client端配置motan_client.xml时,在同步调用配置的基础上,只需要修改referer的interface为Motan自动生成的接口类即可。

<motan:referer id="remoteService" interface="quickstart.FooServiceAsync" directUrl="localhost:8002"/>

  1. 异步使用方式如下:

public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {"classpath:motan_client.xml"}); FooServiceAsync service = (FooServiceAsync) ctx.getBean("remoteService"); // sync call System.out.println(service.hello("motan")); // async call ResponseFuture future = service.helloAsync("motan async "); System.out.println(future.getValue()); // multi call ResponseFuture future1 = service.helloAsync("motan async multi-1"); ResponseFuture future2 = service.helloAsync("motan async multi-2"); System.out.println(future1.getValue() ", " future2.getValue()); // async with listener FutureListener listener = new FutureListener() { @Override public void operationComplete(Future future) throws Exception { System.out.println("async call " (future.isSuccess() ? "sucess! value:" future.getValue() : "fail! exception:" future.getException().getMessage())); } }; ResponseFuture future3 = service.helloAsync("motan async multi-1"); ResponseFuture future4 = service.helloAsync("motan async multi-2"); future3.addListener(listener); future4.addListener(listener); }

具体代码可以参考demo模块

集群调用示例

在集群环境下使用Motan需要依赖外部服务发现组件,目前支持consul或zookeeper。

使用Consul作为注册中心

Consul安装与启动

安装(官方文档)

# 这里以linux为例 wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip unzip consul_0.6.4_linux_amd64.zip sudo mv consul /bin

启动(官方文档)

测试环境启动: consul agent -dev

ui后台 http://localhost:8500/ui

Motan-Consul配置

  1. 在server和client中添加motan-registry-consul依赖

<dependency> <groupId>com.weibo</groupId> <artifactId>motan-registry-consul</artifactId> <version>RELEASE</version> </dependency>

  1. 在server和client的配置文件中分别增加consul registry定义。

<motan:registry regProtocol="consul" name="my_consul" address="127.0.0.1:8500"/>

  1. 在Motan client及server配置改为通过registry服务发现。
  2. client

<motan:referer id="remoteService" interface="quickstart.FooService" registry="my_consul"/>

  1. server

<motan:service interface="quickstart.FooService" ref="serviceImpl" registry="my_consul" export="8002" />

  1. server程序启动后,需要显式调用心跳开关,注册到consul。

MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true)

  1. 进入ui后台查看服务是否正常提供调用
  2. 启动client,调用服务

使用ZooKeeper作为注册中心

ZooKeeper安装与启动(官方文档)

单机版安装与启动

最好的开源rpc(微博轻量级RPC框架)(1)

最好的开源rpc(微博轻量级RPC框架)(2)

服务名语法

(com.weibo.User* & !com.weibo.UserMapping) | com.weibo.Status* # 匹配com.weibo下以User开头的不包括UserMapping的所有服务,或以Status开头的所有服务

路由规则语法

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

指令管理

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

步骤:

最好的开源rpc(微博轻量级RPC框架)(3)

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

查询指令增删改查记录

步骤:

,