一个简单的RPC框架实现
package com.rpc;
public interface EchoService {
String echo(String ping);
}
package com.rpc;
public class EchoServiceImpl implements EchoService{
@Override
public String echo(String ping) {
// TODO Auto-generated method stub
return ping != null ? ping + "--> I am ok.":"I am ok.";
}
}
package com.rpc; import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* 服务生产者
* @author Administrator
*
*/
public class RpcExporter {
static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public static void exporter(String hostname,int port) throws Exception{
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress(hostname, port));
try {
while(true){
executor.execute(new ExporterTask(server.accept()));
}
} finally {
server.close();
} } private static class ExporterTask implements Runnable{ Socket client = null;
public ExporterTask(Socket client) {
this.client = client;
}
@Override
public void run() {
ObjectInputStream input = null;
ObjectOutputStream output = null;
try {
input = new ObjectInputStream(client.getInputStream());
String interfaceName = input.readUTF();
Class<?> service = Class.forName(interfaceName);
String methodName = input.readUTF();
Class<?>[] parameterTypes = (Class<?>[]) input.readObject();
Object[] arguments = (Object[]) input.readObject();
Method method = service.getMethod(methodName, parameterTypes);
Object result = method.invoke(service.newInstance(), arguments);
output = new ObjectOutputStream(client.getOutputStream());
output.writeObject(result);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(output != null )
try{
output.close();
}catch(IOException e){
e.printStackTrace();
}
if(input != null)
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
if(client != null)
try{
client.close();
}catch(IOException e){
e.printStackTrace();
}
}
} }
}
package com.rpc; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* 服务消费者
* @author Administrator
*
* @param <S>
*/
public class RpcImporter<S> {
// serviceClass 即传入的具体实现类
@SuppressWarnings("unchecked")
public S importer(final Class<?> serviceClass, final InetSocketAddress addr) {
return (S) Proxy.newProxyInstance(serviceClass.getClassLoader(), serviceClass.getInterfaces(),
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = null;
ObjectOutputStream output = null;
ObjectInputStream input = null;
try {
socket = new Socket();
socket.connect(addr);
output = new ObjectOutputStream(socket.getOutputStream());
output.writeUTF(serviceClass.getName());
output.writeUTF(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
input = new ObjectInputStream(socket.getInputStream());
return input.readObject();
} finally {
if (socket != null)
socket.close();
if (output != null)
output.close();
if (input != null)
input.close();
} }
});
}
}
package com.rpc;
import java.net.InetSocketAddress;
public class RpcTest {
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
try {
RpcExporter.exporter("localhost", 8080);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
RpcImporter<EchoService> importer = new RpcImporter<EchoService>();
EchoService echo = importer.importer(EchoServiceImpl.class, new InetSocketAddress("localhost", 8080));
System.out.println(echo.echo("Are you ok ?"));
}
}
一个简单的RPC框架实现的更多相关文章
- 徒手撸一个简单的RPC框架
来源:https://juejin.im/post/5c4481a4f265da613438aec3 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的 ...
- 动手实现一个简单的 rpc 框架到入门 grpc (上)
rpc 全称 Remote Procedure Call 远程过程调用,即调用远程方法.我们调用当前进程中的方法时很简单,但是想要调用不同进程,甚至不同主机.不同语言中的方法时就需要借助 rpc 来实 ...
- 动手实现一个简单的 rpc 框架到入门 grpc (下)
之前手动实现了一次简陋的 rpc 调用,为了简单使用了 json 编码信息,其实这是非常不可靠的,go 中 json 解析会有一些问题,比如整数会变成浮点数,而且 json 字符串比较占空间. gRP ...
- 一个简单的"RPC框架"代码分析
0,服务接口定义---Echo.java /* * 定义了服务器提供的服务类型 */ public interface Echo { public String echo(String string) ...
- 一个简单的RPC框架
一个 系统模型 二.数据库代码实现 1. mkdir database cd database vim dbInit.c /* * * Database Init tool * */ #include ...
- 【RPC】手撸一个简单的RPC框架实现
涉及技术 序列化.Socket通信.Java动态代理技术,反射机制 角色 1.服务提供者:运行在服务端,是真实的服务实现类 2.服务发布监听者:运行在RPC服务端,1将服务端提供的 ...
- 自己用 Netty 实现一个简单的 RPC
目录: 需求 设计 实现 创建 maven 项目,导入 Netty 4.1.16. 项目目录结构 设计接口 提供者相关实现 消费者相关实现 测试结果 总结 源码地址:github 地址 前言 众所周知 ...
- 最简单的RPC框架实现
通过java原生的序列化,Socket通信,动态代理和反射机制,实现一个简单的RPC框架,由三部分组成: 1.服务提供者,运行再服务端,负责提供服务接口定义和服务实现类 2.服务发布者,运行再RPC服 ...
- 教你用 Netty 实现一个简单的 RPC!
众所周知,dubbo 底层使用了 Netty 作为网络通讯框架,而 Netty 的高性能我们之前也分析过源码,对他也算还是比较了解了. 今天我们就自己用 Netty 实现一个简单的 RPC 框架. 1 ...
随机推荐
- 生态 | Apache Hudi集成Alluxio实践
原文链接:https://mp.weixin.qq.com/s/sT2-KK23tvPY2oziEH11Kw 1. 什么是Alluxio Alluxio为数据驱动型应用和存储系统构建了桥梁, 将数据从 ...
- apache 添加多个站点
虚拟主机 (Virtual Host) 是在同一台机器搭建属于不同域名或者基于不同 IP 的多个网站服务的技术.可以为运行在同一物理机器上的各个网站指配不同的 IP 和端口,也可让多个网站拥有不同的域 ...
- Presto性能调优的五大技巧
概述 Presto架构 Presto是一个分布式的查询引擎,本身并不存储数据,但是可以接入多种数据源,并且支持跨数据源的级联查询. Presto的架构分为: Coodinator:解析SQL语句,生成 ...
- linux实现shell脚本监控磁盘内存达到阈值时清理catalina.out日志
想在服务器上写一个shell脚本,在磁盘使用率达到80%时,自动清理掉一些没有用的日志文件,根据这个想法,在生产环境上写了一个以下脚本,按照该流程,可实现在linux环境做一个定时任务来执行shell ...
- Python字典内置函数和方法
Python字典内置函数和方法: 注:使用了 items.values.keys 返回的是可迭代对象,可以使用 list 转化为列表. len(字典名): 返回键的个数,即字典的长度 # len(字典 ...
- Python exec 内置语句
描述 exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码.岭组词 https://www.cgewang.com/post/2205 ...
- Python编程入门(第3版) PDF|百度网盘下载内附提取码
Python编程入门(第3版)是图文并茂的Python学习参考书,书中并不包含深奥的理论或者高级应用,而是以大量来自实战的例子.屏幕图和详细的解释,用通俗易懂的语言结合常见任务,对Python的各项基 ...
- luogu P3279 [SCOI2013]密码
LINK:密码 给出来manacher的数组 让还原出字典序最小的字符串.字符集为小写字母. 当没有任何限制时 放字典序最小的'a'.如果此时还在最长的回文串中的话那么 直接得到当前字符即可. 注意这 ...
- source命令用法:source FileName
转自https://zhidao.baidu.com/question/59790034.html 写得很清楚,就直接搬过来了备忘 作用:在当前bash环境下读取并执行FileName中的命令. 注 ...
- 类加载Class Loading
JVM 何时.如何把 Class 文件加载到内存,形成可以直接使用的 Java 类型,并开始执行代码? 类的生命周期 加载 - 连接(验证.准备.解析)- 初始化 - 使用 - 卸载. 注意,加载 ...