从零学Netty(十二)Netty基于Protostuff(Protocol) 序列化

待我称王封你为后i 2022-12-21 14:54 340阅读 0赞

初探Protostuff的使用

最近看到了一个叫做Protostuff的库,是基于谷歌Protocal Buffer的序列化库,之前了解过Protocol Buffer,对学习了一些资料后,写了个demo

什么是Protocol Buffer?

Protocol Buffer是谷歌出品的一种数据交换格式,独立于语言和平台,类似于json。Google提供了多种语言的实现:java、c++、go和python。对象序列化城Protocol Buffer之后可读性差,但是相比xml,json,它占用小,速度快。适合做数据存储或 RPC 数据交换格式。

Java序列化库 - Protostuff

相对我们常用的json来说,Protocol Buffer门槛更高,因为需要编写.proto文件,再把它编译成目标语言,这样使用起来就很麻烦。但是现在有了protostuff之后,就不需要依赖.proto文件了,他可以直接对POJO进行序列化和反序列化,使用起来非常简单。

引入依赖

  1. <dependency>
  2. <groupId>io.protostuff</groupId>
  3. <artifactId>protostuff-core</artifactId>
  4. <version>1.7.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.protostuff</groupId>
  8. <artifactId>protostuff-runtime</artifactId>
  9. <version>1.7.2</version>
  10. </dependency>

工具类

  1. import io.protostuff.LinkedBuffer;
  2. import io.protostuff.ProtostuffIOUtil;
  3. import io.protostuff.Schema;
  4. import io.protostuff.runtime.RuntimeSchema;
  5. import java.util.Arrays;
  6. import java.util.Map;
  7. import java.util.Objects;
  8. import java.util.concurrent.ConcurrentHashMap;
  9. public class ProtostuffUtils {
  10. /**
  11. * 缓存Schema
  12. */
  13. private static Map<Class<?>, Schema<?>> schemaCache = new ConcurrentHashMap<>();
  14. /**
  15. * 序列化方法,把指定对象序列化成字节数组
  16. *
  17. * @param obj
  18. * @param <T>
  19. * @return
  20. */
  21. @SuppressWarnings("unchecked")
  22. public static <T> byte[] serialize(T obj) {
  23. Class<T> clazz = (Class<T>) obj.getClass();
  24. Schema<T> schema = getSchema(clazz);
  25. LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
  26. byte[] data;
  27. try {
  28. data = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
  29. } finally {
  30. buffer.clear();
  31. }
  32. return data;
  33. }
  34. /**
  35. * 反序列化方法,将字节数组反序列化成指定Class类型
  36. *
  37. * @param data
  38. * @param clazz
  39. * @param <T>
  40. * @return
  41. */
  42. public static <T> T deserialize(byte[] data, Class<T> clazz) {
  43. Schema<T> schema = getSchema(clazz);
  44. T obj = schema.newMessage();
  45. ProtostuffIOUtil.mergeFrom(data, obj, schema);
  46. return obj;
  47. }
  48. @SuppressWarnings("unchecked")
  49. private static <T> Schema<T> getSchema(Class<T> clazz) {
  50. Schema<T> schema = (Schema<T>) schemaCache.get(clazz);
  51. if (Objects.isNull(schema)) {
  52. //这个schema通过RuntimeSchema进行懒创建并缓存
  53. //所以可以一直调用RuntimeSchema.getSchema(),这个方法是线程安全的
  54. schema = RuntimeSchema.getSchema(clazz);
  55. if (Objects.nonNull(schema)) {
  56. schemaCache.put(clazz, schema);
  57. }
  58. }
  59. return schema;
  60. }
  61. public static void main(String[] args){
  62. //创建一个user对象
  63. User user = User.builder().id("1").age(20).name("张三").desc("programmer").build();
  64. //创建一个Group对象
  65. Group group = Group.builder().id("1").name("分组1").user(user).build();
  66. //使用ProtostuffUtils序列化
  67. byte[] groupdata = ProtostuffUtils.serialize(group);
  68. System.out.println("序列化后:" + Arrays.toString(groupdata));
  69. Group result = ProtostuffUtils.deserialize(groupdata, Group.class);
  70. System.out.println("反序列化后:" + result.toString());
  71. byte[] userdata = ProtostuffUtils.serialize(user);
  72. System.out.println("序列化后:" + Arrays.toString(userdata));
  73. User result2 = ProtostuffUtils.deserialize(userdata, User.class);
  74. System.out.println("反序列化后:" + result2.toString());
  75. }
  76. }

对象类

  1. @Data
  2. @Builder
  3. public class Group {
  4. private String id;
  5. private String name;
  6. private User user;
  7. }
  8. @Data
  9. @Builder
  10. public class User {
  11. private String id;
  12. private String name;
  13. private Integer age;
  14. private String desc;
  15. }

测试结果

20201116180005157.png

结合netty应用

网上已经有了较好的文章 我就不造轮子了

netty结合Protostuff传输对象案例,单机压测秒级接收35万个对象

发表评论

表情:
评论列表 (有 0 条评论,340人围观)

还没有评论,来说两句吧...

相关阅读

    相关 开始netty

    Netty概述: 1、netty是基于Java NIO的网络应用框架,client-server框架 2、Netty是一个高性能、异步事件驱动的NIO框架,它提供了对T