Лучшие практики для развертывания веб-приложений Java с минимальным временем простоя?

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

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

55
задан cdeszaq 23 January 2013 в 08:08
поделиться

14 ответов

Было замечено, что rsync не работает должным образом при отправке изменений в файл WAR. Причина этого в том, что файлы WAR по сути являются файлами ZIP и по умолчанию создаются со сжатыми файлами-членами. Небольшие изменения в файлах-членах (до сжатия) приводят к большим различиям в масштабе в ZIP-файле, что делает алгоритм дельта-передачи rsync неэффективным.

Одним из возможных решений является использование jar -0 ... для создания исходного файла WAR. Параметр -0 указывает команде jar не сжимать файлы-члены при создании файла WAR. Затем, когда rsync сравнивает старую и новую версии файла WAR, алгоритм дельта-передачи должен иметь возможность создавать небольшие различия. Затем сделайте так, чтобы rsync отправлял diff-файлы (или исходные файлы) в сжатом виде; например, используйте rsync -z ... или сжатый поток данных / транспорт внизу.

РЕДАКТИРОВАТЬ: В зависимости от того, как структурирован файл WAR, может также потребоваться использовать jar -0 ... для создания компонентных JAR-файлов. Это применимо к файлам JAR, которые часто подвергаются изменениям (или которые просто перестраиваются), а не к стабильным файлам JAR сторонних производителей.

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

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


Другой подход - это посмотреть на ваш WAR-файл, чтобы увидеть, можете ли вы идентифицировать библиотечные JAR-файлы, которые, вероятно, (почти) никогда не изменятся. Извлеките эти JAR из файла WAR и разверните их отдельно в каталоге сервера Tomcat common / lib ; например, используя rsync .

20
ответ дан 7 November 2019 в 07:19
поделиться

Разве вы не можете сделать локальную копию текущего веб-приложения на веб-сервере, выполнить rsync в этот каталог, а затем, возможно, даже с помощью символических ссылок за один раз указать Tomcat на новое развертывание без длительного простоя?

8
ответ дан 7 November 2019 в 07:19
поделиться

Обновление:

Поскольку этот ответ был впервые написан, появился лучший способ развертывания файлов войны в tomcat с нулевым временем простоя. В последних версиях tomcat вы можете включать номера версий в имена файлов war. Так, например, вы можете одновременно развернуть файлы ROOT ## 001.war и ROOT ## 002.war в одном контексте. Все, что находится после ## , интерпретируется tomcat как номер версии, а не часть пути контекста. Tomcat будет поддерживать все версии вашего приложения в рабочем состоянии и обслуживать новые запросы и сеансы до последней полностью загруженной версии, при этом корректно завершая старые запросы и сеансы в той версии, с которой они были запущены. Указать номера версий также можно с помощью диспетчера tomcat и даже задач catalina ant. Подробнее здесь .

Исходный ответ:

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

Что плохого в использовании приложения Tomcat Manager для развертывания? Если вы не хотите выгружать весь военный файл непосредственно в приложение Tomcat Manager из удаленного места, вы можете выполнить его синхронизацию (без сжатия по причинам, указанным выше) с местом-заполнителем на производственном блоке, перепаковать его для войны и затем передайте его менеджеру на месте. В Tomcat есть замечательная задача ant, которая позволяет вам создавать сценарии развертывания с помощью приложения Tomcat Manager.

В вашем подходе есть еще один недостаток, о котором вы не упомянули: пока ваше приложение развернуто частично (во время операции rsync ) ваше приложение может находиться в несогласованном состоянии, когда измененные интерфейсы могут быть не синхронизированы, новые / обновленные зависимости могут быть недоступны и т. д. Кроме того, в зависимости от того, сколько времени занимает ваше задание rsync, ваше приложение может перезапускаться несколько раз. Знаете ли вы, что можно и нужно отключить в Tomcat поведение "прослушивание измененных файлов и перезапуск"? На самом деле это не рекомендуется для производственных систем. Вы всегда можете выполнить перезапуск вашего приложения вручную или по сценарию с использованием муравьиного скрипта с помощью приложения Tomcat Manager.

Конечно, ваше приложение будет недоступно для пользователей во время перезапуска. Но если вас так беспокоит доступность, у вас наверняка есть избыточные веб-серверы за балансировщиком нагрузки. При развертывании обновленного файла war вы можете временно заставить балансировщик нагрузки отправлять все запросы на другие веб-серверы, пока развертывание не будет завершено. Промойте и повторите для других ваших веб-серверов.

30
ответ дан 7 November 2019 в 07:19
поделиться

I'm not sure if this answers your question, but I'll just share on the deployment process I use or encounter in the few projects I did.

Similiar to you, I do not ever recall making a full war redeployment or update. Most of the time, my updates are restricted to a few jsp files, maybe a library, some class files. I am able to manage and determine which are the affected artifacts, and usually, we packaged those update in a zip file, along with an update script. I will run the update script. The script does the following:

  • Backup the files that will be overwritten, maybe to a folder with today's date and time.
  • Unpackage my files
  • Stop the application server
  • Move the files over
  • Start the application server

If downtime is a concern, and they usually are, my projects are usually HA, even if they are not sharing state but using a router that provide sticky session routing.

Another thing that I am curious would be, why the need to rsync? You should able to know what are the required changes, by determining them on your staging/development environment, not performing delta checks with live. In most cases, you would have to tune your rsync to ignore files anyway, like certain property files that define resources a production server use, like database connection, smtp server, etc.

I hope this is helpful.

1
ответ дан 7 November 2019 в 07:19
поделиться

Мой совет - использовать rsync с разнесенными версиями, но развернуть военный файл.

  1. Создайте временную папку в живой среде, в которой вы будете использовать взорванную версию webapp.
  2. Rsync взорван версий.
  3. После успешного выполнения rsync создайте файл войны во временной папке на компьютере с живой средой.
  4. Замените старую войну в каталоге развертывания сервера на новую из временной папки.

Рекомендуется заменить старую войну новой. в контейнере JBoss (который основан на Tomcat), потому что это атомарная и быстрая операция, и можно быть уверенным, что при запуске программы развертывания все приложение будет в развернутом состоянии.

10
ответ дан 7 November 2019 в 07:19
поделиться

На чем стоит ваш PermSpace? Я бы ожидал увидеть и это увеличение, но должно ли упасть после сбора старых классов? (или ClassLoader все еще сидит без дела?)

Думая вслух, вы можете выполнить rsync в отдельный каталог с именем версии или даты. Если контейнер поддерживает символические ссылки, не могли бы вы SIGSTOP корневого процесса, переключить корень файловой системы контекста через символическую ссылку, а затем SIGCONT?

1
ответ дан 7 November 2019 в 07:19
поделиться

As for the early context restarts. All containers have configuration options to disable auto-redeploy on class file or static resource changes. You probably can't disable auto redeploys on web.xml changes so this file is the last one to update. So if you disable to auto redeploy and update the web.xml as the last one you'll see the context restart after the whole update.

1
ответ дан 7 November 2019 в 07:19
поделиться

Это зависит от архитектуры вашего приложения.

Одно из моих приложений находится за прокси-сервером с балансировкой нагрузки, где я выполняю поэтапное развертывание, эффективно сокращая время простоя.

4
ответ дан 7 November 2019 в 07:19
поделиться

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

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

Запустите два сервера приложений : запустите второй сервер приложений (который прослушивает другие порты TCP) и разверните там свое приложение. После развертывания обновите конфигурацию Apache httpd (mod_jk или mod_proxy), чтобы он указывал на второй сервер приложений. Изящный перезапуск процесса Apache httpd. Таким образом, у вас не будет простоев, а новые пользователи и запросы будут автоматически перенаправлены на новый сервер приложений.

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

4
ответ дан 7 November 2019 в 07:19
поделиться

If static files are a big part of your big WAR (100Mo is pretty big), then putting them outside the WAR and deploying them on a web server (e.g. Apache) in front of your application server might speed up things. On top of that, Apache usually does a better job at serving static files than a servlet engine does (even if most of them made significant progress in that area).

So, instead of producing a big fat WAR, put it on diet and produce:

  • a big fat ZIP with static files for Apache
  • a less fat WAR for the servlet engine.

Optionally, go further in the process of making the WAR thinner: if possible, deploy Grails and other JARs that don't change frequently (which is likely the case of most of them) at the application server level.

If you succeed in producing a lighter WAR, I wouldn't bother of rsyncing directories rather than archives.

Strengths of this approach:

  1. The static files can be hot "deployed" on Apache (e.g. use a symbolic link pointing on the current directory, unzip the new files, update the symlink and voilà).
  2. The WAR will be thinner and it will take less time to deploy it.

Weakness of this approach:

  1. There is one more server (the web server) so this add (a bit) more complexity.
  2. You'll need to change the build scripts (not a big deal IMO).
  3. You'll need to change the rsync logic.
2
ответ дан 7 November 2019 в 07:19
поделиться

В любой среде, где время простоя является важным фактором, вы наверняка используете какой-то кластер серверов для повышения надежности за счет избыточности. Я бы взял хост из кластера, обновил его, а затем забросил обратно в кластер. Если у вас есть обновление, которое не может работать в смешанной среде (например, требуется несовместимое изменение схемы в базе данных), вам придется отключить весь сайт, по крайней мере, на мгновение. Уловка состоит в том, чтобы вызвать процессы замены перед тем, как отбросить оригиналы.

Используя tomcat в качестве примера - вы можете использовать CATALINA_BASE для определения каталога, в котором будут находиться все рабочие каталоги tomcat, отдельно от исполняемого кода. Каждый раз, когда я развертываю программное обеспечение, я развертываю его в новом базовом каталоге, чтобы новый код находился на диске рядом со старым кодом. Затем я могу запустить другой экземпляр tomcat, который указывает на новый базовый каталог, все запустить и запустить, а затем поменять местами старый процесс (номер порта) на новый в балансировщике нагрузки.

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

Это все компромисс между ИТ-инфраструктурой, сложностью процесса выпуска и усилиями разработчика. Если ваш кластер достаточно велик и ваше желание достаточно велико, достаточно легко разработать систему, которую можно заменить без простоев для большинства обновлений. Большие изменения схемы часто приводят к фактическому простою, поскольку обновленное программное обеспечение обычно не может вместить старую схему, и вам, вероятно, не удастся скопировать данные в новый экземпляр базы данных, выполнить обновление схемы и затем переключить серверы на новую базу данных, поскольку вы пропустите какие-либо данные, записанные в старый после того, как из него был клонирован новый db. Конечно, если у вас есть ресурсы, вы можете поручить разработчикам изменить новое приложение, чтобы использовать новые имена таблиц для всех обновляемых таблиц, и вы можете установить триггеры на живую базу данных, которая будет правильно обновлять новые таблицы данными по мере их записи в старые таблицы с помощью предыдущая версия (или, возможно, использовать представления для эмуляции одной схемы из другой). Подключите свои новые серверы приложений и поменяйте их местами в кластер. Существует множество игр, в которые вы можете играть, чтобы минимизировать время простоя, если у вас есть ресурсы для их разработки.

Возможно, наиболее полезным механизмом сокращения времени простоя во время обновления программного обеспечения является обеспечение возможности работы вашего приложения в режиме только для чтения. Это предоставит вашим пользователям некоторые необходимые функции, но оставит вам возможность вносить общесистемные изменения, требующие модификации базы данных и т. Д. Переведите ваше приложение в режим только для чтения, затем клонируйте данные, обновите схему, подключите новые серверы приложений к новой базе данных, затем переключите балансировщик нагрузки на использование новых серверов приложений. Единственное время простоя - это время, необходимое для переключения в режим только для чтения, и время, необходимое для изменения конфигурации вашего балансировщика нагрузки (большая часть которого может справиться с этим без простоя вообще).

13
ответ дан 7 November 2019 в 07:19
поделиться

Мы загружаем новую версию веб-приложения в отдельный каталог, затем либо перемещаемся, чтобы заменить его на работающий, либо используем символические ссылки. Например, у нас есть символьная ссылка в каталоге веб-приложения tomcat с именем «myapp», которая указывает на текущее веб-приложение с именем «myapp-1.23». Мы загружаем новое веб-приложение в "myapp-1.24". Когда все будет готово, остановите сервер, удалите символьную ссылку и сделайте новую, указывающую на новую версию, а затем снова запустите сервер.

Мы отключаем автоматическую перезагрузку на рабочих серверах для повышения производительности, но даже в этом отношении файлы в веб-приложениях изменяются в не-Атомарный способ может вызвать проблемы, так как статические файлы или даже страницы JSP могут измениться таким образом, что это приведет к неработающих ссылкам или еще хуже.

На практике веб-приложения фактически расположены на общем устройстве хранения, поэтому кластеризованные серверы с балансировкой нагрузки и отработкой отказа имеют один и тот же доступный код.

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

1
ответ дан 7 November 2019 в 07:19
поделиться

Это не «лучшая практика», а то, о чем я только что подумал.

Как насчет развертывания веб-приложения через DVCS, например git?

Таким образом, вы можете позволить git выяснить, какие файлы передавать на сервер. У вас также есть хороший способ отказаться от него, если он окажется сломанным, просто сделайте откат!

0
ответ дан 7 November 2019 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: