dubbo序列化问题(一)浮点数问题 转
dubbo是一个分布式服务框架,在国内比较常用,在开发过程中遇到一个浮点数反序列化问题。
问题描述,当参数是float类型的3.7,反序列化却得到了一个double类型的值:3.700000047683716。
然后,我写了个测试程序:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
public class TestHessionLite {
public static void main(String[] args) throws IOException {
HashMap<String,Float> map=new HashMap<String,Float>();
Float loat=new Float(3.7);
map.put("3.7", loat);
byte[] aa=TestHessionLite.serialize(map);
Object mm=TestHessionLite.deserialize(aa);
System.out.println(mm.toString());
}
public static byte[] serialize(Object obj) throws IOException{
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output ho = new Hessian2Output(os);
byte[] cc = null;
try {
if(obj==null) throw new NullPointerException();
ho.writeObject(obj);
ho.flushBuffer();
cc=os.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}finally{
ho.close();
}
return cc;
}
public static Object deserialize(byte[] by) throws IOException{
try {
if(by==null) throw new NullPointerException();
ByteArrayInputStream is = new ByteArrayInputStream(by);
Hessian2Input hi = new Hessian2Input(is);
return hi.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
输出结果为
{3.7=3.700000047683716}
然后由分别使用3.5、3.6进行测试
{3.6=3.5999999046325684}
{3.5=3.5}
经过测试,并不是所有小数都有问题,部分小数会出现序列化问题。
我的dubbo服务序列化使用的是dubbo默认的hession2,而使用hessian2协议,也就是传输对象序列化,它是二进制的RPC协议。
经过分析,问题应该是出在了十进制浮点数转二进制。
后面又查看了相关资料,以及写了十进制和二进制互转的测试程序发现,就是不分小数在float单精度下是无法表示出来的。具体原因可以见下面资料http://blog.csdn.net/zcczcw/article/details/7362473。
如果将float,改成double,就不存在刚才精度问题了,因为double是双精度,可以保存64位二进制;
但是当小数点超过8位时,double也会被截取。
而是用kryo进行序列化则不会出现上面问题,因为kryo不是通过二进制存储,是通过字节数组来进行存储,这样可以保证数据不用进行转化。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import org.apache.commons.codec.binary.Base64;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.JavaSerializer;
public class TestKryo {
public static void main(String[] args) {
HashMap<String,Float> map=new HashMap<String,Float>();
Float loat=new Float(3.7);
map.put("value", loat);
String aa=TestKryo.serialize(map);
Object mm=TestKryo.deserialize(aa,HashMap.class);
System.out.println(mm.toString());
}
private static <T extends Serializable> String serialize(T obj) {
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.register(obj.getClass(), new JavaSerializer());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Output output = new Output(baos);
kryo.writeClassAndObject(output, obj);
output.flush();
output.close();
byte[] b = baos.toByteArray();
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return new String(new Base64().encode(b));
}
@SuppressWarnings("unchecked")
private static <T extends Serializable> T deserialize(String obj,
Class<T> clazz) {
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.register(clazz, new JavaSerializer());
ByteArrayInputStream bais = new ByteArrayInputStream(
new Base64().decode(obj));
Input input = new Input(bais);
return (T) kryo.readClassAndObject(input);
}
}
dubbo序列化问题(一)浮点数问题 转的更多相关文章
- 热部署环境下,dubbo序列化的bug和优化
一.问题的发现与解决 (1) 在热部署下,使用dubbo的序列化一个pojo对象,反序列化时报错:ClassNotFoundException. 最后发现原因是我们的框架选择使用了java序列 ...
- Dubbo序列化多个CopyOnWriteArrayList对象变成同一对象的一个大坑!!
环境: win10 + jdk 1.8 + dubbo 2.5.10 问题描述: 当一个对象(此对象内包含多个CopyOnWriteArrayList对象) 作为参数调用RPC接口后, 服务提供者拿到 ...
- dubbo序列化
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. dubbo 支持多种序列化方式并且序列化是和协议相对应的.比如:dubbo协议的 dub ...
- dubbo序列化hibernate.LazyInitializationException could not initialize proxy - no Session懒加载异常的解决
dubbo序列化,hibernate.LazyInitializationException could not initialize proxy - no Session懒加载异常的解决 转载声明: ...
- dubbo 序列化 问题 属性值 丢失 ArrayList 解决
参考文章:http://blog.csdn.net/wanyanxgf/article/details/6944733 http://tianya23.blog.51cto.com/1081650/5 ...
- dubbo序列化的一点注意
最近工作中遇见了一个小问题,在此记录一下,大致是这样的,有一父类,有一个属性traceId,主要是记录日志号,这样可以把所有日志串起来,利于排查问题,所有的pojo对象继承于此,但是其中一同事在子类p ...
- dubbo 序列化机制之 hessian2序列化实现原理分析
对于远程通信,往往都会涉及到数据持久化传输问题.往大了说,就是,从A发出的信息,怎样能被B接收到相同信息内容!小点说就是,编码与解码问题! 而在dubbo或者说是java的远程通信中,编解码则往往伴随 ...
- Dubbo 序列化协议 5 连问,你接得住不?
1)dubbo 支持哪些通信协议? 2)支持哪些序列化协议? 3)说一下 Hessian 的数据结构? 4)PB 知道吗? 5)为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dub ...
- 在Dubbo中使用高效的Java序列化(Kryo和FST)
在Dubbo中使用高效的Java序列化(Kryo和FST) 作者:沈理 文档版权:Creative Commons 3.0许可证 署名-禁止演绎 完善中…… TODO 生成可点击的目录 目录 序列化漫 ...
- Dubbo + Kryo 实现高速序列化
Dubbo 中的序列化 Dubbo RPC 是 Dubbo 体系中最核心的一种高性能.高吞吐量的远程调用方式,可以称之为多路复用的 TCP 长连接调用: 长连接:避免了每次调用新建 TCP 连接,提高 ...
随机推荐
- MestReNova14.0中文版安装教程
MestReNova 14是一款专业级的核磁共振(NMR)与质谱(MS)数据分析软件,专注于化合物结构解析和验证.该软件以卓越的谱图处理能力和智能化算法为核心,提供自定义参数调整.自动峰识别.精准积分 ...
- Zabbix---数据库表分区
1) 查询zabbix数据库中各种表存储的大小和行数: mysql> select table_name, (data_length + index_length)/1024/1024 as t ...
- 08-Python迭代器与生成器
迭代器 什么是迭代器 迭代是Python最强大的功能之一,是访问序列中元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器 ...
- 采集modbus设备数据转wincc项目案例
1 文档说明 1. 网关设置采集Modbus设备数据 2. 把采集的数据转成profinet协议转发给wincc. 2 VFBOX网关工作原理 VFBOX网关是 ...
- python基础-元组tuple( )
元组的定义和操作 元组的特性: 元素数量 支持多个 元素类型 任意 下标索引 支持 重复元素 支持 可修改性 不支持 数据有序 是 使用场景 不可修改.可重复的 一批数据记录场景 # 定义元组 ...
- 案例分享!RK3568 + FPGA多通道AD采集处理与显示
案例展示 测试数据汇总 表 1 本文带来的是基于瑞芯微RK3568J + 紫光同创Logos-2的ARM + FPGA多通道AD采集处理与显示案例. 本次案例演示的开发环境如下: Wind ...
- Android发布,全志T507四核A53@1.4GHz工业平台,含税仅168元起!
近年来,Android系统在工业自动化.仪器仪表.医疗.安防等工业领域的使用日趋广泛.为了满足广大工业用户的需求,创龙科技针对全志T507-H工业平台进行了Android系统适配. 创龙科技T507- ...
- 【经验分享】全志科技官方Ubuntu16.04根文件系统镜像的替换和测试方法
本文主要基于全志A40i开发板--TLA40i-EVM,一款基于全志科技A40i处理器设计的4核ARM Cortex-A7高性能低功耗国产评估板,演示Ubuntu根文件系统镜像的替换和测试方法. 创 ...
- 使用C#对华为IPC摄像头二次开发(二)
上一篇我们实现了用SDK登录摄像头并实现预览(https://www.cnblogs.com/wdw984/p/13564195.html),这次我们实现通过SDK调用摄像头本身自带的人脸抓拍功能. ...
- JVM学习笔记-如何在IDEA打印JVM的GC日志信息
若要在Idea上打印JVM相应GC日志,其实只需在Run/Debug Configurations上进行设置即可. 拿<深入Java虚拟机>书中的3-7代码例子来演示,如 1 public ...