Как лучше всего модернизировать приложение J2EE 2002 года? - PullRequest
21 голосов
/ 03 мая 2010

У меня есть этот друг ....

У меня есть друг, который работает над приложением java ee (j2ee), запущенным в начале 2000-х годов. В настоящее время они добавляют функцию здесь и там, но имеют большую кодовую базу. За эти годы команда сократилась на 70%.

[Да, «у меня есть этот друг». Это я, пытаюсь с юмором впихнуть стыд подросткового старшеклассника]

Java, Vintage 2002

Приложение использует EJB 2.1, структуры 1.x, DAO и т. Д. С прямыми вызовами jdbc (смесь хранимых процедур и подготовленных операторов). Нет ОРМ. Для кеширования они используют смесь OpenSymphony OSCache и собственного слоя кеша.

За последние несколько лет они потратили усилия на модернизацию интерфейса, используя ajax техники и библиотеки. Это в основном включает в себя библиотеки JavaScript (JQuery, Юи и т. д.).

Клиентская сторона

На стороне клиента отсутствие пути обновления от распорок1 до распорок2 не позволяет им перейти на распорки2. Другие веб-фреймворки стали популярными (калитка, весна, JSF). Struts2 не был «явным победителем». Миграция всего существующего пользовательского интерфейса со Struts1 на Struts2 / wicket / etc, похоже, не принесла значительных преимуществ при очень высокой стоимости. Они не хотели иметь набор технологий du-jour (подсистема X в Struts2, подсистема Y в Wicket и т. Д.), Поэтому разработчик писал новые функции, используя Struts 1.

Серверная сторона

На стороне сервера они рассматривали переход на ejb 3, но никогда не имели большого импульса. Всем разработчикам удобно с ejb-jar.xml, EJBHome, EJBRemote, что «ejb 2.1 как есть» представляет путь наименьшего сопротивления.

Одна большая жалоба на среду ejb: программисты все еще делают вид, что "сервер ejb работает в отдельном jvm, а не в сервлет-движке". Ни один сервер приложений (jboss / weblogic) никогда не применял это разделение. Команда никогда не размещала сервер ejb в отдельном окне, а затем на сервере приложений.

Файл ear содержит несколько копий одного файла jar; один для «веб-слоя» (foo.war / WEB-INF / lib) и один для серверной части (foo.ear /). Сервер приложений загружает только одну банку. Дублирование делает для двусмысленности.

Кэширование

Что касается кеширования, они используют несколько реализаций кеша: кеш OpenSymphony и доморощенный кеш. Jgroups обеспечивает поддержку кластеризации

Что теперь?

Вопрос: У команды в настоящее время есть запасные циклы, чтобы инвестировать в модернизацию приложения? Куда их умный инвестор потратит?

Основные критерии:

1) повышение производительности. В частности, сокращение времени на разработку новых функций подсистем и сокращение технического обслуживания. 2) производительность / масштабируемость.

Они не заботятся о моде или техно-дур-стрит.

Что вы все рекомендуете?

Со стороны постоянства Переключить все (или только новую разработку) на JPA / JPA2?
Прямой спящий режим? Ждать Java EE 6?

На стороне клиента / веб-фреймворка : Мигрировать (некоторые или все) на стойки2? калитка? JSF / jsf2

Что касается кеширования: керамическая плитка? EHCache? когерентность? придерживаться того, что у них есть? Как наилучшим образом воспользоваться преимуществами огромных размеров кучи, которые предлагает 64-битная jvms?

Заранее спасибо.

Ответы [ 6 ]

7 голосов
/ 04 мая 2010

Действительно трудно оправдать реинжиниринг того, что «работает» как есть. Вы проводите много работы, возвращаясь к тому, с чего начали.

Это сказал.

Переход от EJB 2.1 Session Beans к EJB 3 довольно тривиален. Для нас, когда мы осуществили переход, большинство наших EJB-компонентов были развернуты отдельно, а не в объединенном EAR. Но у вас нет этой проблемы. Даже с EJB 3 у вас вполне может быть файл (или файлы) ejb-jar.xml.

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

Нет причин развертывать «уровень приложения» на отдельном jvm / сервере. Вызывает ли веб-уровень удаленные сеансовые компоненты? против местного? Вы можете видеть или не видеть ускорение при переключении на локальные вызовы (многие «совместно расположенные» развертывания могут быть выполнены аналогично локальному вызову на некоторых серверах, если они настроены правильно, не знаю, если вы уже делаете это).

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

Что касается JPA против SQL, я бы оставил все как есть. Не стоит переделывать весь уровень данных, чтобы перейти на JPA, и если вы действительно хотите использовать преимущества времени выполнения JPA (по сравнению со временем разработки), особенно кэширования и т. Д., Вам придется преобразовать ПОЛНЫЙ уровень данных (или, по крайней мере, большой). куски взаимосвязанных частей) все сразу. Действительно рискованно и подвержено ошибкам.

В случае проблемы с "дублирующимися банками" это артефакт упаковки и сборки, а не развертывания. Чтобы устранить проблему неоднозначности, вам нужно поработать в своей среде разработки, чтобы использовать общий репозиторий JAR, и помнить о том, что если вы обновите JAR для одного, вы обновите его для всех. Люди осуждают, что это необоснованное требование, заставляя обновлять все приложение в случае изменения фляги. Для огромных, разрозненных приложений, конечно. Но для приложений в одной JVM нет, это не так. Как бы нам ни хотелось, чтобы каждый маленький кусочек был изолированным миром в изобильном супе, который мы называем средой загрузчика классов Java, это просто неправда. И чем больше мы можем упростить это, тем лучше для нас с точки зрения сложности и обслуживания. Для обычных jar-файлов вы МОЖЕТЕ рассмотреть возможность объединения этих jar-файлов на сервер приложений и вне приложения. Мне не нравится этот подход, но он имеет применение, если вы можете заставить его работать на вас. Это, безусловно, уменьшает размер развертывания.

Клиентская сторона, это не так сложно преобразовать из Struts 1 в Struts 2, так как они оба очень похожи на высоком уровне (в частности, они обе являются фреймворками действий). Ключевым моментом здесь является то, что обе структуры могут жить бок о бок друг с другом, что позволяет, опять же, постепенные изменения. Вы можете медленно перенести старый код поверх, или вы можете только реализовать новый код в новой среде. Это отличается от попытки смешать и сопоставить структуру действий и структуру компонентов. Это буквально ситуация "собаки и кошки, живущие вместе". Если бы я пошел по этому пути, я бы просто развернул компоненты компонентов в их собственных WAR и пошел дальше. Управление состоянием компонентов каркасов делает взаимодействие с ними на стороне сервера действительно проблематичным. Если вы решили реализовать через новую WAR, убедитесь, что вы потратили немного времени на выполнение какого-то «единого входа», чтобы люди «вошли» в каждый модуль соответствующим образом. Пока приложения не имеют общего состояния сеанса, это действительно необходимо для интеграции. И после того, как вы решили добавить новую подсистему через новую WAR, вы можете использовать любую технологию, какую захотите, на стороне клиента.

Кэширование - это другая проблема. Разные кэши решают разные проблемы. Одно дело кэшировать и запоминать некоторые маленькие кусочки в системе (например, рендеринг JSP) или использовать распределенный кеш для передачи сеансов между экземплярами во время восстановления после сбоя или балансировки нагрузки. Другое дело иметь доменный слой на основе кеша, где постоянство и кеширование очень и очень тесно связаны. Это гораздо сложнее. Просто держать все это прямо в голове - это больно.

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

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

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

Ум, это можно сделать. Хитрость заключается в простой интеграции уровня доступа к данным, и вы можете начать кэширование на этом уровне. Но если у вас есть люди, которые делают прямые вызовы SQL, они должны идти.

Наконец, я думаю, что используемый термин - это эволюция, а не революция. Переход на EJB 3 или 3.1 Я не думаю, что это должно быть болезненно, так как это в значительной степени Just Works with EJB 2.1, что является благом. Вы МОЖЕТЕ иметь "смешанную" среду. Самая болезненная интеграция была бы, если бы вы использовали бины Entity, но вы этого не сделали, так что это хорошо. И для всех скептиков EJB эта обратная совместимость, которая распространяется на почти 10 лет EJB, - это то, что позволяет вам на самом деле сохранить большую часть кода, но все еще двигаться вперед.

3 голосов
/ 03 мая 2010

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

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

Например, Spring предоставляет вам интеграцию со Struts 1 , что упрощает внедрение компонентов Struts 1 в «Spring way». Ваши приложения Struts должны работать так же, как и раньше, но теперь у них есть рычаги для модернизации с нуля.

Далее, абстракции доступа к данным Spring позволят вам подключить существующие DAO JDBC и начать вводить абстракции DA, чтобы упростить их модернизацию. Если вы решите придерживаться JDBC, это нормально, Spring предоставляет расширенную поддержку JDBC , чтобы он чувствовал себя менее каменным веком. Если вы хотите поработать с JPA или Hibernate, то они будут интегрироваться с приложением, управляемым Spring, так же легко, как и JDBC.

Для EJB Spring может обернуть слой доступа EJB в нечто менее доисторическое, что облегчает их проглатывание. После того, как вы изолировали клиентский уровень от специфики доступа к данным EJB, вы можете, если захотите, заменить EJB (по одному) на более простые компоненты, управляемые Spring (с любым удаленным взаимодействием, транзакциями, безопасностью или вообще без них). из них), или вы можете сохранить EJB (возможно, используя EJB3), если захотите.

Таким образом, пусть Spring возьмет на себя роль "основы" приложения, начав с использования тех же устаревших компонентов, которые у вас уже есть. После этого вы получаете больше свободы для модернизации, в зависимости от темпа и риска, который вы диктуете.

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

1 голос
/ 03 мая 2010

Хорошо, вот ответ, который не требует переписывания на другом языке или обучения весной и написания 2000 строк XML. Посоветуйте своему другу попробовать развернуть приложение в glassfish v3, EJB 2.1 будет работать (и будет хорошо работать с любым новым кодом EE 6).

В дальнейшем они теперь могут разрабатывать новый код в EJB 3.1 и могут реорганизовать старый код EJB 2.1 на досуге.

Они могут продолжать использовать Struts или медленно переносить новый код в JSF / Wicket / ???

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

Кэширование? EclipseLink (JPA 2 RI) имеет довольно неплохое кэширование на борту. Читать дальше

Больше всего у этого пудинга есть доказательства. Я только что развернул старое приложение EJB 3 + Struts 1.3 в glassfish v3 на работе, он был не только мёртвым простым (потребовалось немало усилий, чтобы перенести его из проекта jdeveloper в проект netbeans), но он отлично подошел для начать рефакторинг к EE 6, что мы намереваемся сделать, если будут запрошены ошибки или функции.

По сути, это сводится к тому, что «если ничего не сломано, не чините его». зачем менять рабочий (хотя и очень старый) код? Оставьте его включенным, напишите новые функции в EE 6, а если функция затрагивает старый код, рассмотрите возможность ее рефакторинга в EE 6, пока вы там.

Больше всего усилий, связанных с этим, будет развертывание в Glassfish v3 ...

0 голосов
/ 03 мая 2010

Честно говоря, вы, вероятно, могли бы просто переделать всю вещь в Grails и сделать это примерно в 20 раз быстрее, чем сколько времени понадобилось, чтобы сделать это в 2002 году;)

Для проектов, для которых мне абсолютно необходимо использовать настоящий стек Java, я использую Spring 3.0 и Hibernate 3.5. Вы даже можете использовать Roo, чтобы быстро запустить проект, и просто отключить его, если он вам больше не нужен. Используйте такую ​​идею, как IntelliJ, чтобы ускорить кодирование.

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

Кроме того, Ajax действительно плох с Spring. Если вы хотите использовать отображение базы данных в вашем MVC, вы должны кодировать против пользовательских десериализаторов Джексона ... так что вам нужно проанализировать сырой JSON. Это ужасно, и Весенние люди уже знают о проблеме. Удачи, увидев исправление высокого уровня в ближайшее время.

Раньше я смеялся над людьми из Ruby on Rails ... но я должен был передать их им, они поняли это правильно. Для небольших и средних проектов это действительно работает. И если вам нужна масштабируемость стека Java, Grails - отличное решение.

Если вы действительно, действительно, действительно не хотите идти в этом направлении, тогда просто используйте модернизированный Spring 3.0 с Hibernate 3.5.

0 голосов
/ 03 мая 2010

Я понимаю боль твоего друга:)

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

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

Мой совет - начать отделять вашу бизнес-модель от чего-либо еще (DAO, UI, управление транзакциями ...), тогда вам будет проще внедрить новую платформу (ORM?). Даже если в итоге это не сработает, вы, вероятно, улучшите качество своей кодовой базы, отсоединившись.

0 голосов
/ 03 мая 2010

На вашем месте я начну с измерений. Возможно, возьмите несколько типичных операций, предпочтительно те, которые раздражают пользователей при высокой нагрузке или что-то в этом роде, разделите их путь на несколько этапов и измерьте, сколько времени затрачивается на каждом этапе. Как только вы найдете шаг, который занимает много времени, вы можете сузиться, пока у вас не появится вероятный преступник. Если это доступ к БД, может быть, кеширование поможет и т. Д. Вы можете найти некоторую простую старую оптимизацию, но это тоже хорошо, верно?

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

Что касается миграции с EJB2.1 на EJB3, я протестировал внедрение зависимостей EJB3 по сравнению с поиском EJB2.1 JNDI, и это было намного быстрее. Может быть, избавление от EJBHome тоже сделало вещи быстрее, хотя я точно не знаю. После полной миграции на EJB3 у вас будет JPA, и заставить ehcache работать очень легко, и я могу вам сказать, что ehcache очень эффективен. (ну, я не знаю, как он сравнивается с тем, что вы используете сейчас ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...