Всем привет, я Чжан Чжан, автор паблика «Дорога к улучшению архитектуры».
Так называемый предварительный прогрев службы предназначен для выполнения некоторых операций по подготовке к инициализации для конкретных сценариев до завершения запуска службы и до предоставления внешних служб.
Например, предварительный разогрев пула потоков, предварительный разогрев кэша, предварительный разогрев базы данных, предварительный разогрев веб-сайтов, предварительный разогрев JVM и т. д.
Поскольку при первом запуске службе требуется период обкатки, в течение этого периода состояние работы службы не является оптимальным. Поэтому, если в это время служебный трафик внезапно увеличится до нормального уровня, это может привести к большому количеству тайм-аутов запросов или мгновенной перегрузке системы.
В сценариях веб-приложений запуск программы Java делится на два процесса:
1. Процесс запуска:относится к отJVM Переходим к этапу, на котором инициализация программы завершена и может ответить на первый запрос. Поскольку при запуске программы требуется динамическая загрузка классов и инициализация, запуск будет медленнее. Медленный запуск повлияет на скорость отклика программы и замедлит работу. Web Расширение приложения.
2. Процесс предварительного нагрева:относится к отJVM Начинайте с этапа, когда оптимизация программы завершена и достигнуты пики производительности. Медленный прогрев может привести к Web Приложение не может вовремя обработать запросы пользователей, что приводит к большому количеству таймаутов запросов.
а. Предварительный подогрев соединительного бассейна.
Как и в случае с пулом соединений с базой данных, мы можем инициализировать несколько соединений по мере необходимости и помещать их в пул соединений при запуске приложения, чтобы избежать их повторного создания при поступлении запросов и влияния на производительность.
При запуске системы она пытается получить определенное количество соединений (здесь берется минимальное значение простоя). В это время пул соединений пуст. После того, как соединение сгенерировано, оно будет помещено в пул соединений при запросе. войдет, больше соединений создаваться не будет.
б. Прогрев данных точки доступа.
Решение:
1. Настройте запланированное задание для обновления кэшированных данных.
2. Напишите страницу обновления кэша напрямую и обновите ее вручную после выхода в Интернет.
Для некоторых «горячих» данных с особенно высоким уровнем доступа в крайних случаях, учитывая сетевую задержку, а также потребление сериализации и десериализации от обслуживания до Redis, помещать их в кэш Redis не идеально.
Затем мы можем рассмотреть возможность помещения этих данных в локальный кеш. Конечно, объем данных не может быть слишком большим. После помещения экстремальных данных горячей точки в локальный кеш потребление в измерении приложения при запросе данных практически отсутствует, нет сетевых задержек, а также нет потребления сериализации и десериализации.
Вы можете использовать кеш гуавы
1. Запрос на получение пула потоков
На примере Tomcat мы можем настроить количество начальных потоков для прогрева пула потоков.
2. Пользовательский пул потоков.
Для пользовательского пула потоков просто вызовите метод prestartAllCoreThreads во время инициализации.
3. Прогрейте пул подключений к БД
При запуске службы создайте несколько подключений к базе данных по мере необходимости и поместите их в пул подключений. Затем, когда приложение начнет обрабатывать запросы на чтение и запись базы данных, вы можете использовать подключения непосредственно из пула подключений, избегая необходимости чтения и записи. запросы на создание соединений и помещение их в пул соединений. Процесс занимает много времени.
Наш широко используемый пул соединений Druid обеспечивает более удобную возможность предварительного нагрева пула соединений. Общие методы настройки:
4. Разминка JVM
Как мы все знаем, язык Java сосуществует с интерпретируемым и компилируемым выполнением. То есть файл исходного кода Java (.java) сначала компилируется в байт-код (.class) с помощью Javac, а затем байт-код интерпретируется или компилируется и выполняется виртуальной машиной, соответствующей каждой операционной системе.
Для повышения скорости выполнения вводится JIT (Just-in-time компиляция). Во время выполнения JIT сохранит скомпилированный машинный код для использования в следующий раз. JIT будет компилировать только часто выполняемый код, например циклы, часто используемые методы и т. д.
JVM по умолчанию включает JIT-компиляцию. Вы можете проверить параметры запуска -Xint и -Djava.compiler=NONE. Если есть инструкции по отключению JIT, вы можете удалить и снова включить JIT по мере необходимости.
Кроме того, в JDK1.8 появились лямбда-выражения, которые принесли разработчикам большое удобство, однако чрезмерное использование лямбда-выражений также может привести к негативным последствиям. Принцип лямбда-выражения заключается в создании анонимного внутреннего класса при выполнении, который необходимо загрузить и скомпилировать.
Поэтому для некоторого «горячего» кода вы можете не использовать лямбда-выражения или выполнять предварительные вызовы при запуске службы. После достаточного количества вызовов он становится «горячим» кодом. Последующие вызовы будут компилироваться JIT и генерироваться анонимные внутренние классы. можно пропустить, шаги загрузки также повышают эффективность выполнения.
3. Проблемы с предварительным нагревом и их решения
Поскольку на этапе запуска службы добавляется логика предварительного нагрева, возникнут потери. Наиболее прямым проявлением этого является увеличение времени запуска службы, которое может варьироваться от нескольких минут до более десяти минут.
Но медленный запуск не обязательно плох. Он эквивалентен достаточной инициализации и прогреву перед предоставлением услуг внешнему миру.
Конечно, у всего есть две стороны. Главное – найти баланс между быстрым и медленным запуском, чтобы сервис можно было запустить в приемлемое время и обеспечить качественное обслуживание через короткое время после выхода в Интернет.
Во время самого процесса приложения произошло внезапное увеличение загрузки ЦП. Как показано на рисунке ниже, при запуске служба получит сигнал тревоги ЦП. Проверка мониторинга показала, что загрузка ЦП более чем в два раза превышает обычную норму.
Посмотрев код предварительного разогрева при запуске, мы обнаружили, что будут запускаться следующие запросы, как показано на рисунке. Объем запросов в сотни раз превышает нормальный уровень. Поэтому позиционирование должно быть вопросом разогрева кода.
Код предварительного нагрева выглядит следующим образом:
Приведенный выше код использует CountDownLatch в качестве счетчика для запуска трех интерфейсов горячей точки, когда служба начинает достигать цели предварительного нагрева. Однако из-за слишком большого количества параметров количество запросов на обслуживание резко возросло, что вызвало тревогу.
После обнаружения проблемы мы уменьшили количество входных параметров и количество циклов, тем самым уменьшив количество самозапросов сервиса, и проблема была устранена.
Выше приведены некоторые распространенные методы предварительного нагрева сервисов. Прежде чем использовать его, необходимо выяснить, какие сервисы необходимо предварительно разогреть. Для сервисов, которые необходимо предварительно разогреть, вам необходимо выяснить, какой конкретный контент необходимо предварительно разогреть. Предварительный нагрев нельзя делать вслепую, поскольку это может оказаться контрпродуктивным.
После предварительного прогрева вам также необходимо наблюдать за соответствующими индикаторами, чтобы проверить, эффективен ли предварительный прогрев, и убедиться, что служба работает стабильно и нормально.