上篇博客主要介绍了dubbo的使用,这篇文章主要深入rpc的核心原理
准备知识:
1 java 网络编程(这里使用的bio)
2 java动态代理
3 反射
=================================
通俗来说rpc就是
客户端持有的是接口(但是没有持有实现),
服务端放的是接口的具体实现以及接口。
客户端把方法和方法的参数 以及其他参数 通过socket发送给服务端,
然后服务端执行相对应的方法,最后再把执行结果返回给客户端。
RPC的架构一般分为三部分:
1)服务提供者,运行在服务器端,提供服务接口定义与服务实现类。
在本项目主要是(ITestService 以及 TestServiceImpl)
2)服务中心,运行在服务器端,负责将本地服务注册成远程服务,管理远程服务,提供给服务消费者使用。
在本项目主要是(IServerCenter以及BioServiceCenter)
3)服务消费者,运行在客户端,通过远程代理对象调用远程服务。
在本项目主要是(RpcProxy 返回代理对象)
核心代码如下:
服务提供者的接口定义
public interface ITestService { String sayHi(String name); }
服务提供者的接口实现
public class TestServiceImpl implements ITestService { public String sayHi(String name) { return "Hi, " + name; } }
服务中心接口抽象
public interface IServerCenter { public void stop(); /** * 开启服务 * * @throws IOException */ public void start() throws IOException; /** * 服务提供者注册到服务中心上 * * @param servInterfaceName * 服务接口名字 * @param servImplClazz * 具体服务实现class * @throws IOException */ public void register(String servInterfaceName, Class<?> servImplClazz); }
服务中心接口实现
客户端的远程代理类(主要是生成代理对象,发送请求给服务器 并获取返回结果)
关闭流的代码这里省略了
测试类
public class Test { public static void main(String[] args) { final int port = 9999; new Thread(new Runnable() { @Override public void run() { BioServiceCenter bioServiceCenter = new BioServiceCenter(port); bioServiceCenter.register(ITestService.class.getName(), TestServiceImpl.class); try { bioServiceCenter.start(); } catch (IOException e) { e.printStackTrace(); } } }).start(); ITestService iTestService = (ITestService) RpcProxy.getRpcProxyObject(ITestService.class, new InetSocketAddress("localhost", port)); System.out.println(iTestService.sayHi("nihao ")); } }
运行结果如下
注意:这个例子只是模拟了核心处理流程,还有以下几个点可以优化
1 bio相对来说性能不如nio ,可以考虑使用netty等高性能网络通信框架
2 使用更加高效的序列化方式,比如Google protobu ,kryo等
3 服务注册与发现 可以使用zookeeper实现,更加稳定