Django、Boto、S3:为什么我突然收不到响应?
这件事让我很头疼,我搞不清楚问题出在哪里。AWS现在有点问题,但这个问题在那之前就已经存在了,而且现在依然表现得一样。
简单来说:我有一个管理后台的功能,可以上传图片到S3,并把图片的路径存储在数据库里。在我刚重启apache的时候,一切都运行得很好,大约能持续20分钟。然后它就停止工作了,页面只显示“等待来自域名的响应”。就这样,没有任何错误提示,只是一直在等待,直到我重启apache。重启后又能正常工作,直到再次停止,通常是在20分钟后。我发现这个问题和流量的多少或者插入、删除的次数没有关系。
下面是模型的代码:
class SampleImage(models.Model):
def __unicode__(self):
return self.name
name = models.CharField(max_length=50)
front_image = S3EnabledImageField(upload_to='samples')
back_image = S3EnabledImageField(upload_to='samples')
S3EnabledImageField的代码:
class S3EnabledImageField(models.ImageField):
def generate_filename(self, instance, filename):
path_join = os.path.join(self.get_directory_name(), self.get_filename(filename))
return path_join.replace("\\", "/")
def __init__(self, bucket=settings.BUCKET_NAME, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
if settings.USE_AMAZON_S3:
self.connection = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
if not self.connection.lookup(bucket):
self.connection.create_bucket(bucket)
self.bucket = self.connection.get_bucket(bucket)
kwargs['storage'] = S3Storage(self.bucket)
super(S3EnabledImageField, self).__init__(verbose_name, name, width_field, height_field, **kwargs)
S3Storage的代码:
class S3Storage(FileSystemStorage):
def __init__(self, bucket=None, location=None, base_url=None):
if location is None:
location = settings.MEDIA_ROOT
if base_url is None:
base_url = settings.MEDIA_URL
self.location = os.path.abspath(location)
self.bucket = bucket
self.base_url = base_url
def _open(self, name, mode='rb'):
class S3File(File):
def __init__(self, key):
self.key = key
def size(self):
return self.key.size
def read(self, *args, **kwargs):
return self.key.read(*args, **kwargs)
def write(self, content):
self.key.set_contents_from_string(content)
def close(self):
self.key.close()
return S3File(Key(self.bucket, name))
def _save(self, name, content):
key = Key(self.bucket, name)
if hasattr(content, 'temporary_file_path'):
key.set_contents_from_filename(content.temporary_file_path())
elif isinstance(content, File):
key.set_contents_from_file(content)
else:
key.set_contents_from_string(content)
key.make_public()
return name
def delete(self, name):
self.bucket.delete_key(name)
def exists(self, name):
return Key(self.bucket, name).exists()
def listdir(self, path):
return [key.name for key in self.bucket.list()]
def path(self, name):
raise NotImplementedError
def size(self, name):
return self.bucket.get_key(name).size
def url(self, name):
return Key(self.bucket, name).generate_url(100000)
def get_available_name(self, name):
return name
1 个回答
0
看你的代码我不太确定。不过,听起来可能有一些连接没有关闭?无论如何,为什么不试试这个:
https://bitbucket.org/david/django-storages/wiki/S3Storage
呢?
我用django-storages效果很好。