「java开源rpc框架」java grpc框架
今天给各位分享java开源rpc框架的知识,其中也会对java grpc框架进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
主流的RPC框架有哪些?
RPC是远程过程调用的简称,广泛应用在大规模分布式应用中,作用是有助于系统的垂直拆分,使系统更易拓展。Java中的RPC框架比较多,各有特色,广泛使用的有RMI、Hessian、Dubbo等。RPC还有一个特点就是能够跨语言。
1、RMI(远程方法调用)
JAVA自带的远程方法调用工具,不过有一定的局限性,毕竟是JAVA语言最开始时的设计,后来很多框架的原理都基于RMI,RMI的使用如下:
对外接口
span style="font-size:12px;"public interface IService extends Remote {
public String queryName(String no) throws RemoteException;
}/span
服务实现
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
// 服务实现
public class ServiceImpl extends UnicastRemoteObject implements IService {
/**
*/
private static final long serialVersionUID = 682805210518738166L;
/**
* @throws RemoteException
*/
protected ServiceImpl() throws RemoteException {
super();
}
/* (non-Javadoc)
* @see com.suning.ebuy.wd.web.IService#queryName(java.lang.String)
*/
@Override
public String queryName(String no) throws RemoteException {
// 方法的具体实现
System.out.println("hello" + no);
return String.valueOf(System.currentTimeMillis());
}
}
RMI客户端
[java] view plain copy
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
// RMI客户端
public class Client {
public static void main(String[] args) {
// 注册管理器
Registry registry = null;
try {
// 获取服务注册管理器
registry = LocateRegistry.getRegistry("127.0.0.1",8088);
// 列出所有注册的服务
String[] list = registry.list();
for(String s : list){
System.out.println(s);
}
} catch (RemoteException e) {
}
try {
// 根据命名获取服务
IService server = (IService) registry.lookup("vince");
// 调用远程方法
String result = server.queryName("ha ha ha ha");
// 输出调用结果
System.out.println("result from remote : " + result);
} catch (AccessException e) {
} catch (RemoteException e) {
} catch (NotBoundException e) {
}
}
}
RMI服务端
[java] view plain copy
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
// RMI服务端
public class Server {
public static void main(String[] args) {
// 注册管理器
Registry registry = null;
try {
// 创建一个服务注册管理器
registry = LocateRegistry.createRegistry(8088);
} catch (RemoteException e) {
}
try {
// 创建一个服务
ServiceImpl server = new ServiceImpl();
// 将服务绑定命名
registry.rebind("vince", server);
System.out.println("bind server");
} catch (RemoteException e) {
}
}
}
2、Hessian(基于HTTP的远程方法调用)
基于HTTP协议传输,在性能方面还不够完美,负载均衡和失效转移依赖于应用的负载均衡器,Hessian的使用则与RMI类似,区别在于淡化了Registry的角色,通过显示的地址调用,利用HessianProxyFactory根据配置的地址create一个代理对象,另外还要引入Hessian的Jar包。
3、Dubbo(淘宝开源的基于TCP的RPC框架)
基于Netty的高性能RPC框架,是阿里巴巴开源的,总体原理如下:
Dubbo与Nacos的区别两者是不是有重叠?
没有重叠,只是两者侧重点不一样。Nacos主要功能集中在动态服务发现、服务配置、服务元数据及流量管理。你可以把他简单的理解为是一个注册中心和配置中心,而Dubbo是一款高性能、轻量级的开源Java服务框架,主要功能点在于RPC框架。
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成。
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力,面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。
监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示。服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销。
java rpc框架哪个好 知乎
Thrift 是由 Facebook 开源的一个 RPC 框架,现在已经挂在 apache.org 下了。主要的几个好处:
1. 支持非常多语言,包括在 WEB 开发中很常用的 PHP,以及最重要的 C++/Python/Java 等 WEB后端常用语言,当然,还包括很 cool 的 Ruby、Erlang。
2. 完整的 RPC 框架实现,用脚本生成通讯相关的框架代码,开发者只需要集中精力处理好 业务逻辑。比如搭建一个 Hello World Service 只需要几分钟。
3.拥有被 Facebook、Last.fm 等不少大规模互联网应用验证过的性能和可用性。
Hessian是一款基于HTTP协议的RPC框架,采用的是二进制RPC协议,非常轻量级 ,且速度较快。
当然,还有Hetty,它是一款构建于Netty和Hessian基础上的高性能的RPC框架。
如何实现一个简单的RPC框
0,服务接口定义---Echo.java
/*
* 定义了服务器提供的服务类型 */public interface Echo { public String echo(String string);
}
一,客户端代码分析--实现类:MainClient.java
客户端实现包括:获得一个代理对象,并使用该代理对象调用服务器的服务。获取代理对象时,需要指定被代理的类(相当于服务器端提供的服务名),Server IP,Port,这样客户端就能找到服务端的服务了。
延伸:分布式环境下,Client如何打到Server的服务?---因为,在服务器中运行的某些服务不像标准服务有着固定的端口,如HTTP的80端口。
一种解决方法是:在运行服务的每台机器上都运行一个特殊的守护进程,该守护进程负责跟踪位于该机器中每一项服务所使用的端口;此外,守护进程还监听一个特定的已经端口,Client通过这个端口与守护进程联系,请求得到指定服务的端口。
复杂的RPC实现框架中,比如可以把服务注册到ZooKeeper中,Client也从ZooKeeper中查询服务。参考:一个更复杂的RPC框架实现
Echo echo = RPC.getProxy(Echo.class, "127.0.0.1", 20382);
System.out.println(echo.echo("hello,hello"));//使用代理对象调用服务器的服务.并将结果输出
二,服务器端分析--实现类:MainServer.java
服务器实现包括:创建一个服务器对象,将它能提供的服务注册,并启动进程监听客户端的连接
Server server = new RPC.RPCServer(); /*
* server 启动后,需要注册server端能够提供的服务,这样client使用 服务的名字、
* 服务器的IP、以及服务所运行的端口 来调用 server 的服务 */
server.register(Echo.class, RemoteEcho.class);//注册服务的名字
server.register(AnOtherEchoService.class, AnOtherEchoServiceImpl.class);
server.start();//启动server
三,服务器监听Client连接分析----实现类:Listener.java
当server.start()后,它要创建一个Listener对象,这是一个线程类,该线程用来监听Client连接。
public void start() {
System.out.println("启动服务器");
/*
* server 启动时,需要Listener监听是否有client的请求连接
* listener 是一个线程,由它来监听连接 */
listener = new Listener(this); this.isRuning = true;
listener.start();//listener 是一个线程类,start()后会执行线程的run方法
}
其实,监听连接就是JAVA ServerSocket类和Socket类提供的相关功能而已。
/*
* accept()是一个阻塞方法,server_socket 一直等待client 是否有连接到来 */
Socket client = server_socket.accept();//建立一条TCP连接
四,动态代理对象 生成---RPC.java
客户端只需要编写生成代理对象,用代理对象去调用远程服务的代码即可。但是,底层的功能如:建立连接,序列化(本例中也没有考虑),跨语言调用(未考虑)...是由RPC框架完成的。
当MainClient 语句:RPC.getProxy(Echo.class, "127.0.0.1", 20382);执行时,会由
/*
* @param Class[]{} 该参数声明了动态生成的代理对象实现了的接口,即 clazz 所代表的接口类型 .
* 这表明了生成的代理对象它是一个它所实现了的接口类型的对象
* 从而就可以用它来调用它所实现的接口中定义的方法
*
* @param handler 生成代理实例对象时需要传递一个handler参数
* 这样当该 代理实例对象调用接口中定义的方法时,将会委托给InvocationHandler 接口中声明的invoke方法
* 此时,InvocationHandler 的invoke 方法将会被自动调用 */
T t = (T) Proxy.newProxyInstance(RPC.class.getClassLoader(), new Class[] {clazz}, handler); return t;
返回该代理对象,然后就会委托第三个参数 handler 自动执行 invoke(),invoke将客户端调用的所有相关信息封装到Invocation 对象中(后面分析)。然后执行第16行代码发起连接。
1 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 2 Invocation invo = new Invocation(); 3 invo.setInterfaces(clazz); 4 5 //利用反射机制将java.lang.reflect.Method 所代表的方法名,参数 封装到 Invocation invo对象中 6 invo.setMethod(new org.jy.rpc.protocal.Method(method.getName(),method.getParameterTypes())); 7 invo.setParams(args); 8 9 /*10 * 当把需要调用的远程server端的方法名和参数封装到invo之后,Client 对象 就可以把 invo 作为参数 传递给服务器了.11 * 为什么需要这样做呢?InvocationHandler 的invoke方法是自动执行的,在该方法里面,它根据生成的代理对象 proxy (第一个参数)12 * 所实现的接口(由 Proxy.newProxyInstance()的第二个参数指定) 就可以知道这个接口中定义了哪些方法13 * InvocationHandler 的 invoke 方法的第二个参数Method method 就可以解析出接口中的方法名和参数了14 * 把它们封装进Invocation invo对象中,再将 invo 作为 client.invoke(invo)的参数 发送到服务器方15 */16 client.invoke(invo);//invoke 先调用init发起一个Socket连接,再将invo 发送至输出流中17 return invo.getResult();18 }
五,“客户端存根”--Client.java
最重要的是它的 invoke方法(注意与InvocationHandler的invoke()区分)。它负责建立连接,打开输入、输出流,向服务器发送字节数据。
1 public void invoke(Invocation invo) throws UnknownHostException, IOException, ClassNotFoundException {2 init();3 System.out.println("写入数据");4 oos.writeObject(invo);//将Client 需要调用的Server的 接口、方法、参数 封装起来 发给服务器5 oos.flush();6 ois = new ObjectInputStream(socket.getInputStream());//用来接收从 server 返回 回来的执行结果 的输入流7 Invocation result = (Invocation) ois.readObject();8 invo.setResult(result.getResult());//将结果 保存到 Invocation result对象中9 }
六,“服务器存根“---实现类:RPCServer.java
上面提到,服务器通过Listener监听客户端连接,当建立客户端连接后,Socket client = server_socket.accept(); 不再阻塞,服务器调用它的call()方法完成客户端请求的功能。也即,客户端请求的结果实际上是在服务器执行生成的。返回的结果是在Client.java 的 invoke() 方法里被读取出来 。call()再一次用到了JAVA反射(第11行) 参考:JAVA动态代理
1 public void call(Invocation invo) { 2 System.out.println(invo.getClass().getName()); 3 Object obj = serviceEngine.get(invo.getInterfaces().getName()); 4 if(obj!=null) { 5 try { 6 Method m = obj.getClass().getMethod(invo.getMethod().getMethodName(), invo.getMethod().getParams()); 7 /* 8 * 利用JAVA反射机制来执行java.lang.reflect.Method 所代表的方法 9 * @param result : 执行实际方法后 得到的 服务的执行结果10 */11 Object result = m.invoke(obj, invo.getParams());12 invo.setResult(result);//将服务的执行结果封装到invo对象中。在后面的代码中,将该对象写入到输出流中13 } catch (Throwable th) {14 th.printStackTrace();15 }16 } else {17 throw new IllegalArgumentException("has no these class");18 }19 }
七,”RPC 编码、解码,协议的定义“---Invocation.java Method.java
其实,这里并不是那种实用的开源RPC框架如Thrift中所指的编码、IDL……上面两个类只是RPC实现过程中辅助完成Java动态代理的实现,说白了就是封装客户端需要调用的方法,然后指定生成的代理对象需要实现的接口(服务).
八,总结:
先运行MainServer.java启动服务器,然后,再运行MainClient.java 启动一个客户端连接服务器就可以看到执行结果。
当需要添加新的服务时:按以下步骤即可:①定义服务接口及其实现类,如:AnOtherEchoService.java ②:在MainServer.java中注册新添加的服务。
③:在MainClient.java中编写获得新服务的代理对象的代码,并用该代理对象调用新服务接口中声明的方法。
这样,在客户端就能够远程地调用服务器上的一个新服务了。
关于java开源rpc框架和java grpc框架的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。