因为我们服务基本都是 Java 框架,所以当初也是想当然的用 Java 原生的图片编辑能力来画图实现需求,随着业务增长,性能越来越吃紧,而且需求也越来越复杂,需要画越来越复杂的图,Java 越来越难画了
求大家指教,有什么成熟的后端服务方案,画图又快,还能画一些复杂的海报图呢。可以考虑用别的语言
1
cz5424 253 天前 via iPhone
用前端画,吃用户手机 cpu
|
2
cz5424 253 天前 via iPhone
后端画图避免不了性能问题
|
4
justNoBody 253 天前
原生指的是 java.awt.Graphics2D 么?
|
5
securityCoding 253 天前
海报用 H5 实现输出 html 文件,后台起一个 headless chrome 进程直接本地渲染最后调用 sdk 截图 api 就好了,封装成服务很方便
|
8
cz5424 253 天前 via iPhone
@securityCoding Chrome 并发也是一个很大的问题,内存大户
|
9
acbingo OP @securityCoding 也考虑过用 puppeteer ,但是 pptr 太吃内存了,而且速度也没快多少。倒是解决了画复杂海报的痛点
|
10
cz5424 253 天前 via iPhone
前端画图,像素根据手机宽度生成低分辨率的,速度应该不慢
|
11
securityCoding 253 天前
|
12
acbingo OP 我甚至在想,能不能上一些 GPU 加速呢🤔🤔,稍微研究了一下,感觉上手成本都比较高😂
|
13
securityCoding 253 天前 1
@acbingo #9 封装成独立服务堆数量就是了,海报别再 java 画了这是条不归路,ui 同学走查能搞死你
|
14
acbingo OP @securityCoding 现在已经部了 20 台了,业务还会有几倍的增长空间,所以还是想看看能不能找到性能更好的方案。。。另外现在业务想画一些复杂的,比如说画些饼图、曲线图,之前用 Java 写写字、拼拼图还行,但是让我生成饼图就有点功力不够了😂
|
15
acbingo OP |
16
darkengine 253 天前
考虑下把这个活儿胶水给其他适合做图像处理的语言搞吧
|
17
securityCoding 253 天前
@acbingo #14 另外就是纯 web 的方案了这个不太了解不过我之前有同事实现过,headless chrome 方案我之前做了一版上线稳如老狗,k8s hpa 一开不需要操啥心
|
18
insubtemp 253 天前
前端画,前端也能异步提前生成,这不就省了 20 台服务器
|
19
night98 253 天前
你海报是什么类型的海报,这点你要说清楚,你生成的图片是底图加用户信息的这种,还是每次生成的图片都不一样?解决方案也都不一样的
|
20
openmynet 253 天前 1
考虑性能的话最佳选择就是 c++或 rust ,rs 的话这有个库 https://crates.io/crates/charts-rs ,支持 json 格式数据直接生成图表方便对接。或者是用 plotters 实现更复杂的操作。
|
21
wingoo 253 天前
不是太复杂的文字和图片的组合可以考虑直接用公有云的水印功能
|
22
youknowiam 253 天前 2
我之前使用过 headless 浏览器导出过 pdf ,内存吃紧,不是个好方案。画图的话我之前写过类似用 Rust ssr 导出 echarts 为 svg 的功能,使用的是 https://github.com/yuankunzhang/charming 这个库改了下源码支持 html ,速度还挺快就几 ms ,导出为 png 的话稍微慢点,需要渲染图片。
|
23
sketcherly 253 天前 via Android
既然服务端是异步生成的,考虑是不是可以客户端异步,盲猜应该是可以的
|
24
GreatAuk 253 天前
@securityCoding 这会感觉性能压力更大
|
25
leaflxh 253 天前
让客户端画,实时性要求不高就上队列一个一个处理吧,用户等一会
|
26
mightybruce 253 天前 1
前端画图很快的, 用 rust 、c++ 等语言编译成 wasm 模块执行可以大大减少服务器的压力。
现在 b 站 用 ffmpeg 在客户端处理视频比过去快了很多倍。 webgl 和 wasm 比较成熟,推荐几个比如 https://www.scichart.com/blog/surpassing-limits-javascript-bigdata-webassembly/ 更新的技术比如 webgpu 通过直接调用 GPU 方式可以大大加速密集型计算,不过现在这个还处于浏览器实验性的 API |
27
cdlnls 253 天前
如果是因为机器性能和部署的原因的话,看了你的描述,我感觉可以试试把画图这部份抽出来部署到函数计算上。
这样成本可能会比现在降低很多( 20 台服务器说多也不多,说少也不少了),性能的话可以写个 demo 测测看情况,实例数量可以随着并发增加而增加,而且不需要维护。 |
28
cdlnls 253 天前
另外也是建议你先检查一下你这里说的”性能压力“是什么,看看具体性能的瓶颈在哪里,有时候一个代码上的小优化,就可以起到一个立竿见影的效果,也有时候调整一下服务器规格,比如增加内存使用读写更快的磁盘也能在某些情况下大大的缓解性能压力。
|
29
jiangzm 253 天前
最优肯定是放前端来处理,web 端通过 html 转 canvas 再转 image ,所见即所得。
如果是非前端即时生成或者非 web 端(小程序),通过后端(nodejs)调用 puppeteer 生成,为了提高效率肯定要加一层对象缓存。 根据模板 html+渲染数据 json 计算出当次内容 hash 值,判断是否已在对象仓库中,有即返回资源的 CDN 地址,不存在再渲染上传到对象仓库返回对应资源地址。( bucket 根据需求设置过期时间,防止存量过大问题) |
30
coolcoffee 253 天前
就没有人提到 serverless 吗? puppeteer 配合 aws lambda ,压测 QPS 有 120 ~ 160 ,针对大部分场景都足够了。
|
31
OldCarMan 253 天前 1
🤔个人觉得可以这样,4 步走:
1.解决业务可扩展性问题:可以让前端使用图片编辑器生成图片信息,如果业务需求是后续不可编辑可以生成截图保存,如果是可编辑的可以把整个编辑后的图片 html 保存,建议把其上传到对象存储; 2.前端将图片编辑结果提交给后端服务,后端将 html 信息+业务参数封装,丢到消息队列里面。 3.html->图片,这一步可以考虑各种各样的处理方式,根据自己的要求(比如性能要求)去搜索相关的库,比如 html to image java/nodejs/c++/rust 等等,生产完将结果上传并丢回消息队列里面,这个胶水层服务提供:消息队列消费,生产;图片处理;图片上传的服务。 4.后端服务消费胶水层服务产生的图片 url 目的:1.解决扩展性; 2.吞吐量; 3.图片业务与主业务的解耦,数据量大时,图片业务硬件资源吃的较多,可以单独升级图片处理服务。 |
32
WashFreshFresh 253 天前
建议拆分成单独服务部署,任务调度好应该能缓解压力,然后就是优化代码。之前的公司做项目的时候,有个转图生成各种格式各种分辨率海报的功能,做微服务改造的时候就是拆分成了单个服务,部署了 10+台机器,然后优化了下代码,效率杠杠的。
|
33
MrDarnell 253 天前
@acbingo 不晓得你要画多复杂的图,但正常情况下前端画图都是瞬间完成的,不存在你说的等待,你可以留意你玩的游戏,普遍可以达到 64 帧/s 以上,而一个帧就是一次全屏绘图,你感觉到等待了吗?
|
34
janus77 253 天前
改 c++,然后独立部署,外部调用
|
35
seanlin5 253 天前
@securityCoding 相当于写好 H5 模板,在服务器起一个 headless chrome 实现截图,然后将截图保存成 url ,通过接口方式回传给前端显示?
|
36
zoharSoul 253 天前
html 模板 填上动态的文字后, 直接渲染就行啊
|
37
securityCoding 253 天前
@seanlin5 是的,核心就是 headless chrome 来渲染 H5
|
38
airqj 253 天前 via Android
用 wasm,让前端来画
|
39
airqj 253 天前 via Android
而且现在 wasm 是支持多线程的
应该慢不了 |
40
fengpan567 253 天前
让前端画呗
|
41
acbingo OP 十分感谢大家的回复~~
我已经有个大概的认知了,目前打算去探索一些让前端去画,再传到后端保存的方案。另外针对前端无法生成的需求场景,先用老场景进行兜底 等有余力后,再考虑探索一下后端 html to image 的方案,看能不能做个后台可以用自己运营编辑海报样式并生成 html |
42
sunqb 252 天前
@securityCoding 截图的问题真的很多,奇奇怪怪的问题。特别是如果 html 里面有视频或者动图,但是如果静态的 html 很简单。
|
43
luozic 252 天前 1
——
1.缩小后端生成图的场景, ———— 2.解耦,用专门的语言+显卡 simd 等支持的加速。 这个虽然 B 站恶心,但是 B 站整的客户端 wasm 缩小服务器占用可以参考。 -------- 反正你这个应该是商务的应用吧? 不过就看你的顾客骂不骂风扇起飞了 —————— 3.部分情况可以尝试性试试 Java 平台的 simd ,gpu 的支持。 不过这些要么是 jdk22/graalvm 22 才支持,并且还是 preview ,或者是魔改的 jdk---比如 TornadoVM https://github.com/beehive-lab/TornadoVM |
44
wssy001 251 天前
@coolcoffee serverless 按需计费的 一个月 750 小时一直跑的话 成本恐怕会是普通包月机器的好几倍
|