先说是不是,再说为什么。
1.RPC本质上不一定是TCP,或者说常见的RPC是基于TCP的或使用TCP之上的某种协议的。实际上RPC也可以基于UDP之类的协议。详见:https://www.w3.org/History/1992/nfs_dxcern_mirror/rpc/doc/User/Internet.htmlwww.w3.orgRPC Protocol Overviewwww.freesoft.org
可以看到几十年前,都可以使用UDP的RPC了。
2.为什么一般需要用RPC而不是直接使用TCP?
很简单呀,为了简化开发模型。
直接使用TCP做两个系统间的通信方式,你需要先定义一个是server,需要写代码实现server的端口监听,建立连接,接收数据和返回数据,还需要实现一个client,做类似的反向事情,中间需要定义传输的byte数据,怎么转换成有意义的报文。其实你可以看到,这些东西里,大部分都与业务本身没有关系,在处理通信、序列化和反序列化,而我们把这些非业务处理的部分,使用某个具体的通信方式和序列化方式封装成lib,就不需要使用者考虑,直接可以方便愉快的使用了。
想象一下,你是愿意写代码:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static final int PORT = 12345;//监听的端口号
public static void main(String[] args) {
System.out.println("服务器启动...\n");
Server server = new Server();
server.init();
}
public void init() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
// 一旦有堵塞, 则表示服务器与客户端获得了连接
Socket client = serverSocket.accept();
// 处理这次连接
new HandlerThread(client);
}
} catch (Exception e) {
System.out.println("服务器异常: " + e.getMessage());
}
}
private class HandlerThread implements Runnable {
private Socket socket;
public HandlerThread(Socket client) {
socket = client;
new Thread(this).start();
}
public void run() {
try {
// 读取客户端数据
DataInputStream input = new DataInputStream(socket.getInputStream());
String clientInputStr = input.readUTF();//这里要注意和客户端输出流的写方法对应,否则会抛 EOFException
// 处理客户端数据
System.out.println("客户端发过来的内容:" + clientInputStr);
// 向客户端回复信息
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
System.out.print("请输入:\t");
// 发送键盘输入的一行
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
out.writeUTF(s);
out.close();
input.close();
} catch (Exception e) {
System.out.println("服务器 run 异常: " + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
socket = null;
System.out.println("服务端 finally 异常:" + e.getMessage());
}
}
}
}
}
}
再写一倍client代码。还是愿意
public interface MockService{
String doSome(int seq);
}
然后直接使用:
String result = mockService.doSome(123);
假如你是一个工期紧张巴巴的程序员,你愿意写哪个代码?