Подтвердить что ты не робот

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

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

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

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

Java, Vintage 2002

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

В течение последних нескольких лет они потратили усилия на модернизацию пользовательского интерфейса, используя ajax методы и библиотеки. Это во многом связано с javascript-библиотеками (jquery, yui и т.д.).

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

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

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

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

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

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

Кэширование

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

Теперь что?

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

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

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

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

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

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

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

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

Спасибо заранее.

4b9b3361

Ответ 1

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

Тем не менее.

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

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

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

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

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

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

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

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

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

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

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

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

Наконец, я думаю, что термин, который нужно использовать, - это эволюция, а не революция. Мигрируя в EJB 3 или 3.1, я не думаю, что это должно быть болезненно, поскольку это в значительной степени просто работает с EJB 2.1, что является благом. У вас может быть "смешанная" среда. Самая болезненная интеграция была бы, если бы вы использовали Entity beans, но вы этого не сделали, так что хорошо. И для всех скептиков EJB эта обратная совместимость, которая охватывает, что, почти 10 лет EJB, - это то, что позволяет фактически сохранить основную часть вашего кода, но все же двигаться вперед.

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

Прежде всего, усилия, связанные с этим, будут внедряться в стеклянную фазу v3...

Ответ 4

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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

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

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

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

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

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