简体   繁体   中英

Python time out reading image from Amazon S3

I am getting the following exception reported intermittently from my django website which hosts it's images on Amazon S3 via boto. Am I reading the below right that it's timing out trying to read the image width using get_image_dimensions? If so how would I introduce a retry or increase the timeout?

    Internal Server Error: /photographer/24/23
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 111, in get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
      File "/usr/django/example/photographer/views.py", line 364, in photographer_image
        media_url=settings.MEDIA_URL), RequestContext(request))
      File "/usr/local/lib/python2.7/dist-packages/django/shortcuts.py", line 23, in render_to_response
        return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
      File "/usr/local/lib/python2.7/dist-packages/django/template/loader.py", line 178, in render_to_string
        return t.render(context_instance)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 148, in render
        return self._render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 142, in _render
        return self.nodelist.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 844, in render
        bit = self.render_node(node, context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 858, in render_node
        return node.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py", line 126, in render
        return compiled_parent._render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 142, in _render
        return self.nodelist.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 844, in render
        bit = self.render_node(node, context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 858, in render_node
        return node.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py", line 65, in render
        result = block.nodelist.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 844, in render
        bit = self.render_node(node, context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 858, in render_node
        return node.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py", line 312, in render
        return nodelist.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 844, in render
        bit = self.render_node(node, context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 858, in render_node
        return node.render(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 898, in render
        output = self.filter_expression.resolve(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 596, in resolve
        obj = self.var.resolve(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 734, in resolve
        value = self._resolve_lookup(context)
      File "/usr/local/lib/python2.7/dist-packages/django/template/base.py", line 770, in _resolve_lookup
        current = getattr(current, bit)
      File "/usr/local/lib/python2.7/dist-packages/django/core/files/images.py", line 17, in _get_width
        return self._get_image_dimensions()[0]
      File "/usr/local/lib/python2.7/dist-packages/django/core/files/images.py", line 27, in _get_image_dimensions
        self.open()
      File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/files.py", line 79, in open
        self.file.open(mode)
      File "/usr/local/lib/python2.7/dist-packages/django/core/files/base.py", line 122, in open
        if not self.closed:
      File "/usr/local/lib/python2.7/dist-packages/django/core/files/base.py", line 60, in _get_closed
        return not self.file or self.file.closed
      File "/usr/local/lib/python2.7/dist-packages/storages/backends/s3boto.py", line 128, in _get_file
        self.key.get_contents_to_file(self._file)
      File "/usr/local/lib/python2.7/dist-packages/boto/s3/key.py", line 1643, in get_contents_to_file
        response_headers=response_headers)
      File "/usr/local/lib/python2.7/dist-packages/boto/s3/key.py", line 1475, in get_file
        query_args=None)
      File "/usr/local/lib/python2.7/dist-packages/boto/s3/key.py", line 1528, in _get_file_internal
        for bytes in self:
      File "/usr/local/lib/python2.7/dist-packages/boto/s3/key.py", line 386, in next
        data = self.resp.read(self.BufferSize)
      File "/usr/local/lib/python2.7/dist-packages/boto/connection.py", line 412, in read
        return http_client.HTTPResponse.read(self, amt)
      File "/usr/lib/python2.7/httplib.py", line 567, in read
        s = self.fp.read(amt)
      File "/usr/lib/python2.7/socket.py", line 380, in read
        data = self._sock.recv(left)
      File "/usr/lib/python2.7/ssl.py", line 341, in recv
        return self.read(buflen)
      File "/usr/lib/python2.7/ssl.py", line 260, in read
        return self._sslobj.read(len)
    SSLError: The read operation timed out

    Request repr():
    <WSGIRequest
    path:/photographer/24/23,
    GET:<QueryDict: {u'event': [u'41']}>,
    POST:<QueryDict: {}>,
    COOKIES:{},
    META:{'CONTEXT_DOCUMENT_ROOT': '/var/www/html',
     'CONTEXT_PREFIX': '',
     u'CSRF_COOKIE': u'8dbRjiwQ4OHSzX8LB5I3tzm5H2We2CHy',
     u'CSRF_COOKIE_USED': True,
     'DOCUMENT_ROOT': '/var/www/html',
     'GATEWAY_INTERFACE': 'CGI/1.1',
     'HTTP_ACCEPT': '*/*',
     'HTTP_ACCEPT_ENCODING': 'gzip,deflate',
     'HTTP_CONNECTION': 'Keep-alive',
     'HTTP_FROM': 'googlebot(at)googlebot.com',
     'HTTP_HOST': 'www.example.com',
     'HTTP_USER_AGENT': 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
     'PATH_INFO': u'/photographer/24/23',
     'PATH_TRANSLATED': '/usr/django/example/example/wsgi.py/photographer/24/23',
     'QUERY_STRING': '&event=41',
     'REMOTE_ADDR': '66.249.67.136',
     'REMOTE_PORT': '50479',
     'REQUEST_METHOD': 'GET',
     'REQUEST_SCHEME': 'http',
     'REQUEST_URI': '/photographer/24/23?&event=41',
     'SCRIPT_FILENAME': '/usr/django/example/example/wsgi.py',
     'SCRIPT_NAME': u'',
     'SERVER_ADDR': '172.31.8.216',
     'SERVER_ADMIN': 'webmaster@localhost',
     'SERVER_NAME': 'www.example.com',
     'SERVER_PORT': '80',
     'SERVER_PROTOCOL': 'HTTP/1.1',
     'SERVER_SIGNATURE': '<address>Apache/2.4.7 (Ubuntu) Server at www.example.com Port 80</address>\n',
     'SERVER_SOFTWARE': 'Apache/2.4.7 (Ubuntu)',
     'mod_wsgi.application_group': 'ip-172-31-8-216.eu-west-1.compute.internal|',
     'mod_wsgi.callable_object': 'application',
     'mod_wsgi.enable_sendfile': '0',
     'mod_wsgi.handler_script': '',
     'mod_wsgi.input_chunked': '0',
     'mod_wsgi.listener_host': '',
     'mod_wsgi.listener_port': '80',
     'mod_wsgi.process_group': '',
     'mod_wsgi.queue_start': '1417087116170868',
     'mod_wsgi.request_handler': 'wsgi-script',
     'mod_wsgi.script_reloading': '1',
     'mod_wsgi.version': (3, 4),
     'wsgi.errors': <mod_wsgi.Log object at 0x7f439e4854b0>,
     'wsgi.file_wrapper': <built-in method file_wrapper of mod_wsgi.Adapter object at 0x7f439e59ef30>,
     'wsgi.input': <mod_wsgi.Input object at 0x7f439e04e3f0>,
     'wsgi.multiprocess': True,
     'wsgi.multithread': True,
     'wsgi.run_once': False,
     'wsgi.url_scheme': 'http',
     'wsgi.version': (1, 0)}>

In case it helps anyone else, I made a change to my Image model in django to save the width and height values during model creation:

image = models.ImageField(upload_to="images/photos/",height_field='image_height',width_field='image_width')
image_width = models.IntegerField(null=True)
image_height = models.IntegerField(null=True)

Then in the template referred to the image_width & image_height fields directly:

{{ image.image_width }} X {{ image.image_height }}

Since this change I've not had a single instance of 'SSLError: The read operation timed out'. I can only assume that reading these values at runtime using the {{ image.image.width }} method was too much for S3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM