Плохая работа на Azure для приложения Owin/IIS

Мы измерили некоторые проверочные тесты, и я заметил, что процессор работает много времени в режиме ядра. Я хотел бы знать, почему это.

Приложение: это классическая веб-роль службы Azure Cloud, где Owin прослушивает в IIS, а сам Owin обслуживает только статические файлы, которые кэшируются в памяти (поэтому должно быть только небольшое снижение производительности и каждый должен быть довольно быстрым). Содержимое копируется через await stream.CopyToAsync(response.Body) для вывода потока.

Сам тест выглядит как gatling:

val openLoginSet = exec(http("ROOT")
      .get("/")
      .headers(Headers105Test2.headers_0)
      .resources(
        http("MED: arrow-down-small.png").get(uriIconAssets + "/arrow-down-small.png").headers(Headers105Test2.headers_1),
        http("MED: arrow-up-small.png").get(uriIconAssets + "/arrow-up-small.png").headers(Headers105Test2.headers_1),
        http("MED: close-medium.png").get(uriIconAssets + "/close-medium.png").headers(Headers105Test2.headers_1),
        http("MED: decline-medium.png").get(uriIconAssets + "/decline-medium.png").headers(Headers105Test2.headers_1),
        http("MED: help-medium.png").get(uriIconAssets + "/help-medium.png").headers(Headers105Test2.headers_1),
        http("MED: submit-medium.png").get(uriIconAssets + "/submit-medium.png").headers(Headers105Test2.headers_1),
        http("MED: delete-medium.png").get(uriIconAssets + "/delete-medium.png").headers(Headers105Test2.headers_1),
        http("MED: en-us.js").get("/en-us.js").headers(Headers105Test2.headers_8),
        http("MED: cloud_logo_big.png").get("/assets/cloud_logo_big.png").headers(Headers105Test2.headers_1),
        http("MED: favicon.ico").get("/favicon.ico").headers(Headers105Test2.headers_0))

val httpProtocol = http
  .baseURL("https://myurl.com")
  .inferHtmlResources()

val openLoginSenario = scenario("OpenOnly").exec(repeat(400, "n") {
    exec(openLoginSet).pause(3,6)
})

setUp(openLoginSenario.inject(rampUsers(150) over (3 minutes)))
  .protocols(httpProtocol)
  .maxDuration(3 minutes)

(Я сократил тест, чтобы запустить 3 минуты, чтобы поймать данные, чтобы показать здесь) Есть три компьютера, которые запускают этот тест gatling, каждый до 150 одновременных потоков, поэтому всего 450 потоков.

Я вижу, что в ядре много запущенного кода, а процесс W3wp не занимает большую часть процессора:

Захваченный CPU при запуске теста (процессор растет при добавлении новых потоков):

Тест только начался

Захваченный CPU, когда тесты почти до конца:

Перед окончанием теста

Режим ядра выглядит довольно плохо, и я не уверен, что это может вызвать его. Не должно быть почти никаких блокировок. Когда вы читаете, что еще может вызвать режим с высоким ядром, я обнаружил, что DPC могут его вызвать. Поэтому я также захватил некоторые данные DPC, но я не уверен, что нормально, а что нет. Во всяком случае, график с DPC max times также включен в sshot.

vmbus.sys занимает самое значительное время со всех DPC. Это означает, что экземпляр Azure не является каким-то голым металлом (не удивляет) и что экземпляр разделяет его власть с другими. Насколько я понимаю, vmbus.sys отвечает за сообщение между, например, самой сетевой карты и размещенного экземпляра HyperV. Может ли работать в HyperV основной причиной низкой производительности?

Я хотел бы знать, где искать и как узнать, что вызывает режим ядра в моей ситуации.


Еще несколько данных:

Часть данных DPC при запуске теста (за 30 секунд):

Total = 17887 for module vmbus.sys
Elapsed Time, >        0 usecs AND <=        1 usecs,    137, or   0.77%
Elapsed Time, >        1 usecs AND <=        2 usecs,   2148, or  12.01%
Elapsed Time, >        2 usecs AND <=        4 usecs,   3941, or  22.03%
Elapsed Time, >        4 usecs AND <=        8 usecs,   2291, or  12.81%
Elapsed Time, >        8 usecs AND <=       16 usecs,   5182, or  28.97%
Elapsed Time, >       16 usecs AND <=       32 usecs,   3305, or  18.48%
Elapsed Time, >       32 usecs AND <=       64 usecs,    786, or   4.39%
Elapsed Time, >       64 usecs AND <=      128 usecs,     85, or   0.48%
Elapsed Time, >      128 usecs AND <=      256 usecs,      6, or   0.03%
Elapsed Time, >      256 usecs AND <=      512 usecs,      1, or   0.01%
Elapsed Time, >      512 usecs AND <=     1024 usecs,      2, or   0.01%
Elapsed Time, >     1024 usecs AND <=     2048 usecs,      0, or   0.00%
Elapsed Time, >     2048 usecs AND <=     4096 usecs,      1, or   0.01%
Elapsed Time, >     4096 usecs AND <=     8192 usecs,      2, or   0.01%
Total,                                                 17887

Часть данных DPC , когда тест закончился (за 30 секунд):

Total = 141796 for module vmbus.sys
Elapsed Time, >        0 usecs AND <=        1 usecs,   7703, or   5.43%
Elapsed Time, >        1 usecs AND <=        2 usecs,  21075, or  14.86%
Elapsed Time, >        2 usecs AND <=        4 usecs,  17301, or  12.20%
Elapsed Time, >        4 usecs AND <=        8 usecs,  38988, or  27.50%
Elapsed Time, >        8 usecs AND <=       16 usecs,  32028, or  22.59%
Elapsed Time, >       16 usecs AND <=       32 usecs,  11861, or   8.36%
Elapsed Time, >       32 usecs AND <=       64 usecs,   7034, or   4.96%
Elapsed Time, >       64 usecs AND <=      128 usecs,   5038, or   3.55%
Elapsed Time, >      128 usecs AND <=      256 usecs,    606, or   0.43%
Elapsed Time, >      256 usecs AND <=      512 usecs,     53, or   0.04%
Elapsed Time, >      512 usecs AND <=     1024 usecs,     26, or   0.02%
Elapsed Time, >     1024 usecs AND <=     2048 usecs,     11, or   0.01%
Elapsed Time, >     2048 usecs AND <=     4096 usecs,     10, or   0.01%
Elapsed Time, >     4096 usecs AND <=     8192 usecs,     53, or   0.04%
Elapsed Time, >     8192 usecs AND <=    16384 usecs,      3, or   0.00%
Elapsed Time, >    16384 usecs AND <=    32768 usecs,      1, or   0.00%
Elapsed Time, >    32768 usecs AND <=    65536 usecs,      5, or   0.00%
Total,                                                141796

% DPC Время от начала до конца теста

введите описание изображения здесь

Мы также подозревали, что мы достигли ограничений в сети - поэтому тесты загружают так много данных, что пределы сетевого адаптера достигнуты. Это может быть правдой в конце теста (когда имеется максимальное количество потоков), но это не объясняет, почему так много времени в режиме ядра даже в начале теста.

Просто чтобы показать, сколько данных отправлено - объем отправленных данных (голубая линия) на 2 порядка ниже емкости сетевого адаптера.

введите описание изображения здесь

Ответ 1

Это может не помочь вам напрямую. но у нас были некоторые проблемы с производительностью после переноса приложения в облако. Обсудите здесь:

Огромное падение производительности после перехода на Azure

После большого исследования, наконец, мы выяснили, что наша проблема связана с механизмом обработки переходных ошибок. Он всегда ходил и читал web.config каждый раз, что вызывало огромное использование ЦП, что не было проблемой с тем же кодом в не облачной среде. Мы обработали его, используя вокруг него шаблон Singleton.

Надеемся, что это поможет вам выяснить, есть ли какие-либо проблемы с приложением.

Приветствия.:)

Ответ 2

Поскольку IIS 6 обрабатывается многими запросами в режиме ядра, что обычно быстрее, чем пользовательский режим.

больше в режиме ядра IIS

Похоже, что в вашем случае статический контент обрабатывается кешем режима ядра, так что эти запросы не включают код режима пользователя. В большинстве случаев это желательно из-за улучшения perf и т.д.

больше содержимого, которое может/не может быть обработано в режиме ядра

больше о настройке/мониторинг кеширования IIS для проверки его использования в вашем тесте

еще больше

Удачи!