- 浏览: 199210 次
- 性别:
- 来自: 哈尔滨
文章分类
- 全部博客 (267)
- java.lang (8)
- 问题汇总 (21)
- 异常记录 (20)
- 功能实现 (19)
- 面试总结 (25)
- 技巧总结 (8)
- 常用代码 (4)
- 编程习惯 (3)
- 编码规则 (3)
- java.util (10)
- java.io (1)
- JavaWeb (9)
- MySQL (16)
- SVN (3)
- MyBatis (11)
- Velocity (7)
- 其他知识 (10)
- 人生哲理 (1)
- 人生故事 (1)
- 自我感悟 (1)
- shiro (3)
- 基础知识 (0)
- 问题总结 (1)
- Spring 标签 (1)
- Spring (3)
- 点滴生活 (1)
- DOS (1)
- CAS (4)
- Linux (9)
- Storm (6)
- Shell (1)
- regex (1)
- Collection (4)
- poi (1)
- 经典语句 (1)
- NIO (5)
- concurrent (14)
- RPC (1)
- zookeeper (3)
- 待整理 (2)
- Hadoop (9)
- RabbitMq (2)
- flume (1)
- hive (7)
- hbase (4)
- kafka (1)
- scala (1)
- GC (0)
- java.util.concurrent.atomic (1)
- java.lang.ref (6)
- JVM (2)
- algorithm (1)
- conception (1)
- java key word (1)
- sun.misc (1)
最新评论
一、
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议
二、
1.序列化与反序列化
序列化:将对象从内存中以二进制数据流的形式传递
反序列化:将二进制数据传递到内存中
持久化:内存中的数据是不能永久保存的,即瞬时数据,保存到文本中或其他介质中,永久化
反持久化:从持久化转化为内存存储
持久化的前提是序列化,但序列化的目的不一定是为了持久化
2.基本实现
若:
(若实现Serializable ,生成的
private static final long serialVersionUID = 1L;
)
执行序列化后,修改了Object的属性,增加或删除,再次执行反序列化的时候,异常
解释:
序列化写入的类与反序列化读出的类是两个不同的类,
是因为作用域的原因,写入时,程序执行完毕,内存自动回收
可以认为 读入的类是写入的类的克隆,具有相同的内容
若属性的数量或内容对应不上,克隆就会出现异常
对象序列化即实现Serializable 后,会生成一个随机的serialVersionUID
若属性变化,则会生成新的 serialVersionUID,
进行序列化读出与写入的时候就会比较serialVersionUID是否是同一个
即 serialVersionUID 是序列化与反序列化时的唯一标识
其他:
RPC传输Object时,设置不同机器上的Person的serialVersionUID相同,
即使Person中的内容完全相同,也不一定认为是同一个,即修改serialVersionUID,保持一致
3.transient 不需序列化
输出:
zhang null male
age 属性不需序列化,所以无输出
4.
缺点:
1)只支持java语言,无法跨语言
2)序列化后的数据量比较大
3)执行序列化与反序列化的效率比较低
三、第三方序列化与反序列化框架
Avro
GoogleProtoBuffer
Thrift
1.GoogleProtoBuffer
生成与执行步骤
1)数据写入 .proto文件
2)编译成类文件
3)导入类文件进行序列化与反序列化
1)PersonProto.proto
2.编译类文件
解压:protoc.exe 安装包,见 下方
打开 win+r cmd --> cd .. 到安装包目录 --> 将上面的 PersonProto.proto 拷贝到该目录下
执行 protoc.ext --java_out . ./PersonProto.proto
在解压的目录中会出现相应的生成文件
拷贝文件至对应的包中
报错--因为未导入相应的JAR包 -- 见下面链接
3.调用API执行
序列化后的文件大小对比
4.扩展
若IO流改为网络流,
接收方以同样的方式对 PersonProto.proto 进行处理,语言可以不同,即不同语言间传递对象
三、RPC实现
描述:客户端发送数据,服务端接收,计算,返回结果给客户端
1.MathService.proto
生成对应的JAVA文件
2.
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议
二、
1.序列化与反序列化
序列化:将对象从内存中以二进制数据流的形式传递
反序列化:将二进制数据传递到内存中
持久化:内存中的数据是不能永久保存的,即瞬时数据,保存到文本中或其他介质中,永久化
反持久化:从持久化转化为内存存储
持久化的前提是序列化,但序列化的目的不一定是为了持久化
2.基本实现
public class Person implements Serializable{ /** * */ private static final long serialVersionUID = -1170943594852852868L; private String name ; private Integer age ; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Person(String name, Integer age) { super(); this.name = name; this.age = age; } public Person() { super(); } }
/** * 序列化:将对象以二进制的格式输出到文本文件中 * @throws IOException */ @Test public void testSerializable() throws IOException{ /** * 所有需要序列化的类均需要实现 Serializable 接口 * 标记接口,标识 此类允许序列化与反序列化 * java.io.NotSerializableException */ Person person = new Person(); person.setName("zhang"); person.setAge(Integer.valueOf(26)); // 序列化输出:文件内容为二进制格式,无法直接阅读 FileOutputStream out = new FileOutputStream("D:\\study\\test.txt"); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(person); oos.flush(); oos.close(); } /** * 反序列化:读取文本中的二进制信息 * @throws IOException * @throws ClassNotFoundException */ @Test public void testReverseSerializable() throws IOException, ClassNotFoundException{ FileInputStream in = new FileInputStream("D:\\study\\test.txt"); ObjectInputStream ois = new ObjectInputStream(in); Person person = (Person) ois.readObject(); System.out.println(person.getName()+" "+person.getAge()); }
若:
(若实现Serializable ,生成的
private static final long serialVersionUID = 1L;
)
执行序列化后,修改了Object的属性,增加或删除,再次执行反序列化的时候,异常
解释:
序列化写入的类与反序列化读出的类是两个不同的类,
是因为作用域的原因,写入时,程序执行完毕,内存自动回收
可以认为 读入的类是写入的类的克隆,具有相同的内容
若属性的数量或内容对应不上,克隆就会出现异常
对象序列化即实现Serializable 后,会生成一个随机的serialVersionUID
若属性变化,则会生成新的 serialVersionUID,
进行序列化读出与写入的时候就会比较serialVersionUID是否是同一个
即 serialVersionUID 是序列化与反序列化时的唯一标识
其他:
RPC传输Object时,设置不同机器上的Person的serialVersionUID相同,
即使Person中的内容完全相同,也不一定认为是同一个,即修改serialVersionUID,保持一致
3.transient 不需序列化
public class Person implements Serializable{ /** * */ private static final long serialVersionUID = -1170943594852852868L; private String name ; /** * 若某个属性保密,不希望进行系列化处理,加关键字,transient */ private transient Integer age ; private String gender ; public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Person(String name, Integer age) { super(); this.name = name; this.age = age; } public Person() { super(); } public Person(String name, Integer age, String gender) { super(); this.name = name; this.age = age; this.gender = gender; } }
/** * 序列化:将对象以二进制的格式输出到文本文件中 * @throws IOException */ @Test public void testSerializable() throws IOException{ /** * 所有需要序列化的类均需要实现 Serializable 接口 * 标记接口,标识 此类允许序列化与反序列化 * java.io.NotSerializableException */ Person person = new Person(); person.setName("zhang"); person.setAge(Integer.valueOf(26)); person.setGender("male"); // 序列化输出:文件内容为二进制格式,无法直接阅读 FileOutputStream out = new FileOutputStream("D:\\study\\test.txt"); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(person); oos.flush(); oos.close(); } /** * 反序列化:读取文本中的二进制信息 * @throws IOException * @throws ClassNotFoundException */ @Test public void testReverseSerializable() throws IOException, ClassNotFoundException{ FileInputStream in = new FileInputStream("D:\\study\\test.txt"); ObjectInputStream ois = new ObjectInputStream(in); Person person = (Person) ois.readObject(); System.out.println(person.getName()+" "+person.getAge()+" "+person.getGender()); }
输出:
zhang null male
age 属性不需序列化,所以无输出
4.
缺点:
1)只支持java语言,无法跨语言
2)序列化后的数据量比较大
3)执行序列化与反序列化的效率比较低
public class PersonObjectSeriable implements Serializable{ /** * */ private static final long serialVersionUID = -7328657292302834890L; private String name ; private transient Integer age ; private String gender ; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public PersonObjectSeriable() { super(); } }
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Test; public class SunSerializableTest { @Test public void testSerializable() throws IOException{ PersonObjectSeriable person = new PersonObjectSeriable(); person.setName("zhang"); person.setAge(26); person.setGender("male"); FileOutputStream out = new FileOutputStream("D:\\study\\java\\PersonObjectSerializable.txt"); ObjectOutputStream stream = new ObjectOutputStream(out); stream.writeObject(person); stream.flush(); stream.close(); } @Test public void testReverseSeriable() throws IOException, ClassNotFoundException{ FileInputStream in = new FileInputStream("D:\\study\\java\\PersonObjectSerializable.txt"); ObjectInputStream stream = new ObjectInputStream(in); PersonObjectSeriable person = (PersonObjectSeriable) stream.readObject(); System.out.println(person.getName()+" "+person.getAge()+" "+person.getGender()); } }
三、第三方序列化与反序列化框架
Avro
GoogleProtoBuffer
Thrift
1.GoogleProtoBuffer
生成与执行步骤
1)数据写入 .proto文件
2)编译成类文件
3)导入类文件进行序列化与反序列化
1)PersonProto.proto
package cn.study;// 文件的包路径,便于其他文件引用使用 option java_package = "com.study.rpc.ser.day.one.test"; // 生成的JAVA的类的包名 option java_outer_classname = "PersonProtos"; // JAVA文件名称 message Person{ // 声明类 // required 表示必须,optional 表示可选 // int32 对应 int 类型 // 1,2,3 ... 类中属性的唯一标识,按顺序添加,一旦添加不可更改;否则无法实现序列化 required string name = 1; optional int32 age = 2; required string gender = 3; }
2.编译类文件
解压:protoc.exe 安装包,见 下方
打开 win+r cmd --> cd .. 到安装包目录 --> 将上面的 PersonProto.proto 拷贝到该目录下
执行 protoc.ext --java_out . ./PersonProto.proto
在解压的目录中会出现相应的生成文件
拷贝文件至对应的包中
报错--因为未导入相应的JAR包 -- 见下面链接
3.调用API执行
@Test public void testSerializable() throws IOException{ Person person = Person.newBuilder() .setName("zhang").setAge(26).setGender("male").build(); FileOutputStream output = new FileOutputStream("D:\\study\\java\\PersonObjectProto.txt"); person.writeTo(output); }
序列化后的文件大小对比
@Test public void testReverseSerializable() throws IOException{ FileInputStream input = new FileInputStream("D:\\study\\java\\PersonObjectProto.txt"); Person person = Person.parseFrom(input); input.close(); System.out.println(person.getName()+" "+person.getAge()+" "+person.getGender()); }
4.扩展
若IO流改为网络流,
接收方以同样的方式对 PersonProto.proto 进行处理,语言可以不同,即不同语言间传递对象
三、RPC实现
描述:客户端发送数据,服务端接收,计算,返回结果给客户端
1.MathService.proto
package cn.study; option java_package = "com.study.rpc.ser.day.one"; option java_outer_classname = "MathServiceProto"; option java_generic_services = true ; // 是否包含服务 message Req{ // 定义第一个类,接收两个参数 required int32 num1 = 1; required int32 num2 = 2; } message Resp{ // 定义第二个类,返回值 required int32 result = 1; } service MathService{ // 定义接口,方法名称 add 参数 Req 返回值 Resp rpc add(Req) returns (Resp); }
生成对应的JAVA文件
2.
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import com.google.protobuf.BlockingRpcChannel; import com.google.protobuf.Descriptors.MethodDescriptor; import com.google.protobuf.Message; import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; import com.study.rpc.ser.day.one.MathServiceProto.MathService; import com.study.rpc.ser.day.one.MathServiceProto.MathService.BlockingInterface; import com.study.rpc.ser.day.one.MathServiceProto.Req; import com.study.rpc.ser.day.one.MathServiceProto.Resp; public class MathClient { /** * @param args * @throws ServiceException */ public static void main(String[] args) throws ServiceException { //stu -- 存根 -- 远程服务在本地的一个代表 //-- 具有和远程服务相同的远程调用方法 //-- 如果本地需要调用远程方法 找到存根调用对应方法即可 //-- 存根的底层会自动调用远程的方法来执行并获取结果并返回 //即:去取钱,但附近没有银行,但有ATM //ATM就相当于银行的一个远程服务在本地的代表;取钱 扣款 与去银行是一样的 BlockingInterface stu = MathService.newBlockingStub(new MyBlockingRPCchannel()); Req req = Req.newBuilder().setNum1(25).setNum2(26).build(); Resp resp = stu.add(null, req); System.out.println(resp.getResult()); } } class MyBlockingRPCchannel implements BlockingRpcChannel{ public Message callBlockingMethod(MethodDescriptor methodDescriptor, RpcController controller, Message req, Message resp) throws ServiceException { Socket socket = new Socket(); // 请求连接远程服务器 try { socket.connect(new InetSocketAddress("127.0.0.1", 9999)); // 发送请求给服务器 OutputStream out = socket.getOutputStream(); req.writeTo(out); socket.shutdownOutput(); // 接收服务器返回结果 InputStream in = socket.getInputStream(); resp = Resp.parseFrom(in); socket.shutdownInput(); return resp; } catch (IOException e) { e.printStackTrace(); }finally{ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } return null ; } }
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; import com.study.rpc.ser.day.one.MathServiceProto.MathService.BlockingInterface; import com.study.rpc.ser.day.one.MathServiceProto.Req; import com.study.rpc.ser.day.one.MathServiceProto.Resp; public class MathService { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { ServerSocket server = null ; Socket socket = null ; try { server = new ServerSocket(); server.bind(new InetSocketAddress(9999)); socket = server.accept(); InputStream input = socket.getInputStream(); Req req = Req.parseFrom(input); socket.shutdownInput(); MyMathService mathService = new MyMathService(); Resp resp = mathService.add(null, req); OutputStream out = socket.getOutputStream(); resp.writeTo(out); socket.shutdownOutput(); } catch (ServiceException e) { e.printStackTrace(); }finally{ socket.close(); server.close(); } } } class MyMathService implements BlockingInterface{ public Resp add(RpcController controller, Req request) throws ServiceException { int num1 = request.getNum1(); int num2 = request.getNum2(); int result = num1 + num2 ; Resp resp = Resp.newBuilder().setResult(result).build(); return resp; } }
- protobuf-java-2.6.1.jar (582.7 KB)
- 下载次数: 0
- protoc-2.6.1-win32.zip (1.2 MB)
- 下载次数: 0
相关推荐
RPC是一种远程调用的通信协议,例如dubbo、thrift等,我们在互联网高并发应用开发时候都会使用到类似的服务。本专题主要通过三个章节实现一个rpc通信的基础功能,来学习RPC服务中间件是如何开发和使用。章节内以源码...
linux使用,使用教程 linux下安装rpc.rstatd 1.rpc服务需rsh的支持,一般情况下rsh已安装。rpm -qa rsh查看。 2.右键另存为http://heanet.dl.sourceforge.net/sourceforge/rstatd/rpc.rstatd-4.0.1.tar.gz下载rpc....
<artifactId>jsonrpc4j <version>1.5.0 <groupId>javax.portlet <artifactId>portlet-api <version>2.0 Service代码: @JsonRpcService("/member") public interface MemberService { ... } 因为是基于...
ONC RPC 协议实现,根据.x接口文档生成JAVA代码,实现不同语言间的RPC调用
异步回调和同步回调相比,除了序列化组件和连接池组件,会多...异步回调能提高系统整体的吞吐量,具体使用哪种方式实现RPC-client,可以结合业务场景来选取(对时延敏感的可以选用同步,对吞吐量敏感的可以选用异步)。
C语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC...RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPCC语言头文件 RPC
2、使用Netty进行通讯(同节点RPC不走网络,直接入收件箱队列); 3、路由策略:随机路由、指定Key路由、资源Id路由、强制路由 4、使用ZK进行集群状态管理 备注: 1、使用自定义注解进行服务注册及辅助控制(线程...
JSON-RPC-Java是一个用Java来实现动态JSON-RPC的框架. 利用它内置的一个轻级量JSON-RPC JavaScripIt客户端,可以让你透明地在JavaScript中调用Java代码。JSON-RPC-Java可运行在Servlet容器中如Tomcat也可以运行在...
The RPC8201F is a single-chip/single-port 10/100Mbps Ethernet PHY transceiver that supports: • MII (Media Independent Interface) • RMII (Reduced Media Independent Interface) The RPC8201F implements ...
jsonrpc是一个基于Java的高性能开源RPC框架
详细讲解RPC
jsonrpc-c-master 基于 json rpc 1.0 纯C开发的服务端代码和示例
此插件支持在jmeter中以rpc方式对dubbo接口进行调用、rpc方式调用dubbo,解压包后里面有两个文件,一个是支持rpc的插件,另一个赠送idea中对数据库访问的插件 插件名称:jmeter-plugins-dubbo-2.7.7-jar-with-...
JSON-RPC-Java是一个用Java来实现动态JSON-RPC的框架. 利用它内置的一个轻级量JSON-RPC JavaScripIt客户端,可以让你透明地在JavaScript中调用Java代码。JSON-RPC-Java可运行在Servlet容器中如Tomcat也可以运行在...
拍拍贷微服务rpc框架源码.zip # 拍拍贷微服务体系 拍拍贷微服务体系是拍拍贷基础框架部总结内部微服务多年实践,参考、吸收大量业内解决方案形成的适合中型互联网公司的微服务解决方案。 拍拍贷微服务体系主要组成...
android-json-rpc是一个在android程序中使用的JSON-RPC客户端类库。它提供了一个简单的API来执行JSON-RPC服务调用
自定义rpc框架 ,用到了nettty zookeeper等等,模仿dubbo
rpc远程过程调用的手写简单源码 学习rpc通信的可以下载下来看看 很有帮助 包括客户端和服务端的网络调用 通信 序列化....等等
JsonRpc-Cpp - JSON-RPC implementation. * Copyright (C) 2008-2011 Sebastien Vincent * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser ...