Java 后端生成海报图片遇到了性能压力,求指教~

253 天前
 acbingo

因为我们服务基本都是 Java 框架,所以当初也是想当然的用 Java 原生的图片编辑能力来画图实现需求,随着业务增长,性能越来越吃紧,而且需求也越来越复杂,需要画越来越复杂的图,Java 越来越难画了

求大家指教,有什么成熟的后端服务方案,画图又快,还能画一些复杂的海报图呢。可以考虑用别的语言

4199 次点击
所在节点    Java
44 条回复
wingoo
253 天前
不是太复杂的文字和图片的组合可以考虑直接用公有云的水印功能
youknowiam
253 天前
我之前使用过 headless 浏览器导出过 pdf ,内存吃紧,不是个好方案。画图的话我之前写过类似用 Rust ssr 导出 echarts 为 svg 的功能,使用的是 https://github.com/yuankunzhang/charming 这个库改了下源码支持 html ,速度还挺快就几 ms ,导出为 png 的话稍微慢点,需要渲染图片。
sketcherly
253 天前
既然服务端是异步生成的,考虑是不是可以客户端异步,盲猜应该是可以的
GreatAuk
253 天前
@securityCoding 这会感觉性能压力更大
leaflxh
253 天前
让客户端画,实时性要求不高就上队列一个一个处理吧,用户等一会
mightybruce
253 天前
前端画图很快的, 用 rust 、c++ 等语言编译成 wasm 模块执行可以大大减少服务器的压力。
现在 b 站 用 ffmpeg 在客户端处理视频比过去快了很多倍。
webgl 和 wasm 比较成熟,推荐几个比如
https://www.scichart.com/blog/surpassing-limits-javascript-bigdata-webassembly/


更新的技术比如 webgpu 通过直接调用 GPU 方式可以大大加速密集型计算,不过现在这个还处于浏览器实验性的 API
cdlnls
253 天前
如果是因为机器性能和部署的原因的话,看了你的描述,我感觉可以试试把画图这部份抽出来部署到函数计算上。

这样成本可能会比现在降低很多( 20 台服务器说多也不多,说少也不少了),性能的话可以写个 demo 测测看情况,实例数量可以随着并发增加而增加,而且不需要维护。
cdlnls
253 天前
另外也是建议你先检查一下你这里说的”性能压力“是什么,看看具体性能的瓶颈在哪里,有时候一个代码上的小优化,就可以起到一个立竿见影的效果,也有时候调整一下服务器规格,比如增加内存使用读写更快的磁盘也能在某些情况下大大的缓解性能压力。
jiangzm
253 天前
最优肯定是放前端来处理,web 端通过 html 转 canvas 再转 image ,所见即所得。

如果是非前端即时生成或者非 web 端(小程序),通过后端(nodejs)调用 puppeteer 生成,为了提高效率肯定要加一层对象缓存。

根据模板 html+渲染数据 json 计算出当次内容 hash 值,判断是否已在对象仓库中,有即返回资源的 CDN 地址,不存在再渲染上传到对象仓库返回对应资源地址。( bucket 根据需求设置过期时间,防止存量过大问题)
coolcoffee
253 天前
就没有人提到 serverless 吗? puppeteer 配合 aws lambda ,压测 QPS 有 120 ~ 160 ,针对大部分场景都足够了。
OldCarMan
253 天前
🤔个人觉得可以这样,4 步走:

1.解决业务可扩展性问题:可以让前端使用图片编辑器生成图片信息,如果业务需求是后续不可编辑可以生成截图保存,如果是可编辑的可以把整个编辑后的图片 html 保存,建议把其上传到对象存储;

2.前端将图片编辑结果提交给后端服务,后端将 html 信息+业务参数封装,丢到消息队列里面。

3.html->图片,这一步可以考虑各种各样的处理方式,根据自己的要求(比如性能要求)去搜索相关的库,比如 html to image java/nodejs/c++/rust 等等,生产完将结果上传并丢回消息队列里面,这个胶水层服务提供:消息队列消费,生产;图片处理;图片上传的服务。

4.后端服务消费胶水层服务产生的图片 url

目的:1.解决扩展性; 2.吞吐量; 3.图片业务与主业务的解耦,数据量大时,图片业务硬件资源吃的较多,可以单独升级图片处理服务。
WashFreshFresh
253 天前
建议拆分成单独服务部署,任务调度好应该能缓解压力,然后就是优化代码。之前的公司做项目的时候,有个转图生成各种格式各种分辨率海报的功能,做微服务改造的时候就是拆分成了单个服务,部署了 10+台机器,然后优化了下代码,效率杠杠的。
MrDarnell
253 天前
@acbingo 不晓得你要画多复杂的图,但正常情况下前端画图都是瞬间完成的,不存在你说的等待,你可以留意你玩的游戏,普遍可以达到 64 帧/s 以上,而一个帧就是一次全屏绘图,你感觉到等待了吗?
janus77
253 天前
改 c++,然后独立部署,外部调用
seanlin5
253 天前
@securityCoding 相当于写好 H5 模板,在服务器起一个 headless chrome 实现截图,然后将截图保存成 url ,通过接口方式回传给前端显示?
zoharSoul
253 天前
html 模板 填上动态的文字后, 直接渲染就行啊
securityCoding
253 天前
@seanlin5 是的,核心就是 headless chrome 来渲染 H5
airqj
253 天前
用 wasm,让前端来画
airqj
253 天前
而且现在 wasm 是支持多线程的
应该慢不了
fengpan567
253 天前
让前端画呗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1030721

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX