GZIPOutputStream & GZIPInputStream 数据压缩&解压

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

数据压缩&解压

  • 前言
  • 一、最终走上了压缩的路 GZIPOutputStream
  • 二、收到数据进行解压 GZIPInputStream
  • 三、测试Demo
  • 四、验证结果
  • 总结


前言

最近接手了一批性能优化…
遇到这样一个接口:已经把能优化的部分都优化了(包括业务逻辑批处理、数据预处理、数据缓存、减少查表字段、加表索引等)。

但是,这个接口里有个外部调用会去查询3000+数据,得到的数据大小约为1.5M,耗时:2s
外部系统接口执行时间为:0.8s
那么就意味着...数据传输消耗了:1s+

解决方法:
外部系统将出参:压缩
自己系统将得到数据:解压
从而减少数据传输的时间

其他方面:减少出参的冗余字段

一、最终走上了压缩的路 GZIPOutputStream

将json字符串压缩,再加密(保证安全性)

    public static String getCompressionStr(String jsonStr) throws Exception {
        
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gos = new GZIPOutputStream(out);

        gos.write(jsonStr.getBytes(StandardCharsets.UTF_8));
        gos.close();

        byte[] encodeBytes = Base64.getEncoder().encode(out.toByteArray());
        return new String(encodeBytes);
   

二、收到数据进行解压 GZIPInputStream

将收到的字符串进行解密,再解压

    public static String getDecompressionStr(String compressionStr) throws Exception {
        byte[] decodedBytes = Base64.getDecoder().decode(compressionStr);
        
        GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(decodedBytes));
        BufferedReader bf = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8));

        StringBuilder outStr = new StringBuilder();
        String line;

        while ((line = bf.readLine()) != null) {
            outStr.append(line);
        }

        return StringEscapeUtils.unescapeJava(outStr.toString());
    }

三、测试Demo

**** 重要提示 *******
1:验证的时候,日志记得分开打印。日志很大,不然不好查看日志数据
2:调整idea的 setting -> Editor -> General -> Console
Override console cycle buffer size 调整为10240

public class Demo {

    public static void main(String[] args) {
        String jsonStr = getJsonStr();
        System.out.println(jsonStr);
        
        try {
            String compressionStr = getCompressionStr(jsonStr);
//            System.out.println(compressionStr);

            String decompressionStr = getDecompressionStr(compressionStr);
//            System.out.println(decompressionStr);

            List<User> users = JSONArray.parseArray(decompressionStr, User.class);
            System.out.println(users.get(100));
            System.out.println(users.get(100).getUserId());
            System.out.println(users.get(100).getName());
            System.out.println(users.get(100).getAddress());


        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
	
	/**
	 * 随便创建10000个对象,userId,name,address
	 **/
    public static String getJsonStr() {
        List<User> users = new ArrayList<>();
        String address = "让我感到为难的 是挣扎的自由\n" +
                "分别总是在九月 回忆是思念的愁\n" +
                "深秋嫩绿的垂柳 亲吻着我额头\n" +
                "在那座阴雨的小城里 我从未忘记你\n" +
                "成都 带不走的 只有你\n" +
                "和我在成都的街头走一走 喔…\n" +
                "直到所有的灯都熄灭了也不停留";
        for (int i = 0; i < 10000; i++) {
            users.add(new User((long) (i + 1), "张三" + (i + 1), address));
        }
        return JSONArray.toJSONString(users);
    }

四、验证结果

GZIPOutputStream & GZIPInputStream 数据压缩&解压_第1张图片
1:10000个对象的大小为 3328KB
2:压缩后的大小为 80KB
3:解压后的大小为 3328KB
4:解压后数据可转为对象(支持嵌套对象),正常使用

            List<User> users = JSONArray.parseArray(decompressionStr, User.class);

            System.out.println(users.get(100));
            System.out.println(users.get(100).getUserId());
            System.out.println(users.get(100).getName());
            System.out.println(users.get(100).getAddress());
    对应的输出结果为:
    
User(userId=101, name=张三101, address=让我感到为难的 是挣扎的自由
分别总是在九月 回忆是思念的愁
深秋嫩绿的垂柳 亲吻着我额头
在那座阴雨的小城里 我从未忘记你
成都 带不走的 只有你
和我在成都的街头走一走 喔…
直到所有的灯都熄灭了也不停留)

101

张三101

让我感到为难的 是挣扎的自由
分别总是在九月 回忆是思念的愁
深秋嫩绿的垂柳 亲吻着我额头
在那座阴雨的小城里 我从未忘记你
成都 带不走的 只有你
和我在成都的街头走一走 喔…
直到所有的灯都熄灭了也不停留
            

总结

性能优化是真的心累。
特别是产品经理的沙雕设计(一次性拿3000条数据就不合理,为了强行实现功能)
最后说下优化的结果:产线上12s的接口,最终降低至2s

另外说明下:
文章内除了StringEscapeUtils以外,仅用到了jdk自带的库

但是在lang3里StringEscapeUtils已经Deprecated了。可以换成common-text
import org.apache.commons.text.StringEscapeUtils;
//import org.apache.commons.lang3.StringEscapeUtils;

    
        org.apache.commons
        commons-text
        1.10.0
    

你可能感兴趣的:(java)