Межпроцессная коммуникация влияет на время отклика приложения Рэнди Стэффорд

Время отклика имеет критическое значение для эргономики программ. Мало что так раздражает, как ожидание ответа программной системы, особенно если взаимодействие с ней состоит из повторяющихся циклов воздействия и отклика.[14] Возникает ощущение, будто программа крадет у вас время и снижает продуктивность. Однако причины замедленного отклика программисты осознают не всегда, особенно в современных приложениях. В литературе, посвященной контролю производительности, по-прежнему много внимания уделяется структурам данных и алгоритмам, то есть вопросам, способным оказывать влияние на производительность в некоторых случаях, но едва ли в современных многоуровневых приложениях корпоративного уровня.

Мой опыт показывает, что когда в таких приложениях возникает проблема производительности, поиски ее решения следует начинать не с изучения структур данных и алгоритмов. Время отклика больше всего зависит от количества взаимодействий между удаленными процессами (interprocess communications, IPC), осуществляемых в ответ на воздействие. Да, встречаются и другие локальные узкие места, но число взаимодействий между удаленными процессами обычно имеет решающее значение. Каждое взаимодействие между удаленными процессами добавляет некоторую ненулевую задержку в общее время отклика, и эти отдельные добавки суммируются, особенно если возникают последовательно.

Каноническим примером служит пульсирующая нагрузка в приложениях, использующих объектно-реляционное отображение (ORM). Пульсирующая нагрузка описывает последовательное выполнение множественных обращений к базе данных для чтения данных, необходимых для построения графа объектов (см. шаблон Lazy Load[15] в книге Мартина Фаулера «Patterns of Enterprise Application Architecture»,[16] Addison-Wesley Professional). Когда клиентом базы данных является сервер приложений промежуточного уровня (middle-tier), который компонует веб-страницу, обращения к базе данных обычно происходят последовательно в едином потоке. Их периоды ожидания суммируются, образуя суммарное время отклика. Даже если каждое обращение к базе данных длится всего 10 мс, страница, требующая 1000 обращений (что не редкость), появится с задержкой не менее чем в 10 секунд. Другими примерами могут служить обращение к веб-службам, HTTP-запросы веб-браузера, вызов распределенных объектов, шаблон связи «запрос-ответ» и взаимодействие с таблицей данных по специальным сетевым протоколам. Чем больше удаленных IPC требуется для ответа на воздействие, тем большим будет время отклика.

Существует ряд относительно очевидных и широко известных стратегий сокращения количества взаимодействий между удаленными процессами в расчете на одно воздействие. Одна из таких стратегий заключается в применении принципа бережливости — мы можем оптимизировать интерфейс между процессами, чтобы передавались только те данные, которые нужны непосредственно, а объем взаимодействия был минимален. Другая стратегия — как можно более широкое распараллеливание связей между процессами, чтобы общее время отклика определялось в основном IPC с наибольшей задержкой. Третья стратегия — кэшировать результаты предшествующих IPC, чтобы в будущем вместо IPC использовать обращение к локальному кэшу.

Проектируя приложение, следите за количеством взаимодействий между процессами, происходящих в ответ на каждое воздействие. Анализируя приложения с низкой производительностью, я часто сталкивался с тем, что отношение количества IPC к воздействию составляет 1000:1 и больше. Сокращение этого отношения путем кэширования, распараллеливания или других приемов даст значительно больший эффект, чем изменение структуры данных или модификация алгоритма сортировки.

Загрузка...