Motan源码阅读--调用示例

调用示例

同步调用

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>

为调用方和服务方创建公共接口

src/main/java/quickstart/FooService.javapackage quickstart;public interface FooService {    public String hello(String name);
}

编写业务接口逻辑,创建并启动RPC Server

src/main/java/quickstart/FooServiceImpl.javapackage 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 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.javapackage 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端口。

创建并执行RPC Client

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

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

异步调用

异步调用和同步调用基本配置一样,只需要在接口类中加@MotanAsync注解,然后Client端稍作修改,server端不需要做任何修改。

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

编译时,Motan会自动生成异步service类,生成的类名为service名加上Async。 在client配置motan-client.xml时,在同步调用配置的基础上,只需要修改refer的interface为Motan自动生成的接口类即可。

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

异步使用方式如下:

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

集群调用示例

在分布式环境下,motan的使用需要依赖于外部服务发现组件,目前支持consul或zk。

使用Consul作为注册中心

server和client中添加moan-registry-consul依赖

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

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

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

将motan client及server配置改为通过registry服务发现

Client

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

Server

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

Server启动后,需要显示调用心跳开关,注册到consul

MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true)

zookeeper的实现和Consul类似。

原文发布于微信公众号 - 服务端技术杂谈(develop_king)

原文发表时间:2018-08-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java学习

关于Spring 和 Spring MVC的43个问题【问题汇总】

通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。

10910
来自专栏阿杜的世界

RocketMQ学习-NameServer-1

NameServer在RocketMQ中的角色是配置中心,主要有两个功能:Broker管理、路由管理。因此NameServer上存放的主要信息也包括两类:Bro...

14030
来自专栏java学习

你竟敢说你懂Spring框架?有可能你是没看到这些...(上)

所以,特地去搜刮了一些关于spring的面试题,希望能帮助各位同学在升职加薪的路上,一去不复返。

13520
来自专栏ImportSource

Spring Boot处理REST API错误的正确姿势

如何正确的处理API的返回信息,让返回的错误信息提供更多的含义是一个非常值得做的功能。 默认一般返回的都是难以理解的堆栈信息,然而这些信息也许对于API的客户...

631130
来自专栏转载gongluck的CSDN博客

_CrtSetDbgFlag

_CrtSetDbgFlag 若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 Visual Studio 2017 RC 文档。...

51090
来自专栏互联网大杂烩

Java锁与并发

保护临界区资源不会被多个线程同时访问时而受到破坏。通过锁,可以让多个线程排队。一个一个地进入临界区访问目标对象,使目标对象的状态总是保持一致。

13020
来自专栏栗霖积跬步之旅

Could not resolve view with name '***' in servlet with name 'dispatcher'

今天在开发中遇到了一个问题,控制层使用的是SpringMVC框架。 @RequestMapping("historyDetail") priva...

330100
来自专栏xingoo, 一个梦想做发明家的程序员

Java程序员的日常——经验贴(纯干货)二

继昨天的经验贴,今天的工作又收获不少。 windows下编辑器会给文件添加BOM 在windows的编辑器中,为了区分编码,通常会添加一个BOM标记。比如...

22690
来自专栏日常分享

Thrift IDL使用方式

众所周知,Thrift是一个RPC的框架,其可用于不同语言之间的服务相互调用。比如最近接触到的一个运用环境: *前端使用Node.Js重构了部分我们的老旧代码...

47410
来自专栏JAVA技术zhai

干货:Java并发编程系列之synchronized(一)

28770

扫码关注云+社区

领取腾讯云代金券