java自己写rpc(java自己写权限还是用框架)

本篇文章给大家谈谈java自己写rpc,以及java自己写权限还是用框架对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

1、如何实现一个简单的RPC框2、手写一个RPC框架,看看100个线程同时调用情况如何3、RPC框架(1 – 实现服务端注册一个服务)4、java用哪个组件实现的rpc5、怎么编写一个java rpc接口给c#使用6、java protobuf 定义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自己写权限还是用框架)

手写一个RPC框架,看看100个线程同时调用情况如何

简单的介绍RPC是什么,RPC整个调用流程是什么,包含了什么组件。然后实际编写一个RPC实例,模拟100个线程调用以验证RPC的可用性,稳定性等。最后总结自己编写的RPC框架存在哪些问题,可以去完善的,一个优秀的RPC框架应该必备的功能点。

RPC(Remote Procedure Call),远程过程调用,可通过网络调用其他机器的服务请求。RPC是一种规范,和TCP、UDP都没有关系,RCP可以采用TCP协议完成数据传输,甚至可以使用HTTP应用协议。RCP是C端模式,包含了服务端(服务提供方)、客户端(服务使用方),采用特定的网络传输协议,把数据按照特定的协议包装后进行传输操作等操作。先来了解下一个具体的RPC调用请求的执行过程

本图来自网络

这就是一个完整的RPC调用过程,对使用方而言就 只暴露了本地代理对象 ,剩下的数据解析、运输等都被包装了,从服务提供方的角度看还有 服务暴露 ,如下图DUBBO的架构图。

学习写RPC之前必须先了解 动态代理 和 反射 这两个知识点,如不了解先自行了解,本学习笔记不涉及到此内容的介绍。

文件夹目录

可以很清楚的看到convert方法就是从一个输入流中读取出类名称、方法名等数据,组成一个MethodParameter对象,也就是上面所说的Request

服务暴露存储了一个 MapString, Object objectMap 对象,所有可对外提供服务的都必须添加到该容器中,以便于收到网络数据后能找到对应的服务,然后采用反射invoke调用,返回得到的结果。

简单的BIO模型,开启了一个ServerSocket后,接收到数据后就把套接字丢给一个新的线程处理,ServerSocketRunnable接受一个socket后,解析出MethodParameter这个请求对象,然后调用服务暴露的invoke方法,再写回到socket传输给客户端

服务使用方需要使用register进行服务的注册,会生成对应的本地代理对象,后续只需要通过本地代理对象。

代理对象被调用后生成一个MethodParameter对象,通过此IOClient把数据传输到服务端,并且返回对应的数据。

服务端

客户端

测试服务

运行效果

这只是一个非常简单的RPC实践,包含了服务暴露、服务注册(Proxy生成)、BIO模型进行网络传输,java默认的序列化方法, 对RPC有一个初步的认识和了解,知道RPC必须包含的模块 。

不过还是有很多需要优化的点以改进。

还有例如服务统计、优雅下线、负载均衡等也都是一个成熟的RPC框架必须要考虑到的点。

本人微信公众号(搜索jwfy)欢迎关注

RPC框架(1 – 实现服务端注册一个服务)

基于这样一个假设,那就是客户端已经知道了服务端的地址,这部分会由后续的服务发现机制完善。通用接口

hello方法需要传递一个对象,HelloObject对象,定义如下:

注意这个对象需要实现 Serializable 接口,因为它需要在调用过程中从客户端传递给服务端。

接着我们在服务端对这个接口进行实现,实现的方式也很简单,返回一个字符串就行:

服务端需要哪些信息,才能唯一确定服务端需要调用的接口的方法呢?

那么服务端知道以上四个条件,就可以找到这个方法并且调用了。我们把这四个条件写到一个对象里,到时候传输时传输这个对象就行了。即 RpcRequest 对象:

那么服务器调用完这个方法后,需要给客户端返回哪些信息呢?

如果调用成功的话,显然需要返回值,如果调用失败了,就需要失败的信息,这里封装成一个 RpcResponse 对象:

这里还多写了两个静态方法,用于快速生成成功与失败的响应对象。其中,statusCode属性可以自行定义,客户端服务端一致即可。

客户端方面,由于在 客户端这一侧我们并没有接口的具体实现类,就没有办法直接生成实例对象 。这时,我们可以 通过动态代理的方式生成实例,并且调用方法时生成需要的RpcRequest对象并且发送给服务端 。

这里我们采用JDK动态代理,代理类是需要实现 InvocationHandler 接口的。

我们需要传递host和port来指明服务端的位置。并且使用getProxy()方法来生成代理对象。

InvocationHandler 接口需要实现invoke()方法,来指明代理对象的方法被调用时的动作。 在这里,我们显然就需要生成一个RpcRequest对象,发送出去,然后返回从服务端接收到的结果即可:

生成RpcRequest很简单,我 使用Builder模式来生成这个对象 。发送的逻辑我使用了一个RpcClient对象来实现,这个对象的作用, 就是将一个对象发过去,并且接收返回的对象。

我的实现很简单,直接使用Java的序列化方式,通过Socket传输。 创建一个Socket,获取ObjectOutputStream对象,然后把需要发送的对象传进去即可,接收时获取ObjectInputStream对象,readObject()方法就可以获得一个返回的对象。

服务端的实现就简单多了, 使用一个ServerSocket监听某个端口,循环接收连接请求,如果发来了请求就创建一个线程,在新线程中处理调用。 这里创建线程采用线程池:

这里简化了一下, RpcServer暂时只能注册一个接口,即对外提供一个接口的调用服务,添加register方法,在注册完一个服务后立刻开始监听:

这里向工作线程WorkerThread传入了socket和用于服务端实例service。

WorkerThread实现了Runnable接口,用于接收RpcRequest对象,解析并且调用,生成RpcResponse对象并传输回去。 run方法如下:

其中,通过class.getMethod方法,传入方法名和方法参数类型即可获得Method对象。如果你上面RpcRequest中使用String数组来存储方法参数类型的话,这里你就需要通过反射生成对应的Class数组了。通过method.invoke方法,传入对象实例和参数,即可调用并且获得返回值。

服务端侧,我们已经在上面实现了一个HelloService的实现类HelloServiceImpl,我们只需要创建一个RpcServer并且把这个实现类注册进去就行了:

服务端开放在9000端口。

客户端方面,我们需要通过动态代理,生成代理对象,并且调用,动态代理会自动帮我们向服务端发送请求的:

我们这里生成了一个HelloObject对象作为方法的参数。

首先启动服务端,再启动客户端,测试结果:

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框架。

怎么编写一个java rpc接口给c#使用

这个就需要定义一个统一的数据交换标准,比较流行的大概是HTTP接口,或者webservice接口

java protobuf 定义rpc服务怎么调用

1.,选择其中的win版本下载,我选择的是protoc-2.4.1-win32.zip

2.下载一个protobuf-java-2.4.1.jar文件(注意,要与你刚才下的proto.exe版本相同)

然后就开始开发了。

步骤:

1.用记事本编写一个.proto文件:

}如:编写的是test.proto

package protobuf;

option java_package = “com.sq.protobuf”;

option java_outer_classname = “FirstProtobuf”;

message testBuf {

required int32 ID = 1;

required string Url = 2;

}

将其放在与刚解压的protoc.exe同级目录中。

2.在cmd中,到protoc-2.4.1-win32文件夹下,

执行

E:\protoc-2.4.1-win32 protoc.exe –java_out=./ test.proto

则可以找到的一个生成的FirstProtobuf.java文件。

3.在MyEclipse中新建一个java project,建立包com.sq.protobuf,然后将刚才生成的FirstProtobuf.java文件放在其下面。

此时会报错,因为没有引入jar包,在package视图下,将protobuf-java-2.4.1.jar引入,即可解决问题。

java自己写rpc的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java自己写权限还是用框架、java自己写rpc的信息别忘了在本站进行查找喔。

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年3月29日 09:33:17
下一篇 2024年3月29日 09:39:36

相关推荐

  • 深入java虚拟机pdf,深入java虚拟机 中村成洋 pdf

    在linux环境下,java怎么实现从word格式转换为pdf格式 //设置当前使用的打印机,我的Adobe Distiller打印机名字为 Adobe PDF wordCom.setProperty( ActivePrinter , new Variant( Adobe PDF ));//设置printout的参数,将word文档打印为postscript…

    2024年5月23日
    4400
  • java截取指定长度字符串,java截取指定字符串之后的

    java中如何截取字符串中的指定一部分 第一个参数是开始截取的字符位置。(从0开始)第二个参数是结束字符的位置+1。(从0开始)indexof函数的作用是查找该字符串中的某个字的位置,并且返回。 int end);截取s中从begin开始至end结束时的字符串,并将其赋值给s;split讲解:java.lang.string.split split 方法 将…

    2024年5月23日
    4200
  • java绑定一个端口,java使用端口

    java如何多个service共用一个端口 你如果有多个项目的话,你可以把多个项目放到一个tomcat里面,这样端口相同使用项目名称来进行区分项目。你如果非要使用同一个,你也可以配置不同的域名导向不同的项目。就是访问的域名不同转接到的项目不同。 如果需要同时启动多个程序,要么修改tomcat的配置文件中的监听端口。要么修改jar包程序的监听端口。不能在一台服…

    2024年5月23日
    3400
  • linux给文件写权限,linux怎么给文件权限

    linux宝塔写入权限不足 1、可以使用chmod命令修改权限。语法:chmod [-cfvR] [–help] [–version] mode file…说明 : Linux/Unix 的档案调用权限分为三级 : 档案拥有者、群组、其他。利用 chmod 可以藉以控制档案如何被他人所调用。 2、通过更改文件权限可以使用c…

    2024年5月23日
    5000
  • java多线程并发编程基础,Java多线程并发执行返回

    电脑培训分享Java并发编程:核心理论 电脑培训发现本系列会从线程间协调的方式(wait、notify、notifyAll)、Synchronized及Volatile的本质入手,详细解释JDK为我们提供的每种并发工具和底层实现机制。 人们开始意识到了继承的众多缺点,开始努力用聚合代替继承。软件工程解决扩展性的重要原则就是抽象描述,直接使用的工具就是接口。接…

    2024年5月23日
    4600
  • 自学java找工作,自学java找工作需要包装简历吗

    自学java学多久可以找到工作 1、自学Java至少需要一年以上的时间才能达到找工作的水平。报班培训四到六个月的时间就可以找到一份不错的工作。 2、自学Java至少需要一年以上的时间才能达到找工作的水平。 3、如果要想找到一份Java相关的工作,需要至少学习5-6个月时间才能就业。Java开发需要掌握一些基础的编程语言知识,比如掌握面向对象的编程思想、基本的…

    2024年5月23日
    4200
  • java左移右移,java 左移

    java位移问题 1、思路:直接用Integer类的bit运算操作。 2、移位操作:左移:向左移位,符号后面的数字是移了多少位,移的位用0补齐,例如2进制数01111111左移一位后变为11111110,移位是字节操作。 3、Java 位运算 Java 位运算[转]一,Java 位运算表示方法: 在Java语言中,二进制数使用补码表示,最高位为符号位,正数的…

    2024年5月23日
    4100
  • java技术规范,java规范性要求

    现在主流的JAVA技术是什么? java最流行开发技术程序员必看 1 、Git Git一直是世界上最受欢迎的Java工具之一,也是Java开发人员最杰出的工具之一。Git是一个开源工具,是-种出色的分布式版本控制解决方案。 (1).Java基础语法、数组、类与对象、继承与多态、异常、范型、集合、流与文件、反射、枚举、自动装箱和注解。(2).Java面向对象编…

    2024年5月23日
    3900
  • javasocket编程,Java socket编程中,禁用nagle算法的参数

    Java进行并发多连接socket编程 1、Java可利用ServerSocket类对外部客户端提供多个socket接口。基本的做法是先创建一个ServerSocket实例,并绑定一个指定的端口,然后在这个实例上调用accept()方法等待客户端的连接请求。 2、Socket socket=server.accept(0;Thread handleThrea…

    2024年5月23日
    4600
  • java死亡,java死代码是什么意思

    我的世界传送回死亡点指令是什么? 1、下面就让我们一起来了解一下吧:我的世界回到死的地方的指令是输入/back,就可以回到死亡地点了,当然也可以看信标,因为死亡后会有一道光集中在死亡点,只要循着光就可以找到目的地了。 2、在服务器中的指令 首先打开指令台,在指令行输入“/back”就可以回到自己的死亡地点了。在单人游戏中的指令 在单人游戏中,您无法直接返回到…

    2024年5月23日
    4700

发表回复

登录后才能评论



关注微信