一句话解释「RPC调用网络」

124 阅读3分钟

RPC 调用网络,就是把远程服务伪装成本地函数,让你“像写函数一样调服务”。

RPC调用网络 是指通过 RPC 协议实现的一组网络通信机制,使得不同设备或服务之间能够像本地函数调用一样互相发送请求和接收响应。

你以为是函数,其实是网络

在日常开发中,我们调用一个函数 getUserInfo(id),返回一个对象 { name: 'Tom' } —— 看起来就像本地执行的逻辑,对吧?

但当这个函数是通过 RPC(Remote Procedure Call,远程过程调用) 实现的,其实你执行的是一场跨服务器的“戏法”:

  1. 你以为在调用函数
  2. 实际上框架拦截了你的调用
  3. 把参数打包成网络请求
  4. 发给远程服务,执行真实函数逻辑
  5. 拿到结果后反序列化,丢回给你
  6. 一切如常,你浑然不觉这是“跨服”

这就是 RPC 的魔法:隐藏了调用背后的“网络细节”,让远程像本地一样用。

image.png

你写的,其实不是你执行的

// 你以为是调用本地方法
const user = await rpc.getUserById('123');
console.log(user.name);

这段代码背后可能是:

POST /rpc/getUserById
Body: { id: '123' }

=> Response: { name: 'Tom' }

在你毫不知情的情况下,系统完成了:

  • 序列化参数
  • 发送 HTTP/gRPC 请求
  • 路由到服务提供者
  • 反序列化结果并返回

你只写了调用,RPC 帮你搞定了 请求、响应、错误处理、甚至重试机制。

RPC 的本质就是“隐藏网络通信”

RPC ≠ 协议,它是一种调用模式抽象,底层可以是:

  • HTTP(像 RESTful 一样)
  • gRPC(高性能二进制通信)
  • WebSocket / MQ(异步 RPC)

RPC 是构建微服务通信的“地基”

RPC框架实践

使用 trpc 开发一个前后端共享类型的 RPC 服务

适合场景:前后端都用 TypeScript,比如 React + Node.js 项目

开发步骤:

1. 定义服务端 router

// server/routers/user.ts
import { initTRPC } from '@trpc/server';

const t = initTRPC.create();

export const userRouter = t.router({
  getUserById: t.procedure.input((val: string) => val).query((opts) => {
    return { id: opts.input, name: 'Tom' };
  }),
});

2. 创建 appRouter

// server/routers/index.ts
export const appRouter = t.router({
  user: userRouter,
});

export type AppRouter = typeof appRouter;

3. 搭建服务

// server.ts
import { createHTTPHandler } from '@trpc/server/adapters/express';
import express from 'express';

const app = express();
app.use('/trpc', createHTTPHandler({ router: appRouter }));
app.listen(3000);

4. 客户端使用 RPC

// client.ts
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from './server/routers';

const client = createTRPCProxyClient<AppRouter>({
  links: [httpBatchLink({ url: 'http://localhost:3000/trpc' })],
});

const user = await client.user.getUserById.query('123');
console.log(user.name); // Tom

成功!你就像调用本地函数一样用 RPC 获取远程数据,而且还有完整的 TypeScript 类型支持~

使用 gRPC 开发一个高性能跨语言 RPC(Node + Go + Python)

适合场景:语言混合、接口要求高性能、结构清晰

1. 定义 proto 文件

// user.proto
syntax = "proto3";

service UserService {
  rpc GetUserById (UserRequest) returns (UserResponse);
}

message UserRequest {
  string id = 1;
}

message UserResponse {
  string id = 1;
  string name = 2;
}

2. 用 protoc 生成代码

protoc --js_out=import_style=commonjs,binary:. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` user.proto

3. 实现服务端(Node 版本)

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

const packageDefinition = protoLoader.loadSync('./user.proto');
const userProto = grpc.loadPackageDefinition(packageDefinition).UserService;

function getUserById(call, callback) {
  callback(null, { id: call.request.id, name: 'Tom' });
}

const server = new grpc.Server();
server.addService(userProto.service, { GetUserById: getUserById });
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => server.start());

4. 客户端调用

const client = new userProto('localhost:50051', grpc.credentials.createInsecure());

client.GetUserById({ id: '123' }, (err, response) => {
  console.log(response.name); // Tom
});

恭喜~成功实现语言无关的高性能 RPC 通信啦

对比总结

框架语言支持类型共享性能上手成本接入复杂度适合场景
trpc仅 TypeScript✅ 非常好🟠 中等✅ 极低✅ 极低前后端统一栈项目
gRPC多语言❌(要手动定义 proto)🟢 高🟠 中等🟠 中等跨语言、性能要求高
DubboJava🟢 高🟠 中等🔴 偏复杂企业 Java 微服务
自研 RPC任意可控取决实现特殊定制场景

总结

RPC 是一种“让你像调用本地函数一样调用远程服务”的魔法机制。

它屏蔽了网络细节,把跨服务器通信变得像写 JS 函数一样简单自然。