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序列化问题(一)浮点数问题 转的更多相关文章

  1. 热部署环境下,dubbo序列化的bug和优化

    一.问题的发现与解决 (1)     在热部署下,使用dubbo的序列化一个pojo对象,反序列化时报错:ClassNotFoundException. 最后发现原因是我们的框架选择使用了java序列 ...

  2. Dubbo序列化多个CopyOnWriteArrayList对象变成同一对象的一个大坑!!

    环境: win10 + jdk 1.8 + dubbo 2.5.10 问题描述: 当一个对象(此对象内包含多个CopyOnWriteArrayList对象) 作为参数调用RPC接口后, 服务提供者拿到 ...

  3. dubbo序列化

    序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. dubbo 支持多种序列化方式并且序列化是和协议相对应的.比如:dubbo协议的 dub ...

  4. dubbo序列化hibernate.LazyInitializationException could not initialize proxy - no Session懒加载异常的解决

    dubbo序列化,hibernate.LazyInitializationException could not initialize proxy - no Session懒加载异常的解决 转载声明: ...

  5. dubbo 序列化 问题 属性值 丢失 ArrayList 解决

    参考文章:http://blog.csdn.net/wanyanxgf/article/details/6944733 http://tianya23.blog.51cto.com/1081650/5 ...

  6. dubbo序列化的一点注意

    最近工作中遇见了一个小问题,在此记录一下,大致是这样的,有一父类,有一个属性traceId,主要是记录日志号,这样可以把所有日志串起来,利于排查问题,所有的pojo对象继承于此,但是其中一同事在子类p ...

  7. dubbo 序列化机制之 hessian2序列化实现原理分析

    对于远程通信,往往都会涉及到数据持久化传输问题.往大了说,就是,从A发出的信息,怎样能被B接收到相同信息内容!小点说就是,编码与解码问题! 而在dubbo或者说是java的远程通信中,编解码则往往伴随 ...

  8. Dubbo 序列化协议 5 连问,你接得住不?

    1)dubbo 支持哪些通信协议? 2)支持哪些序列化协议? 3)说一下 Hessian 的数据结构? 4)PB 知道吗? 5)为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dub ...

  9. 在Dubbo中使用高效的Java序列化(Kryo和FST)

    在Dubbo中使用高效的Java序列化(Kryo和FST) 作者:沈理 文档版权:Creative Commons 3.0许可证 署名-禁止演绎 完善中…… TODO 生成可点击的目录 目录 序列化漫 ...

  10. Dubbo + Kryo 实现高速序列化

    Dubbo 中的序列化 Dubbo RPC 是 Dubbo 体系中最核心的一种高性能.高吞吐量的远程调用方式,可以称之为多路复用的 TCP 长连接调用: 长连接:避免了每次调用新建 TCP 连接,提高 ...

随机推荐

  1. 详解Web应用安全系列(2)注入漏洞之XSS攻击

    上一篇介绍了SQL注入漏洞,今天我们来介绍另一个注入漏洞,即XSS跨站脚本攻击.XSS 全称(Cross Site Scripting) 跨站脚本攻击, 是Web应用中常见的漏洞.指攻击者在网页中嵌入 ...

  2. 莫名其妙的bug——Segmentation fault

    vscode出现Segmentation fault异常,但是没有问题报错(如上) 先说原因:cout << dp[m]; m没有输入,一个空定义(空指针) 难受啊,有一次cf因为这个bu ...

  3. 韦东山freeRTOS系列教程之【第八章】事件组(event group)

    目录 系列教程总目录 概述 8.1 事件组概念与操作 8.1.1 事件组的概念 8.1.2 事件组的操作 8.2 事件组函数 8.2.1 创建 8.2.2 删除 8.2.3 设置事件 8.2.4 等待 ...

  4. yb课堂 新版VueCli 4.3创建vue项目,Vue基础语法入门 《二十九》

    Vue模版语法开发起步 基于HTML的模版语法,允许声明式地将DOM绑定至底层Vue实例的数据 用简洁的模版语法来声明式的将数据渲染进DOM的系统 结合响应系统,在应用状态改变时,Vue能够智能地计算 ...

  5. CF414B

    这道题dp状态表示需要一点思维,而且会卡到时间复杂度 之前题主用的是试除法,时间复杂度为n^2.5,然后被卡了,但是换一种写法就是对的 #include <iostream> #inclu ...

  6. 全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系,你知道多少?

    全网最适合入门的面向对象编程教程:09 类和对象的 Python 实现-类之间的关系,你知道多少? 摘要: 本文主要对类之间的关系进行了基本介绍,包括继承.组合.依赖关系,并辅以现实中的例子加以讲解, ...

  7. tp6 uniapp跨越问题

    自己写一个简单的中间件

  8. Django配置为连接到Microsoft SQL Server

    可以将Django配置为连接到Microsoft SQL Server 2019.为此,你需要更改数据库设置中的一些配置选项.首先,确保你已经安装了 django 和 pyodbc 这两个库:   p ...

  9. [oeasy]python0116_文字的起源_苏美尔文明_楔形文字_两河流域

    文字起源 回忆上次内容 上次回顾了西里尔字符的编码过程 KOI-7 KOI-8   ISO-8859 系列进行总结 字符扩展 ascii 共 16 种 由iso组织制定 从 iso-8859-1 到 ...

  10. 免费的壁纸API

    最近在给EasyDesktop增加背景的功能, 考虑自己在服务器上部署壁纸, 维护成本比较高, 就找了几个免费的壁纸接口, 体验还不错, 这里简单记录一下. 1.Bing壁纸API 地址是: http ...