Вопрос, вынесенный в заголовок темы, может показаться странным. Действительно, все знают, что Spring Framework стоит ровно столько же, сколько, например, посмотреть на знаменитого брюссельского Писающего мальчика, т.е. ровно ноль. Однако, если задуматься об эксплуатации приложения, разработанного на основе этого замечательного фреймворка, то может оказаться, что у нас не все так однозначно.
В данной статье Суровый расскажет о плюсах эксплуатации приложения, разработанного на основе Spring Framework, на "взрослом" сервере приложений, например на, поскольку уж так получилось, что я работаю в IBM, - WebSphere Application Server. Целью данного изложения является донести до вас, уважаемые читатели, мысль о том, что инфраструктура имеет значение.
Пулы соединений с БД. Конечно, сервера приложений с открытым исходным кодом, например Apache Tomcat, как правило предоставляют ту или иную реализацию пула соединений с БД, но возможности таковой зачастую оставляют желать лучшего. Умеет ли встроенный в Tomcat пул соединений периодически тестировать доступность СУБД и гарантированно обновлять соединения при восстановления после сбоев? Поддерживает ли он замену прав доступа? Грубо говоря, подключаемся к БД под пользователем в зависимости от того, кто аутентифицировался в нашем приложении, если часть логики вынесена на уровень СУБД, то данная возможность бывает полезной. Может ли пул соединений из бесплатного сервера приложений балансировать нагрузку между несколькими базами данных (например, при использовании Oracle RAC или DB2) и определять, что вот эти узлы умерли и теперь к ним не нужно пытаться подключаться, а затем понять, что они снова стали доступны и теперь их тоже нужно использовать? В конце концов, может ли такой пул соединений обеспечивать соединение с работающей на том же образе операционной системы сервером СУБД с помощью JDBC Type 2, задействуя все возможности межпроцессного взаимодействия, предоставляемые современными операционными системами, например Cross Memory Services в z/OS?
JMS. Если вы хотите использовать очереди в вашем приложении, развернутом на серверах приложений Tomcat или Jetty, то придется отдельно поднимать сервера очередей сообщений. В случае сервера приложений, очереди как правило доступны их коробки. Вместе с очередями доступны так же следующие возможности: кластеризация - вы можете строить распределенные очереди, расположенные сразу на нескольких серверах, что существенно увеличивает масштабируемость и доступность вашего приложения, миграция - в случае падения одного из серверов, его очереди автоматически перемещаются на другой, сохраняя необработанные сообщения. В некоторых серверах приложений поддерживается Unit-of-Order - гарантированный порядок обработки сообщений, удовлетворяющих некоторым критериям, обеспечить который часто необходимо при интеграции. Справедливости ради замечу, что иногда сторонний менеджер очередей сообщений, например IBM MQ, бывает предпочтительнее даже при использовании "взрослого" сервера приложений. Как говорят западные коллеги: "It depends".
JTA. Те самые пресловутые распределенные транзакции. Кто-то их понимает и использует, кто-то считает слишком тяжелыми. Как правило это отчасти верно: распределенные транзакции тяжелы для понимания и исполнения, но если нужно обеспечить стопроценную согласованность данных в СУБД, разнесенных по разным углам нашей необъятной, или в СУБД и очереди, то без их использования бывает трудно. Суть распределенных транзакций заключается в том, что мы не коммитим изменения ни в одну из БД, пока не убедимся, что все БД, участвующие в транзакции, смогут их принять. Тем самым мы избегаем проблемы "с одного счета в одном банке деньги списали, а на другой - в другом банке - не зачислили - сработало ограничение целостности".
Безопасность. Современные сервера приложений предоставляют множество различных провайдеров безопасности. Доступны различные провайдеры аутентификации, т.е. вы можете хранить информацию о пользователях во множестве мест: во встроенном LDAP-сервере, в базе данных, во внешнем LDAP-сервере, в различных Internet-directory - специализированных приложениях для управления правами доступа. Возможны следующие сценарии: на работу наняли человека, добавили его в Internet-directory/Access-manager, там запустился процесс раздачи прав, который выдал человеку права на все необходимые ему ресурсы вашего предприятия и теперь каждый сервер приложений в вашей компании (а их может быть очень много) видит данные права, так как подключен к этой Internet-directory/Access-manager. Доступно разделение пользовательской сессии между приложениями: мы аутентифицировались в одном приложении - нам уже не нужно аутентифицироваться в другом. Так же доступна реализация Single-Sign-On: вы делаете один из серверов базой для хранения пользователей, а все другие сервера при аутентификации пользователя обращаются к ней. Реализуется SSO посредством Security Assertion Markup Language (SAML) 1/2 или посредством Simple and Protected Negotiate (SPNEGO) и Kerberos для Windows-клиентов. Возможна авторизация посредством протокола eXtensible Access Control Markup Language (XACML), позволяющего описывать довольно сложные политики (например, приложение доступно пользователю только в рабочее время, а ровно в 18:00 администратор превращается в тыкву). Конечно, с помощью Spring Security и Apache Shiro можно реализовать большинство из данных возможностей самостоятельно, но вам придется "тянуть" эти реализации вместе с каждой программой, в то время как в сервере приложений они доступны из коробки.
Масштабируемость и высокая доступность. В принципе, примитивная кластеризация доступна и для серверов приложений с открытым исходным кодом. Однако, не так просто сделать, например, передачу пользовательской сессии из одного центра обработки данных (ЦоД) в другой через Интернет, а так же настроить эффективную репликацию сессий на большом кластере, состоящем из 40-50 экземпляров сервера приложений. В случае сбоев, не обеспечивается миграция экземпляров сервера на другую машину и т.д. Так же, например в Apache Tomcat, нет механизмов автоматического мониторинга и реакции на ошибки: экземпляр сервера не перезапустится автоматически, если на нем зависло 10 потоков, не отправится письмо администратору при переполнении пула соединений и т.д.
Управляемость. Речь идет о едином сервере управления т.н. Deployment Manager'е и аналогах NodeAgent’а. Единый сервер управления, например, позволяет запустить несколько десятков экземпляров сервера приложений, развернутых на множестве физических серверов да еще и в нескольких ЦоД'ах. Здесь же можно посмотреть сколько имеется обработчиков на той или иной очереди, на том или ином сервере, сколько создано соединений с той или иной БД, какие из них можно убить, какие в данный момент выполняются транзакции, какие ресурсы в них задействованы и т.д. Конечно, реализовать описанные возможности моджно "за три минуты, да на скриптах, ну как мы ядро Линукса патчим", но результаты как правило плачевные.
Скриптовый язык. Кстати, о скриптах. Большинство промышленных серверов приложений содержат утилиты для выполнения скриптов, написанных как правило на языке Python. Пользоваться данными утилитами одно удовольствие. Администратор может описать в виде скрипта все шаги для подготовки к развертыванию сколь угодно большого приложения, таким образом запуск в продуктив или обновление займет сравнительно немного времени. С помощью таких скриптов можно создавать источники данных (представьте себе сервисную шину, подключенную к 120 экземплярам БД), JMS-очереди, менеджеры потоков, создавать новые экземпляры серверов и добавлять их в кластер, выполнять останов или запуск экземпляров сервера приложений, а так же их миграцию.
Административный канал и развертывание в промышленном режиме. Некоторые "взрослые" сервера приложений позволяют включить так называемый административный канал - отдельный порт, защищенный SSL, запросы по которому имеют приоритет. Таким образом, даже если сервер приложений завис, всегда можно на него зайти и посмотреть, какие транзакции выполняются и что собственно произошло. Впрочем, у такого канала есть и другое применение. При обновлении приложения не нужно выключать старую версию! Можно добавить на сервер новую версию приложения в административном режиме - пользователи продолжат работать со старой версией, а по административному каналу станет доступной новая, соответственно администратор может выполнить последнее тестирование перед запуском, проверить все ли правильно развернулось, а только потом окончательно опубликовать версию. При этом пользователи, уже имеющие сессию, продолжат работать со старой версией, чтобы не потерять данные. Новые пользователи аутентифицируются на новой версии. Тем самым мы обновляем приложение без его простоя, что очень важно для критичных систем.
Отдельно стоит отметить поддержку Spring Framework со стороны разработчиков серверов приложений. Например, в Oracle WebLogic можно включить отдельную страницу в консоли администрирования для каждого построенного на данном фреймворке приложения. На странице будет отображено дерево бинов и показаны их свойства. Так же доступны бины самого сервера и упрощена разработка MBean’ов. Помимо этого, Spring Framework прозрачно интегрируется в кластерное окружение, а Spring Security может использовать подсистему безопасности сервера приложений.
В заключение скажу, что выбор платформы для приложения это довольно нетривиальная инженерная задача, в которой должна учитываться масса факторов. Это и соотношение стоимости разработки к стоимости поддержки (при этом нужно учитывать, что разработка может идти год, а использоваться созданное программное обеспечение - десятки лет, благо платформы вроде z Systems позволяют), стоимость самих серверов приложений, ваши отношения с вендором, т.к. несмотря на высокую номинальную стоимость зачастую предоставляются существенные скидки. В конце концов нужно трезво оценивать свою и своей команды квалификацию. И не нужно быть ретроградом, если кто-то в 2001-м году писал на EJB и с тех пор смотреть на них не может, то это еще не повод отказываться от этой замечательной технологии и реализующих ее серверов приложений, но даже если вы гуру Spring Framework, подумайте, может быть для него и на промышленном сервере тоже найдется место?
Как всегда в комментариях приветствуется критика, вопросы и замечания. Оставайтесь на связи!
Понравилось сообщение - подпишитесь на блог
В данной статье Суровый расскажет о плюсах эксплуатации приложения, разработанного на основе Spring Framework, на "взрослом" сервере приложений, например на, поскольку уж так получилось, что я работаю в IBM, - WebSphere Application Server. Целью данного изложения является донести до вас, уважаемые читатели, мысль о том, что инфраструктура имеет значение.
Пулы соединений с БД. Конечно, сервера приложений с открытым исходным кодом, например Apache Tomcat, как правило предоставляют ту или иную реализацию пула соединений с БД, но возможности таковой зачастую оставляют желать лучшего. Умеет ли встроенный в Tomcat пул соединений периодически тестировать доступность СУБД и гарантированно обновлять соединения при восстановления после сбоев? Поддерживает ли он замену прав доступа? Грубо говоря, подключаемся к БД под пользователем в зависимости от того, кто аутентифицировался в нашем приложении, если часть логики вынесена на уровень СУБД, то данная возможность бывает полезной. Может ли пул соединений из бесплатного сервера приложений балансировать нагрузку между несколькими базами данных (например, при использовании Oracle RAC или DB2) и определять, что вот эти узлы умерли и теперь к ним не нужно пытаться подключаться, а затем понять, что они снова стали доступны и теперь их тоже нужно использовать? В конце концов, может ли такой пул соединений обеспечивать соединение с работающей на том же образе операционной системы сервером СУБД с помощью JDBC Type 2, задействуя все возможности межпроцессного взаимодействия, предоставляемые современными операционными системами, например Cross Memory Services в z/OS?
JMS. Если вы хотите использовать очереди в вашем приложении, развернутом на серверах приложений Tomcat или Jetty, то придется отдельно поднимать сервера очередей сообщений. В случае сервера приложений, очереди как правило доступны их коробки. Вместе с очередями доступны так же следующие возможности: кластеризация - вы можете строить распределенные очереди, расположенные сразу на нескольких серверах, что существенно увеличивает масштабируемость и доступность вашего приложения, миграция - в случае падения одного из серверов, его очереди автоматически перемещаются на другой, сохраняя необработанные сообщения. В некоторых серверах приложений поддерживается Unit-of-Order - гарантированный порядок обработки сообщений, удовлетворяющих некоторым критериям, обеспечить который часто необходимо при интеграции. Справедливости ради замечу, что иногда сторонний менеджер очередей сообщений, например IBM MQ, бывает предпочтительнее даже при использовании "взрослого" сервера приложений. Как говорят западные коллеги: "It depends".
JTA. Те самые пресловутые распределенные транзакции. Кто-то их понимает и использует, кто-то считает слишком тяжелыми. Как правило это отчасти верно: распределенные транзакции тяжелы для понимания и исполнения, но если нужно обеспечить стопроценную согласованность данных в СУБД, разнесенных по разным углам нашей необъятной, или в СУБД и очереди, то без их использования бывает трудно. Суть распределенных транзакций заключается в том, что мы не коммитим изменения ни в одну из БД, пока не убедимся, что все БД, участвующие в транзакции, смогут их принять. Тем самым мы избегаем проблемы "с одного счета в одном банке деньги списали, а на другой - в другом банке - не зачислили - сработало ограничение целостности".
Безопасность. Современные сервера приложений предоставляют множество различных провайдеров безопасности. Доступны различные провайдеры аутентификации, т.е. вы можете хранить информацию о пользователях во множестве мест: во встроенном LDAP-сервере, в базе данных, во внешнем LDAP-сервере, в различных Internet-directory - специализированных приложениях для управления правами доступа. Возможны следующие сценарии: на работу наняли человека, добавили его в Internet-directory/Access-manager, там запустился процесс раздачи прав, который выдал человеку права на все необходимые ему ресурсы вашего предприятия и теперь каждый сервер приложений в вашей компании (а их может быть очень много) видит данные права, так как подключен к этой Internet-directory/Access-manager. Доступно разделение пользовательской сессии между приложениями: мы аутентифицировались в одном приложении - нам уже не нужно аутентифицироваться в другом. Так же доступна реализация Single-Sign-On: вы делаете один из серверов базой для хранения пользователей, а все другие сервера при аутентификации пользователя обращаются к ней. Реализуется SSO посредством Security Assertion Markup Language (SAML) 1/2 или посредством Simple and Protected Negotiate (SPNEGO) и Kerberos для Windows-клиентов. Возможна авторизация посредством протокола eXtensible Access Control Markup Language (XACML), позволяющего описывать довольно сложные политики (например, приложение доступно пользователю только в рабочее время, а ровно в 18:00 администратор превращается в тыкву). Конечно, с помощью Spring Security и Apache Shiro можно реализовать большинство из данных возможностей самостоятельно, но вам придется "тянуть" эти реализации вместе с каждой программой, в то время как в сервере приложений они доступны из коробки.
Масштабируемость и высокая доступность. В принципе, примитивная кластеризация доступна и для серверов приложений с открытым исходным кодом. Однако, не так просто сделать, например, передачу пользовательской сессии из одного центра обработки данных (ЦоД) в другой через Интернет, а так же настроить эффективную репликацию сессий на большом кластере, состоящем из 40-50 экземпляров сервера приложений. В случае сбоев, не обеспечивается миграция экземпляров сервера на другую машину и т.д. Так же, например в Apache Tomcat, нет механизмов автоматического мониторинга и реакции на ошибки: экземпляр сервера не перезапустится автоматически, если на нем зависло 10 потоков, не отправится письмо администратору при переполнении пула соединений и т.д.
Управляемость. Речь идет о едином сервере управления т.н. Deployment Manager'е и аналогах NodeAgent’а. Единый сервер управления, например, позволяет запустить несколько десятков экземпляров сервера приложений, развернутых на множестве физических серверов да еще и в нескольких ЦоД'ах. Здесь же можно посмотреть сколько имеется обработчиков на той или иной очереди, на том или ином сервере, сколько создано соединений с той или иной БД, какие из них можно убить, какие в данный момент выполняются транзакции, какие ресурсы в них задействованы и т.д. Конечно, реализовать описанные возможности моджно "за три минуты, да на скриптах, ну как мы ядро Линукса патчим", но результаты как правило плачевные.
Скриптовый язык. Кстати, о скриптах. Большинство промышленных серверов приложений содержат утилиты для выполнения скриптов, написанных как правило на языке Python. Пользоваться данными утилитами одно удовольствие. Администратор может описать в виде скрипта все шаги для подготовки к развертыванию сколь угодно большого приложения, таким образом запуск в продуктив или обновление займет сравнительно немного времени. С помощью таких скриптов можно создавать источники данных (представьте себе сервисную шину, подключенную к 120 экземплярам БД), JMS-очереди, менеджеры потоков, создавать новые экземпляры серверов и добавлять их в кластер, выполнять останов или запуск экземпляров сервера приложений, а так же их миграцию.
Административный канал и развертывание в промышленном режиме. Некоторые "взрослые" сервера приложений позволяют включить так называемый административный канал - отдельный порт, защищенный SSL, запросы по которому имеют приоритет. Таким образом, даже если сервер приложений завис, всегда можно на него зайти и посмотреть, какие транзакции выполняются и что собственно произошло. Впрочем, у такого канала есть и другое применение. При обновлении приложения не нужно выключать старую версию! Можно добавить на сервер новую версию приложения в административном режиме - пользователи продолжат работать со старой версией, а по административному каналу станет доступной новая, соответственно администратор может выполнить последнее тестирование перед запуском, проверить все ли правильно развернулось, а только потом окончательно опубликовать версию. При этом пользователи, уже имеющие сессию, продолжат работать со старой версией, чтобы не потерять данные. Новые пользователи аутентифицируются на новой версии. Тем самым мы обновляем приложение без его простоя, что очень важно для критичных систем.
Отдельно стоит отметить поддержку Spring Framework со стороны разработчиков серверов приложений. Например, в Oracle WebLogic можно включить отдельную страницу в консоли администрирования для каждого построенного на данном фреймворке приложения. На странице будет отображено дерево бинов и показаны их свойства. Так же доступны бины самого сервера и упрощена разработка MBean’ов. Помимо этого, Spring Framework прозрачно интегрируется в кластерное окружение, а Spring Security может использовать подсистему безопасности сервера приложений.
В заключение скажу, что выбор платформы для приложения это довольно нетривиальная инженерная задача, в которой должна учитываться масса факторов. Это и соотношение стоимости разработки к стоимости поддержки (при этом нужно учитывать, что разработка может идти год, а использоваться созданное программное обеспечение - десятки лет, благо платформы вроде z Systems позволяют), стоимость самих серверов приложений, ваши отношения с вендором, т.к. несмотря на высокую номинальную стоимость зачастую предоставляются существенные скидки. В конце концов нужно трезво оценивать свою и своей команды квалификацию. И не нужно быть ретроградом, если кто-то в 2001-м году писал на EJB и с тех пор смотреть на них не может, то это еще не повод отказываться от этой замечательной технологии и реализующих ее серверов приложений, но даже если вы гуру Spring Framework, подумайте, может быть для него и на промышленном сервере тоже найдется место?
Как всегда в комментариях приветствуется критика, вопросы и замечания. Оставайтесь на связи!
Понравилось сообщение - подпишитесь на блог
8 комментариев:
Павел, приветствую!
Очень интересна фича, про которую пишешь:
"Поддерживает ли он замену прав доступа? Грубо говоря, подключаемся к БД под пользователем в зависимости от того, кто аутентифицировался в нашем приложении, если часть логики вынесена на уровень СУБД, то данная возможность бывает полезной."
А разве эта штука работает в какой либо связке, кроме как с DB2? Можно ли такое запилить, когда у нас Oracle? Очень н-н-н-н-адо.
А еще про БД пулы "очень клёво", что когда нужно использовать какую-нибудь нестандарную фичу, используемого драйвера, то будь добр сделай это через WSCallHelper (очень "удобно"), а потом за то, что ты им по пользовался будь добр получи запись в лог :)
Я знаю, что в WAS for z/OS можно настроить, что коннектиться к БД ты будешь под тем пользователем, под которым аутентифицировался в приложении http://www-01.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.zseries.doc/ae/cdat_conthid.html?lang=en. Да и вообще операции в ОС будешь выполнять под ним же: http://www-01.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.zseries.doc/ae/csec_threadidentzos.html?lang=en
Вообще, когда писал заметку, то имел ввиду WebLogic Server.
Если правильно понял, то ответ на вопрос Unknown называется Proxy Authentication. См. https://docs.oracle.com/cd/B28359_01/java.111/b31224/proxya.htm
Ok, а я добавлю про сквозную аутентификацию WAS for z/OS -> DB2
marx, Вы меня правильно поняли, вопрос в том, как это сделать в WAS...
Павел, про то, что можно сделать сквозную аутентификацию WAS z/OS -> DB2 история понятная, мануал на эту тему нагуглить не проблема, а вот сделать так, чтобы работала сквозная аутентификация по схеме - пользователь из Windows Active Directory обращается через браузер к WAS, который в свою очередь устанавливает соединение с Oracle DB, под учетной записью пользователя из AD, вот это будет классно.
Правильно понял, что описанная хотелка реализуема в WebLogic?
Вот здесь пишут, что такое можно сделать и на WebSphere Application Server.
Посмотрел, в целом конечно вариант, но в общем история о том же возьмите WSJdbcUtil / WSCallHelper и вызовите нативные методы драйвера :) А ругань в лог при использовании данных методов как то отключается?
Отправить комментарий
Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!