![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
Мне тут подкинули тему на диплом. Предлагали на php, но я предпочел Java.
задание: Есть много расчетных, математических программ написанных на старых языках или тупо реализованы как консольные приложения(Fortran,C,....). Необходимо написать Web-приложение, которое бы обеспечивало: передачу параметров и исходных данных, запуск этих программ удаленно через Web-браузер, и передачу результатов расчетов (в виде таблиц, либо как готовый к скачиванию файл) клиентскому браузеру. ПРи этом еще необходимо , чтобы одной консольной программой могли пользоваться несколько человек. --------------------- 1)Какие есть варианты реализации такой задачи. 2)Наверное не совсем правильно, чтобы сам Web-сервер производил такие вычисления? и лучше , чтобы он передавал запросы к вычислительным серверам. Тогда нужно использовать WebServices? --------------------- На Java давно не программировал... |
|||
|
||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
^up^
|
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Берёте весь этот набор программ, анализируете их, разделяете по типам - консольные/GUI, по типу ввода/вывода(файлы, ввод пользователем и т. д.), с состоянием/без, с привязкой этого состояния к клиенту/без привязки. Можно представить их в виде конечных автоматов. Для каждого типа пишете абстрактный базовый класс-обертку или иерархию классов. Например для консольных приложений ожидающих ввода пользователя этот базовый класс должен уметь запускать процесс, перехватывать потоки ввода/вывода этого процесса. Дальше этот класс можно расширить классами с хранением состояния и без, которые в свою очередь, могут быть расширены уже конкретными классами, инкапсулирующими особенности того или иного приложения (строки конкретных команд, формат вводимых данных, распарсить выводимые данные, значения конкретных состояний, в которых может находиться процесс и т. д.). Все эти классы реализуют общий интерфейс с методами предназначенными для запуска и останова процессов. Что касается методов для выполнения команд, то тут надо смотреть. Мне кажется лучшим решением будет создание набора интерфейсов или их иерархий, определяющих различные семантики методов для выполнения команд. Классы обёрток, конкретный или базовый, будут реализовывать один или несколько таких интерфейсов. Далее нужно обеспечить минимальное время выполнения команд в многопользовательской среде. Естественно приложение будет многопоточным. Однако классы-обёртки процессов несколькими потоками использовать нельзя. Например для консольных приложений без состояния ожидающих ввода пользователя можно реализовать пул. Для приложений без ожидания ввода, видимо, каждый раз нужно будет создавать новый процесс. Хотя это код можно инкапсулировать в классе-обёртке процесса, и тоже "пулить".
Да. Один аргумент состоит в том, что эти приложения привязаны к конкретной среде (ОС + процессор), а в выбор среды для web-сервера лучше оставить свободным. Второй в том, что и вычислительный сервис и web-сервер довольно ресурсоёмкие приложения. Я думаю - нет. Оба сервера в вашей сети, вы контролируете канал связи, лучше использовать более быстрые варианты. RMI - мне кажется, неплохой вариант. Thread Pool есть, остаётся правильно всё организовать и определиться с семантикой и набором удалённых интерфейсов. Ну вот как то так в общем, дальше надо смотреть уже конкретно. |
|||
|
||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
А зачем? Ведь при каждом обращении к Tomcat создается новый сервлет и свой собственный контекст. И разделение времени процеесора уже забота tomcat так или нет? -------- прочитал второй раз. Видимо имелось ввиду, что постоянно запущенное приложение на выч. сервере , которое будет через RMI взаимодействовать с Web-приложением? ------------ И вот еще , как запускать программы из консоли я нашел, но это для виндов. А как дела обстоят с линухом? Это сообщение отредактировал(а) Aprol - 26.1.2009, 14:43 |
|||
|
||||
| ivg |
|
||||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Проще ожидать ответа от программы на блокирующем чтении из потока, чем постоянно проверять готов ли ответ, а если учесть, что формат ответа может быть любым придётся усложнять реализацию, что вобщем то ни к чему. Нет, ОС.
Угу. Это один из вариантов. Аргументы я привел. Возможно в процессе реализации появятся другие условия.
Я думаю, принципиальной какой-то разницы нет, путь к файлу, аргументы командной строки, переменные окружения, всё это можно установить для конкретной ОС/процесса. |
||||
|
|||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
Решил сделать так:
Есть класс "задача" с полем id. через id задачи с этим объектом связаны объекты "исх.данные","решатель"(в нем вся логика конретной выч. программки или способ запуска программки) и "результат". -когда пользователь хочет запустить какую то задачу, то создается объект "задача". Вызывается метод у задачи, который создает "исх.данные" . потом "задача" запускает "решатель" и получает "результат". Как одновременно поддерживать несколько удаленных объектов "задача"? Может создать какой-то объект диспетчер, который будет манипулировать объектами "задача" и сделать их не удаленными и реализовать класс "задача" как поток? В итоге будет удаленный объект "диспетчер"(например rmi://server/dispatcher), который будет "плодить" потоки "задача"(по потоку для каждого пользователя). А те в свою очередь формировать "исх. данные", запускать "решатель", получать результат и передавать его через диспетчер клиенту? Возможно ли такое реализовать? -------------------------------- можно подробнее о Thread Pool? |
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
А зачем? Судя по описанию, объект "задача" - это, своего рода, контекст выполнения текущего вызова, или объект связанный с ним. Время жизни такого объекта не превышает длительности самого вызова. Если у вас другие мысли по этому поводу, излагайте... Долгоживущими объектами я предлагал сделать объекты "решателей" и объединить их в пул(ы). Во первых потому что "решатель", который связан с конкретным процессом, не должен использоваться одновременно несколькими потоками (процесс связанный с "решателем" ожидает ввода от одного пользователя, а не от нескольких, не так ли?). А во вторых это уменьшит время отработки команды, на период необходимый для старта процесса. По поводу потоков: я не вижу необходимости создавать какие-то дополнительный потоки на сервере. Каждый вызов от клиента, отрабатывает на сервере в своём потоке, в этом можно убедиться, вызывая удаленный метод на клиенте из нескольких потоков одновременно. Идея с одним удалённым объектом("диспетчером") хороша в том случае, если форматы входных и выходных данных всех программ схожи и все вызовы можно объединить в один или несколько методов. На другом краю - вариант, где на каждую конкретную программу свой удалённый объект. Что выбрать или найти золотую середину решать вам. http://en.wikipedia.org/wiki/Thread_pool java.util.concurrent.ThreadPoolExecutor |
|||
|
||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
Да. Этот класс должен уметь запускать "решатель", выдавать "результат", и загружать данные в "исх.данные", причем все это довольно абстрактно,т.к. "задача" не знает к какому классу относятся конкретные "решатель","результат", "исх.данные" . Знает только их интерфейс и родительский класс. Экземпляры создаются фабрикой, класс которой известен "задаче". Тут нужно обеспечить расширяемость, чтобы только используя xml-файлик (или БД) и подставляя готовые классы "решатель","результат","исх.данные" в директории приложения получать новые возможности. Наверное превышает. Сначала записали исх.данные->отключились,вызвали запуск решения-> отключились.
От одного. Но к моменту запуска "решателя" на исполнение все исх.данные уже есть. То есть, если я зарегистрирую объект Task(задача) на сервере и доступ к нему будет такой : rmi://server/Task То для каждого подключения клиента будет создан свой объект Task независящий от других? В качестве клиента у меня Web-сервер и запросы пользователей будут обрабатываться сервлетами, сервлет после отработки запроса убивается, а как потом восстановить подключение именно к нужному экземпляру объекта? Сохранять ссылку в сессии? Скорее нет, чем да. В качестве входных данных моэет быть и одно число и набор чисел и набор файлов. Вот пример как я себе это вижу. Есть программа, которая умножает два числа и запускается из командной строки. ----------- 1)пользователь логинится на Web-сервере 2)Выбирает задачу 3)Web-сервер обращается к RMI-серверу, создает экземпляр Task. (Web-сервер сохраняет ссылку на Task в сессию?) 4)RMI-сервер передает Web-серверу набор полей для исходных данных 5)WEb-сервер формирует страницу ввода этих параметров 6)Пользователь отправляет данные(два числа) 7)Web-сервер первично проверяет данные(синтаксис) и передает их RMI-серверу для детальной проверки(допустимые значение) 8)RMI-сервер в ответ присылает результат проверки. Если false пользователь повторяет ввод, если true то пункт9 9)Web-сервер создает страницу с кнопкой запуска задачи 10)пользователь отправляет запрос "выполнить задачу" 11)Web-сервер связывается с RMI-сервером и вызывает метод запуска задачи. 12) В методе запуска "задачи"(Task) создается решатель и вызывается на исполнение 13)Задача от решателя получает "результат" 14) объект "результат" парсит сам себя(тут не очень хорошо) 15)RMI-сервер возвращает "результат" Web-серверу 16)Web-сервер отправляет результат пользователю. ------------- Вроде так. Вообще есть еще несколько нюансов: -на RMI-сервере нужно создавать для некоторых программ директории. -Иметь возможность сохранять результаты в БД (Где лучше реализовывать на Web-сервере или RMI-сервере?) Это сообщение отредактировал(а) Aprol - 5.2.2009, 05:22 |
|||
|
||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
Написал пару примерчиков.
Выходит все-таки в RMI для каждого пути rmi://server/object соответствует только один экземпляр объекта. И не создается новый при вызове. Пробовал обращаться к объекту и с нескольких потоков и разных запущенных приложений. Результат один, объект один единственный. ------------ Возникла мысль тогда создавать rmi объекты динамически, и после выполнения задачи удалять его. Именовать объекты как rmi://server/Task_<id_пользователя>_<id_задачи>. Такой вариант имеет место быть? ------------------------- И еще не мешало бы учксть, то что некоторые задачи будут выполняться большое кол-во времени Это сообщение отредактировал(а) Aprol - 7.2.2009, 15:35 |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Я бы на вашем месте попытался сделать от начала и до конца веб-интерфейс сначала для одной программы. Самой простой. Потом, если останется время, для второй. Если это действительно нужно и вы не успеете все программы окучить, то следующие поколения дипломников продолжат.
Для каждой программы нужно сделать пару приложений - веб-приложение и вычислитель (RMI server). Веб-приложение (например, для программы task1) - это task1.war (возможно с одним index.jsp). И доступ к нему будет по адресу http://host/task1/ . А rmi server - это task1.jar . А потом можно создавать task2, 3, .. |
|||
|
||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
Я за простотой не гонюсь. Если бы хотел попроще, то и сделал бы чисто Web-приложение на сервлетах. Тупо запускать программу на выполнение из сервлета. Мне нужно гибкое приложение, чтобы можно было добавлять новые прогаммки по одному принципу, не создавая новых web-приложений. .А мне и не нужно все. Нужно одну-две, но сделать так чтобы они по созданному хелпу могли сами добавить новые задачи. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
я вам как раз для "гибкости" и советовал вариант: одна "прогаммка" - это одно веб приложение + один эрэмай сервер. Чтобы добавление нового не требовало перекомпиляции старого. Чтобы не надо было останавливать Томкат для добавления/модификации новой программы, а просто подкладывать/убирать war из директории webapp. |
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Ага, теперь более-менее понятно. Проверка выч. сервисом входных данных и собственно выполнение вычислений я бы объединил в одном вызове, для таких случаев уже давно придуманы Exceptions. Момент с существованием объекта "Задача" на выч. сервере между вызовами довольно спорен. Список всех выч. сервисов, набор типов входных данных для выбранного сервиса можно получать и без этого. Единственный аргумент из приведённого описания в пользу этого:
Можно считать, что сервис именования в RMI (java.rmi.registry.Registry) это просто HashMap, какой объект вы туда положили, на том и будет вызван метод. "Именовать" ненужно, просто возвращаете этот объект в удалённом вызове удалённому клиенту (веб-серверу), предварительно экспортировав его через java.rmi.server.UnicastRemoteObject. Ещё есть вариант - использовать преимущества современной спецификации EJB. То есть на выч. сервере использовать EJB-контейнер, который берёт на себя решение задачи организации управления удалёнными объектами, а ваш объект "Task", судя по описанию, по сути является Stateful Enterprise Java Bean. При этом совсем необязательно тащить здоровый Application Server, существуют довольно легковесные EJB-контейнеры, например openEJB от ASF. |
|||
|
||||
| Aprol |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 259 Регистрация: 15.6.2007 Репутация: нет Всего: нет |
EJB-это еще куча технологий, которые нужно изучить. Может времени не хватить +) А это как? При этом не нужно регистрировать объект с помощью rmiregistry? |
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
||||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |