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

概述

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

功能

  • 支持通过spring配置方式集成,无需额外编写代码即可为服务提供分布式调用能力。
  • 支持集成consul、ZooKeeper等配置服务组件,提供集群环境的服务发现及治理能力。
  • 支持动态自定义负载均衡、跨机房流量调整等高级服务调度能力。
  • 基于高并发、高负载场景进行优化,保障生产环境下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安装与启动(官方文档)

单机版安装与启动

  • Step2:
  • 目标流量的RPC分组列表中选择目标流量分组,如motan-demo-rpc2,
  • 流量权重分配中根据需要按比例分配(可选范围是[0,100]),这里输入0和1,表示将来自motan-demo-rpc的流量全部转入motan-demo-rpc2,点击Next

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

  • Step3:(可选)若需根据具体IP调整流量,可在此配置
  • RPC Client中输入来源流量的ip,RPC Server中输入目标流量的ip,点击添加后将在路由规则结果中显示
  • 也可在路由规则结果中手动输入路由规则,路由规则见路由规则语法,点击Next

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

  • 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

指令管理

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

步骤:

  • 在导航栏选择指令查询,进入指令查询页面
  • 指令修改和删除操作需要管理员权限

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

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

查询指令增删改查记录

步骤:

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

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页