Cherrypy, обслуживание статических файлов занимает много времени, когда страница открыта более чем в одном браузере, файлы никогда не загружаются из кеша

Я использую платформу Cherrypy 3.6.0. У меня проблема с долгой загрузкой страниц (обслуживание статических файлов занимает много времени), когда я открываю страницу более чем в одном браузере. В этом случае, например, файл bootstrap.min.css размером 120 КБ может загружаться 5-10 секунд. Что еще хуже, статические файлы никогда не кэшируются, поэтому каждый раз, когда загружается страница, статические файлы загружаются снова, и снова загрузка страницы занимает несколько секунд. Когда сервер отвечает 304 Не изменено, также требуется такое же количество времени, прежде чем клиентская сторона получит этот ответ (нет разницы во времени ответа независимо от того, загружен ли статический файл или сервер отвечает 304). Конфигурация моих статических файлов:

cherrypy.tree.mount(None, '/static', config={
    '/': {
        'tools.staticdir.on': True,
        'tools.staticdir.dir': static_dir,
        'tools.sessions.on': False,
        'tools.caching.on': True,
        'tools.caching.force' : True,
        'tools.caching.delay' : 0,
        'tools.expires.on' : True,
        'tools.expires.secs' : 60*24*365
        }
    }
)

Я не могу понять, как это возможно, что получение файла размером 120 КБ может занять так много времени... Может быть, кто-нибудь может дать мне совет, где я могу искать причину этой проблемы?

РЕДАКТИРОВАТЬ:

Заголовки:

Remote Address:192.168.100.100:80
Request URL:http://192.168.100.100/static/css/bootstrap.min.css
Request Method:GET
Status Code:304 Not Modified
Request Headersview source
Accept:text/css,*/*;q=0.1
Accept-Encoding:gzip, deflate, sdch
Accept-Language:pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie:session_id=.......................................
Host:192.168.100.100
If-Modified-Since:Mon, 22 Dec 2014 12:30:51 GMT
Referer:http://192.168.100.100/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Response Headersview source
Date:Fri, 14 Jan 2000 23:51:25 GMT
Server:CherryPy/3.6.0
Vary:Accept-Encoding

При временном перекрытии у меня есть:

Stalled: 9.619ms
Request sent: 0.171ms
Waiting (TTFB): 5.02s
Content download: 1.000ms 

Я проверил, что такое TTFB, и это продолжительность от виртуального пользователя, делающего HTTP-запрос, до первого байта страницы, полученной браузером. Значит, что-то не так с отзывчивостью сервера...

РЕДАКТИРОВАТЬ2:

Я создал минимальное приложение, которое загружает только статические файлы, и проблема все еще возникает. Это код приложения:

сервер:

import cherrypy

def start():

    import app

    app.application()

    cherrypy.config.update({'server.socket_host': '0.0.0.0', 'server.socket_port': 9061 })

    engine = cherrypy.engine

    engine.autoreload.unsubscribe()

    try:

        engine.start()

    except:

        sys.exit(1)

    else:

        engine.block()


if __name__ == '__main__':    

    start()

приложение:

import cherrypy

from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('/tmp/cherry/'))


static_dir = '/media/vbox_shared/new_web/app/static'

class Test(object):

    @cherrypy.expose

    def index(self):

        template = env.get_template('test.html')

        return template.render()


def application():

    cherrypy.tree.mount(Test(), '/', config = {})

    cherrypy.tree.mount(None, '/static', config={

        '/': {

            'tools.staticdir.on': True,

            'tools.staticdir.dir': static_dir
        }

    })

HTML:

<html>

<head>

    <meta http-equiv="X-UA-Compatible" content="IE=9"/>

    <link rel="stylesheet" href="/static/css/style.min.css"/>

    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/>

    <link rel="stylesheet" type="text/css" href="/static/css/chosen.min.css"/>

    <link rel="stylesheet" type="text/css" href="/static/css/jquery.jgrowl.min.css"/>

    <link rel="stylesheet" href="/static/css/m-buttons.min.css"/>

    <title>Streams</title>

    <title>test</title>

</head>

<body>

<h1>test</h1>

 <script src="/static/js/jquery-1.11.1.min.js"></script>

    <script src="/static/js/jstree.min.js"></script>

    <script src="/static/js/functions.js"></script>

    <script src="/static/js/stream.js"></script>

    <script src="/static/js/chosen.jquery.min.js"></script>

    <script src="/static/js/chosen.proto.min.js"></script>

    <script src="/static/js/jquery.jgrowl.min.js"></script>

    <script src="/static/js/bootstrap.min.js"></script>

</body>

</html>

ссылки на скриншоты:

http://i58.tinypic.com/21m8ar5.png http://i60.tinypic.com/euh6p0.png

РЕДАКТИРОВАТЬ3:

Я сократил свое приложение до:

import cherrypy
class HelloWorld(object):
    def index(self):
        return """
            <html>
            <head>
                <link rel="stylesheet" href="/static/css/style.min.css"/>
                <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"/>
                <link rel="stylesheet" type="text/css" href="/static/css/chosen.min.css"/>
                <link rel="stylesheet" type="text/css" href="/static/css/jquery.jgrowl.min.css"/>
                <link rel="stylesheet" href="/static/css/m-buttons.min.css"/>
                <title>Streams</title>
                <title>test</title>
            </head>
            <body>
            <h1>test</h1>
                <script src="/static/js/jquery-1.11.1.min.js"></script>
                <script src="/static/js/jstree.min.js"></script>
                <script src="/static/js/chosen.jquery.min.js"></script>
                <script src="/static/js/chosen.proto.min.js"></script>
                <script src="/static/js/jquery.jgrowl.min.js"></script>
                <script src="/static/js/bootstrap.min.js"></script>
            </body>
            </html>"""

    index.exposed = True

conf = {
        '/static':
        {
         'tools.staticdir.on': True,
         'tools.staticdir.dir':'/media/vbox_shared/new_web/app/static'} 

        }

cherrypy.config.update({'server.socket_host': '0.0.0.0', 'server.socket_port': 9066 })
cherrypy.quickstart(HelloWorld(), config=conf)

И проблема все еще возникает. Когда я открываю главную страницу в IE, FF, Safari и Chrome - некоторые статические файлы загружаются более 10 секунд...


person Sebastian Hebel    schedule 22.12.2014    source источник
comment
Недавно я ответил на аналогичный вопрос и пришел к выводу, что CherryPy кэширует файлы по умолчанию. Кэширует в смысле отправки заголовков, которые позволяют браузеру кэшировать контент. tools.caching предназначен для кэширования памяти в процессе, я не думаю, что это хорошая идея для статического контента. Можете ли вы показать нам заголовки для вашего bootstrap.min.css.   -  person saaj    schedule 22.12.2014


Ответы (1)


Вы, должно быть, пропустили некоторые заголовки и некоторую конфигурацию. CherryPy отправляет Vary: Accept-Encoding только для ответов, сжатых gzip. Обычно он отправляет Last-Modified, Content-Type, Content-Length и некоторые другие. Также обратите внимание, что Cache-Control: max-age=0 означает, что вы делаете запрос на обновление, запрашивая сервер для проверки ресурса.

В ответе, на который я ссылался в комментарии, я показал, что обычно 304 Not Modified стоит только CherryPy a os.stat вызов, который является мгновенным, если только ваш диск не сломан.

Я предлагаю вам запустить отдельное приложение CherryPy в том же статическом каталоге с включенным только tools.staticdir, чтобы избежать возможной неправильной настройки, проблем с блокировкой сеанса и т. д. Затем постепенно добавляйте конфигурацию и измеряйте время отклика, например. с Apache ab -c 10 -n 1000 http://192.168.100.100/static/css/bootstrap.min.css.

person saaj    schedule 23.12.2014