我们正在通过烧瓶api提供成千上万的图像,这是最佳实践吗



我们目前有一个设置,通过带有Gunicorn的烧瓶API提供图像。令牌和图像名称随url参数一起提供。我们对整个图像库(最多500张(都这样做。因此,在一次前端获取中,您将发出500个请求。我想知道的是,这是否是一种最佳实践,或者是否有一种方法可以同时为整个图书馆服务,只需一次请求,比如send_all(images)

我们的解决方案的问题是,对于每个get请求,您都需要进行请求和验证。这是有效的,但如果你认为服务器同时收到500个请求,一次收到500个验证,我不确定。

提前非常感谢。:(

请求示例:
http://localhost:5000/image-server&image_name=alpha.png&token="xxx-yyy-zzz"

半伪码:

@app.route("/image-server", methods=['GET])
def get_image():
image_name = request.args.get("image_name")
token = request.args.get("id_token")
if verify_token(token):
return send_file(f"{image_name}")
else:
return Response(404)

有几个选项可以减少获取图像所需的连接。组合图像可以减少请求数量和开销,因此对于节省服务器资源非常重要,尤其是对于已经存在可扩展性问题的flask。标准响应体应该只包含一个图像,因此必须发挥一些创造力。

选项1

将图像放入一个单一的图形中,然后使用CSS修改图形的哪个部分,从而节省了多次请求的需要。缺点:要将每张图像无缝裁剪在一起需要做大量的工作,而且通常无法处理客户端发布的检索图像。通常用于静态精灵,可能根本不适合你,但我想我会把它包括在内。

选项2

使用内容类型:Multipart将多个图像发送回多个边界。这是一种非常真实且久经考验的方法,也是在一个请求中使用多种类型传输二进制数据的标准方法。可能是最困难但非常实用的,也是提供回复的好方法。

选项3

将服务器端的图像压缩为单个主体,然后将它们发送到客户端以在那里解压缩。我确信这可以即时完成,但可能会使用相当多的服务器内存来即时压缩文件。我不确定这种方法的实用性,也不确定它与浏览器客户端的集成程度

选项4(可能是我会使用的选项(

将数据作为一个漂亮的JSON对象发送,一键链接到序列化图像列表。缺点是,在某些(实际上是大多数(情况下,序列化图像会使数据大小增加30-50%,这可能比在单独的请求中单独检索每个图像更糟糕。看看base64或另一种编码形式,即使所有序列化图像的单个请求都会更大,但将请求限制在每个单独图像的api中的总体需求应该会更高效。

HTTP/2还可以支持某种资源组合,从而节省大量请求的需要,但在这种情况下,可能无法使用,应该作为脚注。

对于请求本身,将URL链接为查询参数。请确保检查客户端请求的映像数,并对端点进行速率限制,这样客户端就不会随意使用每个系统资源进行欺骗和垃圾请求。如果客户端任意滥用资源,那么您最不担心的就是因为多次图像抓取而在合法客户端上浪费资源。

示例:

https://myapi.com/getImages?image_names=name1.png,name2.png,name3.png