Python 2.7 Elastic Beanstalk中的缩放实例中断了python flask应用程序的动态图像链接
以下代码在本地计算机以及AWS Elastic BeanStalk的部署中都能很好地工作—提供filxed映像以及动态创建的映像。但是,一旦我将部署扩展到多个EC2实例,动态创建的映像就变得不可用,即使我可以(通过ssh)发现EC2实例中存在动态映像 我怀疑,这与我在html中引用静态图像的方式或负载平衡器处理静态图像的方式有关。但是,我不知道从哪里开始调查。救命啊(Python 2.7 Elastic Beanstalk中的缩放实例中断了python flask应用程序的动态图像链接,python-2.7,amazon-web-services,flask,amazon-elastic-beanstalk,autoscaling,Python 2.7,Amazon Web Services,Flask,Amazon Elastic Beanstalk,Autoscaling,以下代码在本地计算机以及AWS Elastic BeanStalk的部署中都能很好地工作—提供filxed映像以及动态创建的映像。但是,一旦我将部署扩展到多个EC2实例,动态创建的映像就变得不可用,即使我可以(通过ssh)发现EC2实例中存在动态映像 我怀疑,这与我在html中引用静态图像的方式或负载平衡器处理静态图像的方式有关。但是,我不知道从哪里开始调查。救命啊( 固定图像 动态创建的图像 看起来您是在一台服务器上创建实例,但在负载平衡的环境中,您可能有多台服务器,并且这些服务器可以随时
固定图像
动态创建的图像
看起来您是在一台服务器上创建实例,但在负载平衡的环境中,您可能有多台服务器,并且这些服务器可以随时来来去去
因此,基本上,不要在EC2实例上存储任何状态信息
为了解决这个问题,您有两个选择。最好的选择是将图像存储在S3中-如果您仍然希望在/static/下引用它们,那么您可以使用Cloudfront将该路径映射到S3存储桶
另一个选项是使用EFS在所有EC2实例上装载共享文件系统
请记住,EFS的成本大约是S3存储成本的10倍。看起来您是在一台服务器上创建实例,但在负载平衡的环境中,您可能有多台服务器,这些服务器可以随时进出 因此,基本上,不要在EC2实例上存储任何状态信息 为了解决这个问题,您有两个选择。最好的选择是将图像存储在S3中-如果您仍然希望在/static/下引用它们,那么您可以使用Cloudfront将该路径映射到S3存储桶 另一个选项是使用EFS在所有EC2实例上装载共享文件系统
请记住,EFS的成本大约是S3存储成本的10倍。我找到了一个可行的解决方案,但并不完全相信这是正确的方法。这正是我现在的工作方式 首先,我在.exbextension下添加了一个
ANY_NAME.config
,如下所示
选项设置:
aws:elasticbeanstalk:container:python:staticfiles:
“/static/”:“static/”
这是明确地告诉EBS在哪里可以找到静态文件
其次,我通过
而不是
调用了html
其中return render\u模板('hello.html',fname=fname)
在此之后,eb scale 2
很好地服务于动态文件
正如chris提到的,虽然它可以工作,但更好的方法可能是从S3 bucket中提供图像(无论是动态创建的还是静态的)。我找到了一个可行的解决方法,但并不完全相信这是正确的方法。这就是我现在的工作方式 首先,我在.exbextension下添加了一个
ANY_NAME.config
,如下所示
选项设置:
aws:elasticbeanstalk:container:python:staticfiles:
“/static/”:“static/”
这是明确地告诉EBS在哪里可以找到静态文件
其次,我通过
而不是
调用了html
其中return render\u模板('hello.html',fname=fname)
在此之后,eb scale 2
很好地服务于动态文件
正如chris提到的,虽然它可以工作,但更好的方法可能是从S3 bucket提供图像(无论是动态创建的还是静态的)
<code>
from flask import Flask, render_template, request, url_for
import os, datetime
import thread
import time
from copy import deepcopy
import pyqrcode # generating image of QR code from given string
application = Flask(__name__)
class QR(object):
def __init__(self):
self.input_string = None
self.output_string = None
self.input_image_filename = None
def encode(self, input_string, QR_image_filename, QR_image_scale):
"""Return the image of QR code"""
if not input_string:
raise RuntimeError('Input string is empty!') # checking that input_string is not empty
else:
self.input_string = input_string
try:
qr = pyqrcode.create(self.input_string)
qr.png(QR_image_filename, scale=QR_image_scale)
return True
except Exception as e:
print "printing exception : " + str(e)
raise RuntimeError('QR creation failed!')
def background_deletion_task(path):
print "wait starts"
# gevent.sleep(5)
time.sleep(5)
print "wait done"
if os.path.exists(path):
os.remove(path)
print "deletion done"
@application.route('/')
def hello():
gen_qr = QR()
gen_qr.qr_time = datetime.datetime.utcnow().isoformat()
gen_qr.image_file_name = str(gen_qr.qr_time[-6:]) + ".png"
gen_qr.full_path = os.path.join(application.root_path, 'static', gen_qr.image_file_name)
gen_qr.encode(str(gen_qr.image_file_name), gen_qr.full_path, 4)
# ---------------deletion by thread------------
#thread.start_new_thread(background_deletion_task, (gen_qr.full_path,))
return render_template('hello.html', gen_qr = gen_qr)
if __name__ == "__main__":
#application.debug=True
application.run()
</code>