A simple RPC framework example
No Data
极客时间《消息队列高手课》案例篇《动手实现一个简单的RPC框架》示例源代码。
运行示例之前需要先安装:
$java -version java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)$mvn -version Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
$git clone [email protected]:liyue2008/simple-rpc-framework.git $cd simple-rpc-framework $mvn package
$java -jar server/target/server-1.0-SNAPSHOT-jar-with-dependencies.jar [main] INFO com.github.liyue2008.rpc.server.Server - 创建并启动RpcAccessPoint... [main] INFO com.github.liyue2008.rpc.transport.RequestHandlerRegistry - Load request handler, type: 0, class: com.github.liyue2008.rpc.transport.RpcRequestHandler. [main] INFO com.github.liyue2008.rpc.server.Server - 向RpcAccessPoint注册com.github.liyue2008.rpc.hello.HelloService服务... [main] INFO com.github.liyue2008.rpc.server.Server - 服务名: com.github.liyue2008.rpc.hello.HelloService, 向NameService注册... [main] INFO com.github.liyue2008.rpc.nameservice.LocalFileNameService - Register service: com.github.liyue2008.rpc.hello.HelloService, uri: rpc://localhost:9999. [main] INFO com.github.liyue2008.rpc.serialize.SerializeSupport - Found serializer, class: com.github.liyue2008.rpc.nameservice.Metadata, type: 100. [main] INFO com.github.liyue2008.rpc.serialize.SerializeSupport - Found serializer, class: java.lang.String, type: 0. [main] INFO com.github.liyue2008.rpc.serialize.SerializeSupport - Found serializer, class: com.github.liyue2008.rpc.client.stubs.RpcRequest, type: 101. [main] INFO com.github.liyue2008.rpc.nameservice.LocalFileNameService - Metadata: Classname: com.github.liyue2008.rpc.hello.HelloService URIs: rpc://localhost:9999[main] INFO com.github.liyue2008.rpc.server.Server - 开始提供服务,按任何键退出.
java -jar client/target/client-1.0-SNAPSHOT-jar-with-dependencies.jar [main] INFO com.github.liyue2008.rpc.serialize.SerializeSupport - Found serializer, class: com.github.liyue2008.rpc.nameservice.Metadata, type: 100. [main] INFO com.github.liyue2008.rpc.serialize.SerializeSupport - Found serializer, class: java.lang.String, type: 0. [main] INFO com.github.liyue2008.rpc.serialize.SerializeSupport - Found serializer, class: com.github.liyue2008.rpc.client.stubs.RpcRequest, type: 101. [main] INFO com.github.liyue2008.rpc.nameservice.LocalFileNameService - Metadata: Classname: com.github.liyue2008.rpc.hello.HelloService URIs: rpc://localhost:9999[main] INFO com.github.liyue2008.rpc.client.Client - 找到服务com.github.liyue2008.rpc.hello.HelloService,提供者: rpc://localhost:9999. [main] INFO com.github.liyue2008.rpc.client.Client - 请求服务, name: Master MQ... [main] INFO com.github.liyue2008.rpc.client.Client - 收到响应: Hello, Master MQ.
RPC框架对外提供的所有服务定义在一个接口RpcAccessPoint中:
/** * RPC框架对外提供的服务接口 */ public interface RpcAccessPoint extends Closeable{ /** * 客户端获取远程服务的引用 * @param uri 远程服务地址 * @param serviceClass 服务的接口类的Class * @param 服务接口的类型 * @return 远程服务引用 */ T getRemoteService(URI uri, Class serviceClass);/** * 服务端注册服务的实现实例 * @param service 实现实例 * @param serviceClass 服务的接口类的Class * @param <t> 服务接口的类型 * @return 服务地址 */ <t> URI addServiceProvider(T service, Class<t> serviceClass); /** * 服务端启动RPC框架,监听接口,开始提供远程服务。 * @return 服务实例,用于程序停止的时候安全关闭服务。 */ Closeable startServer() throws Exception;
}
注册中心的接口NameService:
/** * 注册中心 */ public interface NameService { /** * 注册服务 * @param serviceName 服务名称 * @param uri 服务地址 */ void registerService(String serviceName, URI uri) throws IOException;/** * 查询服务地址 * @param serviceName 服务名称 * @return 服务地址 */ URI lookupService(String serviceName) throws IOException;
}
需要先定义一个服务接口:
public interface HelloService { String hello(String name); }
客户端:
URI uri = nameService.lookupService(serviceName); HelloService helloService = rpcAccessPoint.getRemoteService(uri, HelloService.class); String response = helloService.hello(name); logger.info("收到响应: {}.", response);
服务端:
定义一个HelloService的实现:
public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { String ret = "Hello, " + name; return ret; } }
然后,把实现注册到RPC框架上,并启动RPC服务:
rpcAccessPoint.startServer(); URI uri = rpcAccessPoint.addServiceProvider(helloService, HelloService.class); nameService.registerService(serviceName, uri);
Module |
说明 |
---|---|
client | 例子:客户端 |
server | 例子:服务端 |
rpc-api | RPC框架接口 |
hello-service-api | 例子:接口定义 |
rpc-netty | 基于Netty实现的RPC框架 |