手写RPC框架-基于BIO
RPC概述
RPC(Remote Proceduce Call 远程过程调用) 一般用来实现部署在不同机器上的系统之间的方法调用,使程序能够像访问本地系统资源一样,通过网络传输过去访问远端系统资源。
RPC 调用过程
Client 客户端调用方法实现,负责发起RPC调用。
ClientStub/SereverStub 可以看作一个代理对象,屏蔽RPC调用过程中复杂的网络处理逻辑,使RPC透明化,使得调用远程方法想调用本地方法一样。
Server 服务端提供远程服务。
Stub 主要作用
* 序列化:负责数据的序列化发序列化。
* 网络传输:数据发送与接收。
注:ServerStub又叫Skeleton。
RPC 实现
1. 远程服务接口
public interface IHello {
public String sayHello(String info);
}
2. 远程服务接口实现类(Server)
public class HelloService implements IHello {
public String sayHello(String info) {
String result = "hello : " + info;
System.out.println(result);
return result;
}
}
提供服务实现的类。
3.服务器代理实现(Skeleton)
public class RpcProxyServer {
private IHello hello = new HelloService();
public void publisherServer(int port) {
try (ServerSocket ss = new ServerSocket(port)) {
while (true) {
try (Socket socket = ss.accept()) {
try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
String method = ois.readUTF();
Object[] objs = (Object[]) ois.readObject();
Class<?>[] types = new Class[objs.length];
for (int i = 0; i < types.length; i++) {
types[i] = objs[i].getClass();
}
Method m = HelloService.class.getMethod(method, types);
Object obj = m.invoke(hello, objs);
try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
oos.writeObject(obj);
oos.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
构建一个ServerSocket服务监听来自客户端的请求。
接收请求的数据。(方法名和参数)
根据请求的数据(方法名和参数),使用反射调用相应的服务。
输出服务的响应数据。
4. RPC 客户端代理实现(ClientStub)
public class RpcProxyClient<T> {
public T proxyClient(Class<T> clazz) {
return (T) clazz.cast(Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try (Socket socket = new Socket("localhost", 8000)) {
try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) {
oos.writeUTF(method.getName());
oos.writeObject(args);
oos.flush();
try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
return ois.readObject();
}
}
}
}
}));
}
}
构建一个Socket,连接远程服务。
向远程服务发送数据。(方法名和方法参数)
接收远程服务响应的数据。
5.服务端发布服务
public class RpcServer {
//发布服务
public static void main(String[] args) {
RpcProxyServer server = new RpcProxyServer();
server.publisherServer(8000);
}
}
6.客户端调用(Client)
public class RpcClient {
// 调用服务
public static void main(String[] args) {
RpcProxyClient<HelloService> rpcClient = new RpcProxyClient<>();
IHello hello = rpcClient.proxyClient(HelloService.class);
String s = hello.sayHello("dd");
System.out.println(s);
}
}
- windows2012服务器搭建mongodb并设置远程访问
- 腾讯地图开放H5定位API,率先支持iOS10
- 写让别人能读懂的代码
- 安装serverstatus监控多台服务器状态
- Windows2012搭建我的世界(Minecraft)服务器超简单
- 高效程序员的MacBook工作环境配置
- vsftpd搭建自己的ftp服务器
- Linux一键安装Transmission电影下载到服务器
- centos安装ab工具给网站进行压力测试
- ubuntu16.04安装mongodb教程
- linux压缩解压命令使用
- linux使用wc命令查看文件行数、字母、字节数命令
- 程序员偷偷深爱的 9 个不良编程习惯
- 低级程序员和高级程序员的区别
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 第22天:NLP实战(六)——基于PaddleHub的疫情期间网民情绪识别
- Echarts大数据可视化物流航向省份流向迁徙动态图,开发全解+完美参数注释
- Linux 常用操作以及概念
- GCD梳理与总结——封装
- 原生JS在网页上复制的所有文字后面自动加上一段版权声明
- 使用宝塔docker安装为知笔记私有部署
- 第4天:美团点评2020校招测试方向笔试试卷分析
- Element-UI饿了么时间组件控件按月份周日期,开始时间结束时间范围限制参数
- 微信小程序flex布局
- 细数 TS 中那些奇怪的符号
- 安装RabbitMQ无法访问localhost:15672的管理界面解决
- koa中http服务与websocket服务共享端口
- 第23天:NLP实战(七)——中文新闻主题分类
- Swoole v4.5.3 版本发布
- .NET5.0 单文件发布打包操作深度剖析