一段时间后,在对我的数据库及其REST Api进行压力测试之后,发生了以下问题。
我们通过JPA / Hibernate将图像另存为 byte数组在Mysql数据库中,如下所示:
@Column(columnDefinition = "MEDIUMBLOB")
private byte[] photo;
它应该工作,除非有很多高质量的图像,而我想检索所有图像。然后响应时间太长,事件邮递员被卡住。
因此,我正在寻找解决方案,以缩小这些字节数组。 有没有一种方法可以将图像压缩为字节数组? 还是也许是分页(不是我认为必须解决的最佳方法)吗?
谢谢。
答案 0 :(得分:0)
我假设您面临的问题是,您在同一查询中读取了许多图像,并且它们占用了过多的内存,从而导致垃圾回收和其他问题。压缩图像无济于事,因为您需要在将其返回给客户端之前再次对其进行解压缩,而且大多数图像格式已经被压缩。
您可以改为查看streaming,在这里您无需将所有匹配的图像从数据库中读取到内存中,而是一次处理一个。确保您还流传输发送到客户端的数据。如果操作正确,则可以降低内存使用量,并且可以在读取其他图像之前将第一张图像发送给客户端,从而减少了写入第一个字节的时间并使响应迅速。
或者按照建议的注释之一操作,先读取元数据,然后一次读取一张图像的完整图像数据。
答案 1 :(得分:0)
如果图像为JPEG,则需要按每个级别进行照片质量压缩:反之则为高压缩和低质量。您可以/应该限制图像大小(宽度和高度)。请参阅ImageIO的ImageWriter和质量设置。
对于BLOB,您应该添加:
@Lob
@Column(columnDefinition = "MEDIUMBLOB")
private byte[] photo;
可能最好将image字段放在自己的数据库表中,这样可以更快地查询原始表。
如前所述,还可以将图像存储在文件系统上,也许使用生成的唯一ID:
UUID uuid = UUID.randomUUID();
String fileName = uuid.toString() + ".jpg";
通常,使用byte[]
字段或本地对象不是最佳选择,因为它不必要地向服务器充电。在JPA之外,立即读取和写入响应会更好。如果您想要数据库中的内容,则可能是本机查询。