写在前面
单机应用中的方法调用很简单,直接调用就行,像这样
因为调用方与被调用方在一个进程内
随着业务的发展,单机应用会越来越力不从心,势必会引入分布式来解决单机的问题,那么调用方如何调用另一台机器上的方法呢 ?
这就涉及到分布式通信方式,从单机走向分布式,产生了很多通信方式
而 RPC 就是实现远程方法调用的方式之一;说 RPC 不是协议,可能很多小伙伴难以置信,以为我在骗你们
看着你们这一身腱子肉,我哪敢骗你们;只要你们把下面的看完,骗没骗你们,你们自己说了算
RPC 的演进过程
先说明一下,下文中的示例虽然是 Java 代码实现的,但原理是通用的,重点是理解其中的原理
第一版
两台机器之间进行交互,那么肯定离不开网络通信协议,TCP / IP 也就成了绕不开的点,所以先辈们最初想到的方法就是通过 TCP / IP 来实现远程方法的调用
而操作系统是没有直接暴露 TCP / IP 接口的,而是通过 Socket 抽象了 TCP / IP 接口,所以我们可以通过 Socket 来实现最初版的远程方法调用
完整示例代码:rpc-01,核心代码如下
package com.qsl.rpc;
import com.qsl.rpc.entity.User;
import com.qsl.rpc.server.UserServiceImpl;
import com.qsl.rpc.service.IUserService;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author 青石路
* @date 2021/1/16 19:49
*/
public class Server {
private static boolean is_running = true;
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
while (is_running) {
System.out.println("等待 client 连接");
Socket client = serverSocket.accept();
System.out.println("获取到 client...");
handle(client);
client.close();
}
serverSocket.close();
}
private static void handle(Socket client) throws Exception {
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
DataInputStream dis = new DataInputStream(in);
DataOutputStream dos = new DataOutputStream(out);
// 从 socket 读取参数
int id = dis.readInt();
System.out.println("id = " + id);
// 查询本地数据
IUserService userService = new UserServiceImpl();
User user = userService.getUserById(id);
// 往 socket 写响应值
dos.writeInt(user.getId());
dos.writeUTF(user.getName());
dos.flush();
dis.close();
dos.close();
}
}
Client:
package com.qsl.rpc;
import com.qsl.rpc.entity.User;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
/**
* @author 青石路
* @date 2021/1/16 19:49
*/
public class Client {
public static void main(String[] args) throws Exception {
Socket s = new Socket("127.0.0.1", 8888);
// 网络传输数据
// 往 socket 写请求参数
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeInt(18);
// 从 socket 读响应值
DataInputStream dis = new DataInputStream(s.getInputStream());
int id = dis.readInt();
St