Dubbo-RPC基本原理
1:RPC介绍
RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务–进程级别
通过网络调用,发生了网络事件
2:dubbo接口调用的基础
1:进程级别
我们的微服务都是部署在不同虚拟机/容器中,是进程隔离的
2:通过socket调用
对于部署在不同虚拟机或者不同容器中的服务,要是想发生数据通信的话,肯定是要走网络的,那么socker是跑不掉了
3:对socket进行封装
对socket进行封装的上层框架有很多中,我们可以使用JDK自带的BIO,NIO,以及对NIO进行封装的Netty
封装类型 | 优点 | 缺点 |
---|---|---|
BIO | 实现起来简单 | 存在着阻塞,性能不高 |
NIO | 性能高 | api众多,实现起来比较麻烦,细节不好掌控 |
Netty | 操作起来简单 | 暂无~ |
3代码环节
本实例基于jdk自带的socket+原生BIO实现网络通信做数据传输
1:基本原理
1:服务端开启一个socketServer,等待客户端的连接–阻塞住
2:客户端连接socketServer
3:将要发送的数据进行封装,并通过socket进行发送-- 序列化
4:服务端监听到客户端的socket连接,获取参数,反序列化 -》A
5:将A作为参数进行方法执行,返回结果,通过objectOutputStream输出
6:客户端收到服务端发回的结果流,进行反序列化生成对象–》结束
2:服务提供者(provider)
public class ProviderApplication {
public static void main(String[] args) throws Exception{
UserService userService = new UserServiceImpl();
ServerSocket serverSocket = new ServerSocket(9999);
while (true){
Socket socket = serverSocket.accept();
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
UserDo userDo = (UserDo) objectInputStream.readObject();
System.out.println(userDo);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(userService.getUser(userDo.getId()));
}
}
}
3:服务消费者(consumer)
public class ConsumerApplication {
public static void main(String[] args) throws Exception{
Socket socket = new Socket("127.0.0.1", 9999);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
UserDo userDo = new UserDo();
userDo.setId(11L);
userDo.setName("朱成才");
userDo.setAge(22);
userDo.setSex(1);
objectOutputStream.writeObject(userDo);
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
UserDo userDo1 = (UserDo) objectInputStream.readObject();
System.out.println("获取到服务器返回的结果result:" + userDo1);
}
}
4:总结
本章节演示了dubbo的最底层的原理,设计到了 socket,序列化,反序列化,想起来早些年还是初级打工人在刚刚接触dubbo的时候,因对象未实现序列化接口,导致报错,排查了些许,当时通过百度解决了问题,后来在研读dubbo源码的时候发现了原理,就是当对象没有实现Serializable接口的时候,会抛出NotSerializableException,本期代码还有很多优化空间,比如在接口调用的时候,代码写死等问题,可以用动态代理解决,下一章见~