[RPC] Motan快速开始

文章目录

一、概述

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

二、功能

支持通过spring配置方式集成,无需额外编写代码即可为服务提供分布式调用能力。

支持集成consul、zookeeper等配置服务组件,提供集群环境的服务发现及治理能力。

支持动态自定义负载均衡、跨机房流量调整等高级服务调度能力。

基于高并发、高负载场景进行优化,保障生产环境下RPC服务高可用。

文档索引

三、XML配置使用

1、同步调用

1.1、pom中添加依赖

xml 复制代码
<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、为调用方和服务方创建公共接口。

java 复制代码
package quickstart;

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

1.3、编写业务接口逻辑、创建并启动RPC Server。

java 复制代码
package quickstart;

public class FooServiceImpl implements FooService {

    public String hello(String name) {
        System.out.println(name + " invoked rpc service");
        return "hello " + name;
    }
}

src/main/resources/motan_server.xml

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

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...");
    }
}

执行Server类中的main函数将会启动Motan服务,并监听8002端口.

1.4、创建并执行RPC Client。

src/main/resources/motan_client.xml

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>

src/main/java/quickstart/Client.java

xml 复制代码
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"));
    }
}

2、异步调用

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

2.1、在接口类上加@MotanAsync注解

java 复制代码
package quickstart;

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

编译时,

Motan自动生成异步service类,生成路径为target/generated-sources/annotations/,生成的类名为service名加上Async。

例如 service类名为FooService.java,则自动生成的类名为FooServiceAsync.java。

另外,需要将motan自动生产类文件的路径配置为项目source path,可以使用maven plugin或手动配置。

pom.xml配置如下:

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>

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

xml 复制代码
<motan:referer id="remoteService" interface="quickstart.FooServiceAsync" directUrl="localhost:8002"/>

异步使用方式如下:

java 复制代码
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);
}

3、Zookeeper注册中心配置

3.1 在server和client中 添加maven依赖

xml 复制代码
<dependency>
    <groupId>com.weibo</groupId>
    <artifactId>motan-registry-zookeeper</artifactId>
    <version>RELEASE</version>
</dependency>

3.2 在server和client 的配置文件中分别增加zookeeper registry定义

xml 复制代码
<motan:registry regProtocol="zk" name="my_zookeeper" address="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"/>

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

client

xml 复制代码
<motan:referer id="remoteService" interface="quickstart.FooService" registry="my_zookeeper"/>

server

xml 复制代码
<motan:service interface="quickstart.FooService" ref="serviceImpl" registry="my_zookeeper" export="8002" />

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

xml 复制代码
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true)

3.5 启动client,调用服务


四、注解配置使用

server端配置

1、声明Annotation用来指定需要解析的包名

java 复制代码
 @Bean
 public AnnotationBean motanAnnotationBean() {
     AnnotationBean motanAnnotationBean = new AnnotationBean();
     motanAnnotationBean.setPackage("com.weibo.motan.demo.server");
     return motanAnnotationBean;
 }

2、配置ProtocolConfig、RegistryConfig、BasicServiceConfig的bean对象

功能与xml配置中的protocol、registry、basicService标签一致。

java 复制代码
 @Bean(name = "demoMotan")
 public ProtocolConfigBean protocolConfig1() {
     ProtocolConfigBean config = new ProtocolConfigBean();
     config.setDefault(true);
     config.setName("motan");
     config.setMaxContentLength(1048576);
     return config;
 }

 @Bean(name = "registryConfig1")
 public RegistryConfigBean registryConfig() {
     RegistryConfigBean config = new RegistryConfigBean();
     config.setRegProtocol("local");
     return config;
 }

 @Bean
 public BasicServiceConfigBean baseServiceConfig() {
     BasicServiceConfigBean config = new BasicServiceConfigBean();
     config.setExport("demoMotan:8002");
     config.setGroup("testgroup");
     config.setAccessLog(false);
     config.setShareChannel(true);
     config.setModule("motan-demo-rpc");
     config.setApplication("myMotanDemo");
     config.setRegistry("registryConfig1");
     return config;
 }

3、service的实现类上添加@MotanService注解,注解的配置参数与xml配置方式的service标签一致。

java 复制代码
 @MotanService(export = "demoMotan:8002")
 public class MotanDemoServiceImpl implements MotanDemoService {

     public String hello(String name) {
         System.out.println(name);
         return "Hello " + name + "!";
     }
 }

4、使用spring-boot启动服务

java 复制代码
 @EnableAutoConfiguration
 @SpringBootApplication
 public class SpringBootRpcServerDemo {

     public static void main(String[] args) {
         System.setProperty("server.port", "8081");
         ConfigurableApplicationContext context =  SpringApplication.run(SpringBootRpcServerDemo.class, args);
		 MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);
         System.out.println("server start...");
     }
 }

client端配置

1、声明Annotation、protocolConfig、RegistryConfig的配置bean。

方式与server端配置类似。

2、配置basicRefererConfig bean

java 复制代码
 @Bean(name = "motantestClientBasicConfig")
 public BasicRefererConfigBean baseRefererConfig() {
     BasicRefererConfigBean config = new BasicRefererConfigBean();
     config.setProtocol("demoMotan");
     config.setGroup("motan-demo-rpc");
     config.setModule("motan-demo-rpc");
     config.setApplication("myMotanDemo");
     config.setRegistry("registry");
     config.setCheck(false);
     config.setAccessLog(true);
     config.setRetries(2);
     config.setThrowException(true);
     return config;
 }

3、在使用motan service 的对象上添加@MotanReferer注解,

注册配置与xml方式的referer标签一致

java 复制代码
 @RestController
 public class HelloController {

     @MotanReferer(basicReferer = "motantestClientBasicConfig", group = "testgroup", directUrl = "127.0.0.1:8002")
     MotanDemoService service;

     @RequestMapping("/")
     @ResponseBody
     public String home() {
         String result = service.hello("test");
         return result;
     }
 }

4、使用spring-boot启动client

java 复制代码
 @EnableAutoConfiguration
 @SpringBootApplication
 public class SpringBootRpcClientDemo {

     public static void main(String[] args) {
         SpringApplication.run(SpringBootRpcClientDemo.class, args);
     }
 }

官网文档

相关推荐
独行soc11 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
XuanRanDev14 小时前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
ktkiko1116 小时前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
鹏大师运维20 小时前
【功能介绍】信创终端系统上各WPS版本的授权差异
linux·wps·授权·麒麟·国产操作系统·1024程序员节·统信uos
亦枫Leonlew21 小时前
微积分复习笔记 Calculus Volume 1 - 4.7 Applied Optimization Problems
笔记·数学·微积分·1024程序员节
小肥象不是小飞象21 小时前
(六千字心得笔记)零基础C语言入门第八课——函数(上)
c语言·开发语言·笔记·1024程序员节
点点滴滴的记录1 天前
RPC核心实现原理
网络·网络协议·rpc
一个通信老学姐1 天前
专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节
徒步僧1 天前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
力姆泰克1 天前
看电动缸是如何提高农机的自动化水平
大数据·运维·服务器·数据库·人工智能·自动化·1024程序员节