Как лучше всего модернизировать приложение J2EE с 2002 эрами?

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

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

[Да, "у меня есть этот друг,". Это - я, пытаясь шутливо ввести подростковый позор адвоката средней школы в соединение]

Java, год изготовления вина 2002

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

За последние несколько лет они потратили усилие модернизировать UI с помощью ajax методы и библиотеки. Это в основном включает JavaScript libaries (jQuery, yui, и т.д.).

Сторона клиента

На стороне клиента отсутствие процедуры обновления от struts1 до struts2 отговорило их мигрировать на struts2. Другие веб-платформы стали популярными (калитка, пружина, jsf). Struts2 не был "явным победителем". Миграция всего существующего UI от Struts1 до Struts2/wicket/etc, казалось, не представила много предельной выгоды по очень высокой стоимости. Они не хотели иметь путаницу technologies-du-jour (подсистема X в Struts2, подсистема Y в Калитке, и т.д.) так новые возможности записи разработчика с помощью Struts 1.

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

На стороне сервера они изучили перемещение в ejb 3, но никогда не имели большой импульс. Разработчики все довольны ejb-jar.xml, EJBHome, EJBRemote, тем "ejb 2.1, как" представлен путь наименьшего сопротивления.

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

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

Кэширование

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

Теперь, что?

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

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

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

Они не заботятся о виде или techno-du-jour уважении.

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

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

На client/web-framework стороне: Мигрировать (некоторые или все) к struts2? калитка? jsf/jsf2?

Что касается кэширования: терракота? ehcache? когерентность? палка с тем, что они имеют? как лучше всего использовать в своих интересах огромные размеры "кучи", которые предлагают 64-разрядные jvms?

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

21
задан user331465 3 May 2010 в 14:24
поделиться

6 ответов

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

Тем не менее.

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

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

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

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

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

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

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

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

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

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

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

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

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

7
ответ дан 29 November 2019 в 22:09
поделиться

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

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

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

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

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

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

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

3
ответ дан 29 November 2019 в 22:09
поделиться

Вот ответ, который не требует переписывания на другой язык или изучения Spring и написания 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...

1
ответ дан 29 November 2019 в 22:09
поделиться

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

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

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

0
ответ дан 29 November 2019 в 22:09
поделиться

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

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

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

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

0
ответ дан 29 November 2019 в 22:09
поделиться

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

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

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

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

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

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

0
ответ дан 29 November 2019 в 22:09
поделиться
Другие вопросы по тегам:

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