Pull to refresh

Comments 20

Вот и вы сделали свой маленький вклад в глобальное потепление.
А если по существу, то интересно посмотреть на хабра-эффект в картинках.
Относительно возможных объяснений:
1. При повышении нагрузки App Engine может запускать сразу несколько инстансов и может быть 3 запроса — 3 запуска инстансов. Также, при высокой нагрузке на всю систему инстансы могут жить весьма недолго. Что в логах медленных запросов — присутствует ли «loading_request=1»?

2. API стабильно потребляет 73мс — вряд ли проблема там, скорее в коде приложения. Уже по 500мс на обычный запрос видно, что приложение тяжеловато.

3. При понижении приоритета приложения может возрасти время выполнения, но не количество потребляемых ресурсов. Скажем, если обычно на бесплатном питоне выделяется 2 секунды CPU в секунду, то для «неэффективных» приложений система может выделять 1 секунду CPU в секунду или меньше, но AE не заставляет приложения производить дополнительные вычисления.

И напоследок: не совсем корректно называть эти предупреждения ошибками — запросы выполняются в обычном режиме, а информация о времени позволяет разработчикам быстро понять где что не так. Скорее, это предупреждения.
>>Что в логах медленных запросов — присутствует ли «loading_request=1»?

Как то не подумал посмотреть ранее. Действительно в 90% этих запросов есть loading_request=1. Но как так получилось что они присутствуют по 5 штук на каждой странице лога???

Смотрю лог нового счетчика. Просмотрел 10 страниц лога — НИ ОДНОГО запроса красным или оранжевым нет. В среднем выполняется за 64ms 175cpu_ms 128api_cpu_ms.

Сейчас трафик — 6 запросов в секунду. Было 8.

На 42 тыс. показов 8 ошибок «Concurrent Modification» — получается 1 ошибка на 6000 запросов (нужно было добавить несколько счетчиков с рандомным доступом).

>>Уже по 500мс на обычный запрос видно, что приложение тяжеловато.

Это все org.toyz.litetext. Счетчик, который используется сейчас, работает где-то за 40 ms.
Но как так получилось что они присутствуют по 5 штук на каждой странице лога???

Скорее всего, утекает память или её потребляется слишком много. Инстансы, потребляющие более 70Мб памяти — прямые кандидаты на отстрел (это происходит тихо-мирно и не особо заметно), а если инстанс съест 200Мб, то умрёт с критическим сообщением в логе.

Также, может помочь активация warmup-запросов, главное не забыть добавить handler для адреса /_ah/warmup
Смотрю лог нового счетчика. Просмотрел 10 страниц лога — НИ ОДНОГО запроса красным или оранжевым нет. В среднем выполняется за 64ms 175cpu_ms 128api_cpu_ms.

Эти предупреждения появляются когда запрос потребляет много ресурсов: жёлтым когда на запрос уходит 700-1000мс и красным когда более 1000мс.
>>Скорее всего, утекает память или её потребляется слишком много.

Скорее всего да — в библиотеке org.toyz.litetext что-то не оптимизировали.
Спасибо, интересно. Тем более, что я впервые увидел статью, когда она как раз была без картинки…

А по какой причине там у Вас в коде длинная колбаса из ифов вместо switch|case?
>>А по какой причине там у Вас в коде длинная колбаса из ифов вместо switch|case?

Хороший вопрос. Раньше было String, потом модифицировал и забыл изменить. Нужно будет исправить…
Извите, вы меня в ступор вводите своими, на мой взгляд, не очень точными формулировками.

Недописал

> Приложение было ограничено как неэффективное.

Можно ссылку на описание где и как GAE «ограничивает приложения как неэффективные»?

Вы же не контролируете жизнь инстанса так что делать выводы о «прошло недостаточно времени» не совсем корректно.
>>Можно ссылку на описание где и как GAE «ограничивает приложения как неэффективные»?

Лично я об этом узнал из статьи: habrahabr.ru/blogs/gae/94640/ абзац «Одна секунда». В официальной документации не припомню чтобы такое встречалось. Но, с учетом моего опыта, похоже на правду.
Не верю я в такие, на мой взгляд необоснованные, предположения Александра.

То что его приложение стало выдавать HTTP 500 ещё ни о чём не говорит. Могли быть его внутренние проблемы или проблемы с базой или ещё что-то.
А вы с ним пообщайтесь. Говорит, что узнал об этом лично от Михаила Айзацкого (из команды Google App Engine).

Склонен считать что это соответствует действительности.
Если бы я начинал выяснять детали каждого голословного утверждения мне бы ни на что полезное времени бы не оставалось.

Ваше право доверять таким утверждениям. Я не вижу в них логики. Мне кажется с точки зрения Гугла им всё равно, по большому счёту, эффективно ваше приложение или нет — вы платите за потребляемые ресурсы. Они конечно же хотят помочь вам сделать приложение эффективным и выводят предупреждения, но они ничего не знают о его внутренней логике и не могут сделать вывод эффективно оно или нет (может быть очень много высокоэффективных действий). И не зря же они постоянно увеличивают предельное время исполнения запроса и в роудмапе есть long running requests.

Не знаю что он услышал от Михаила, но выводы расходятся с логикой, официальной политикой и road-map.
      image1 = makeImage("1");
      image2 = makeImage("2");
      image3 = makeImage("3");
      image4 = makeImage("4");
      image5 = makeImage("5");
      image6 = makeImage("6");
      image7 = makeImage("7");
      image8 = makeImage("8");
      image9 = makeImage("9");
      image0 = makeImage("0");


      if ('1' == c)
        image = image1;
      else if ('2' == c)
        image = image2;
      else if ('3' == c)
        image = image3;
      else if ('4' == c)
        image = image4;
      else if ('5' == c)
        image = image5;
      else if ('6' == c)
        image = image6;
      else if ('7' == c)
        image = image7;
      else if ('8' == c)
        image = image8;
      else if ('9' == c)
        image = image9;
      else if ('0' == c)
        image = image0;


Жаждете попадания на govnokod.ru?
В чём сакральный смысл отказа от массивов и циклов?
А что ж заполнение хэштаблицы не в цикле? :)
А там он по смыслу не очень подходит. Файл рисунка ведь не всегда называется так же как символ, который на этом рисунке изображен. Оказывается в GAE нельзя чтобы файл назывался ( или ). А вот цифрами можно.
Это понятно, я имел в виду что-то типа такого:
      for(int i = 0; i < 10; ++i) {
          imageTable.put(String.format("%d", i), makeImage(String.format("%d.png", i)));
      }

      imageTable.put("(", makeImage("leftBracket.png"));
      imageTable.put(")", makeImage("rightBracket.png"));

Sign up to leave a comment.

Articles