文章目录
- 一、概述
- 二、功能
- 三、XML配置使用
-
- 1、同步调用
-
- 1.1、pom中添加依赖
- 1.2、为调用方和服务方创建公共接口。
- [1.3、编写业务接口逻辑、创建并启动RPC Server。](#1.3、编写业务接口逻辑、创建并启动RPC Server。)
- [1.4、创建并执行RPC Client。](#1.4、创建并执行RPC Client。)
- 2、异步调用
- 3、Zookeeper注册中心配置
-
- [3.1 在server和client中 添加maven依赖](#3.1 在server和client中 添加maven依赖)
- [3.2 在server和client 的配置文件中分别增加zookeeper registry定义](#3.2 在server和client 的配置文件中分别增加zookeeper registry定义)
- [3.3 在Motan client及server配置改为通过registry服务发现。](#3.3 在Motan client及server配置改为通过registry服务发现。)
- [3.4 server程序启动后,需要显式调用心跳开关,注册到zookeeper。](#3.4 server程序启动后,需要显式调用心跳开关,注册到zookeeper。)
- [3.5 启动client,调用服务](#3.5 启动client,调用服务)
- 四、注解配置使用
-
- server端配置
- client端配置
-
- 1、声明Annotation、protocolConfig、RegistryConfig的配置bean。
- [2、配置basicRefererConfig bean](#2、配置basicRefererConfig bean)
- [3、在使用motan service 的对象上添加@MotanReferer注解,](#3、在使用motan service 的对象上添加@MotanReferer注解,)
- 4、使用spring-boot启动client
一、概述
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);
}
}