Веб-приложение Java в контейнере Servlet и автономном
Каковы преимущества создания небольшого веб-приложения Java для запуска в контейнере Servlet (например, Tomcat) против создания автономного приложения Java со встроенным веб-сервером и его запуска за обратным прокси?
Я играю с Java около года. Я заметил, что для запуска Tomcat требуется время, и не всегда можно выполнить hot-redeploy из-за проблем загрузчика классов. API-интерфейс Servlet кажется несколько запутанным для меня, особенно с точки зрения конфигурации и дизайна RESTful (который он действительно не поддерживает полностью).
С другой стороны, я заметил, что моя IDE может скомпилировать и запустить автономное приложение с молниеносной скоростью. Настройка Apache для обратного проксирования - это кусок пирога, а встроенный Jetty, похоже, обрабатывает все, что я могу на него наброситься. Мне не нужны сервлеты, когда я могу использовать Restlet, Wicket и т.д. Быть способным лучше знать, как работает мое приложение (потому что оно не интегрировано с огромным сервером приложений) чувствует себя наделенным полномочиями. Трассировка стека короче. Размер загрузки меньше. Конфигурация конечного пользователя проще. Я предполагаю, что производительность, вероятно, будет лучше, потому что задействовано меньше программных слоев.
Тем не менее, мне напомнили о том, что обычно звучит слишком хорошо, чтобы быть правдой. Поэтому мой вопрос: почему я не хочу делать автономные веб-приложения? Что контейнер сервлетов дает мне и/или моим конечным пользователям, которые нам действительно нужны, но не знают?
Ответы
Ответ 1
Здесь есть два отдельных вопроса:
-
Должен ли я использовать встроенный
сервера или развертывания в контейнере?
Я не думаю, что вы должны видеть
большая разница так или иначе.
Там немного больше кода для
запуск сервера Jetty
программным способом и конфигурацией
легче делать программно.
Несмотря на то, что поддержка IDE для веб-приложения
конфигурации и развертывания
поправляться, еще хуже
чем для автономных приложений
(это по определению, так как
есть надмножество вещей для
поддержка).
С другой стороны, серверы приложений дают
у вас есть некоторые преимущества, такие как встроенный
управление, встроенная способность запускать
как сервис и т.д.
Вы даже можете использовать гибрид
подход: используйте встроенный сервер для
разрабатывать локально, а затем развертывать в
контейнер в производстве. Но это
немного странно: если вы пройдете через
проблема создания надлежащего файла WAR,
IDE должны действительно иметь возможность обрабатывать
развертывание в контейнер
адекватно.
Кстати, странно, что у вас проблемы
с hot-redeploy; Томкат не должен
иметь проблемы с ним, если
вы сталкиваетесь с каким-то странным
угловой корпус...
-
Должен ли я использовать Servlet API?
Это ортогонально от # 1. Вы
может очень хорошо вставить Jetty и
реализовать сервлеты. Вы также можете
использовать API-интерфейс Restlet внутри Tomcat
через ServerServlet
http://www.restlet.org/documentation/1.0/faq#02.
Я лично нахожу API сервлета
быть довольно прямолинейным. Вы получаете
такие приятные вещи, как concurrency и
государственное управление. Я не совсем понимаю
что это означает, что дизайн RESTful
не поддерживается, но если Restlets
лучше отвечайте вашим требованиям,
затем используйте это...
Ответ 2
Embedded Jetty может быть хорошим выбором, если вам не нужен полный стек Servlet. В отличие от Tomcat, Jetty позволяет легко избавиться от тех частей, которые вы не используете (JSP, JNDI, что угодно).
Написание собственного HTTP-сервера, с другой стороны, является ужасной идеей. Конечно, легко написать то, что обрабатывает основные запросы. Но скоро вы обнаружите, что у некоторых клиентов возникают проблемы с этим, потому что он не поддерживает полные спецификации протокола; или что он сбой, когда там более нескольких сотен пользователей; или что существует уязвимость, которая позволяет малышам в Малайзии взорвать ваш принтер. Так что не изобретайте колесо повторно.
Что касается вашей жалобы на то, что API-интерфейс Servlet не поддерживает дизайн RESTful - вам не хватает этого, он никогда не собирался это делать. Но есть много библиотек REST, которые работают поверх API сервлета.
Ответ 3
Встроенный Jetty также является контейнером сервлета. Я предполагаю, что ваше приложение включает в себя web.xml, где вы определяете фильтр/сервлет калитки, сервлет RESTlet и их сопоставления (по крайней мере). Таким образом, вы не можете избавиться от API сервлета (или контейнера сервлета, даже если вы его вставляете), но вы можете скрыть его, а также, возможно, под вашими фреймворками и в свой собственный метод main(). RESTlet (или Джерси или любая реализация JAX-RS), а также Spring MVC основаны на сервлетах, поэтому API Servlet действительно поддерживает REST, я бы сказал.
P.S.
Оба подхода не исключают друг друга. Вы можете очень хорошо работать с Jetty во время разработки, а затем развернуть свою войну в некоторый (не внедренный) контейнер для QA/production. Или... придерживайтесь Jetty для производства, если это действительно подходит вашим потребностям.
Ответ 4
Контейнеры сервлетов часто предоставляют кучу полезных вещей, таких как автоматическое управление сеансами, горячее развертывание, фреймворки для отказоустойчивости и кластеризации и т.д. Конечно, это зависит от контейнера, но иногда это очень полезные инструменты. Иногда это не так.
EDIT: просто заметил ваш комментарий о hot-redeploy. Да, иногда контейнеры являются ошибками и болью для работы, и все они имеют свои собственные причуды. Тем не менее, иногда они действительно предоставляют некоторые действительно хорошие вещи.
Ответ 5
Контейнеры Servlet in-process - это контейнеры, которые работают внутри JVM веб-сервера, что обеспечивает хорошую производительность, но маловероятно.
Контейнеры вне процесса - это контейнеры, которые работают в JVM вне веб-сервера. плохая производительность, но лучше масштабируемость
В случае контейнеров, находящихся вне процесса, веб-сервер и контейнер взаимодействуют друг с другом с помощью стандартного механизма, такого как IPC.
В дополнение к этим типам контейнеров существует 3-й тип, который представляет собой автономные контейнеры сервлетов. Они являются неотъемлемой частью веб-сервера.
Ответ 6
если у вас возникли проблемы с вашим горячим развертыванием, скорее всего, вы не очищаете внешние подключения или другие ресурсы. Чтобы справиться с этим, обычно вы хотите реализовать слушателя, который позволит вам узнать, когда что-то запущено или остановлено.
вы должны, вероятно, в ваших войнах реализовать что-то вроде этого (tomcat 6):
public class MyTomcatInitCleanupListener implements ServletContextListener
{
@Override
public void contextInitialized(ServletContextEvent arg0)
{
super.contextInitialized(arg0);
}
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
super.contextDestroyed(arg0);
}
}
для tomcat 7+, вы можете google "слушатель жизненного цикла tomcat"