![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
vasko |
|
|||
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 6.5.2006 Репутация: нет Всего: нет |
Для успешной работы сервлету необходим сокет(клиент) - один для всех сессии. В связи этим вопрос -
на какие подводные камни можно натолкнуться при реализации сокета в сервлете в связи с многопоточностью? Где лучше создавать, удалять, хранить? Предпологается создавать сокет в методе init() сервлета, а грохать в destroy() Хранить socket и данные, прочитаные из сокета, которые необходимо вернуть в браузер предпологаю в ServletContext
|
|||
|
||||
Tony |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1159 Регистрация: 3.3.2006 Где: Riga Репутация: 6 Всего: 12 |
Я не не очень понал вопроса.Зачем это всё ? Распиши подробней.
![]() |
|||
|
||||
ALKS |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 354 Регистрация: 22.3.2006 Репутация: 6 Всего: 11 |
vasko, просто это не получиться.
дело в том что апп сервер может запускать несколько инстансов для одного и того же сервлета в разных потоках. это делаеться для решения проблем производительности, причем ты это процесс можеш контролировать весьма слабо. Апп сервер сам принимает решение что "пора бы запустить еще один сервлет а то чего-то запросы повалили". единственно в чем можно быть уверен это что все эти сервлеты запускаються в рамках одного и того же процесса. т.е. это просто отдельные потоки и поэтому они могут "расшаривать" одни и те же статические объекты, нарпимер. т.е. самый ужастный путь - запрещать апп серверу создавать более одного сервлета, это возможно на уровне конфигурации вэб приложения, но это это смерть всех идей прозводительности заложенных в апп сервер делать сокет статичным и синхронизировать работу с ним - это тоже скажеться на скорости, но лучше чем первый путь. предполагать что клиентов-сокетов у тебя может быть не один, и разбираться с этим а это не факт что просто ![]() |
|||
|
||||
batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 16 Всего: 151 |
Вроде ведь есть путь указать сделать конкретный сервлет однопоточным (кажется, унаследовав его от SingleThreadServlet).
-------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
vasko |
|
|||
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 6.5.2006 Репутация: нет Всего: нет |
Сервлету необходимо взаимодействовать с другим модулем. Для связи между ними выбрал сокеты. В сервлете клиентский сокет, в модуле серверный сокет.
В сервлете, в методе GET и POST если параметр "needAnswere != 0" необходимо отправить данные по сокету, иначе если для данного HttpServletRequest мы уже получили данные по сокету, мы запихиваем данные в HttpServletResponse. Вопрос собственно в том, не будет ли накладок при работе с сокетом. Безопасно ли сохранять сокет в ServletContext? Я это делаю что бы обезопасить себя от разных инстансов сервлета + MultiThread Или можно в классе сервлета объявить сокет, в инит его инициализировать и безопасно пользоваться в GET и POST (в synchronized блоке)? |
|||
|
||||
ALKS |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 354 Регистрация: 22.3.2006 Репутация: 6 Всего: 11 |
еще раз: лобовой путь - все работу с сокетом запихнуть в спецальный статичный класс (ну или сингтон). ну и методы этого класса собственно работающее с сокетом засинхронизировать.
и в самом сервлетет просто этими методами пользоваться. Lamer George, про SingleThreadServlet просто не знаю. не сталкивался ![]() |
|||
|
||||
batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 16 Всего: 151 |
Пардон, похоже, я облажался. http://www.unix.org.ua/orelly/java-ent/servlet/ch03_04.htm ![]() Судя по этой картинке, всё как раз наоборот ![]() Это сообщение отредактировал(а) Lamer George - 18.5.2006, 14:26 -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
ALKS |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 354 Регистрация: 22.3.2006 Репутация: 6 Всего: 11 |
очень правильная картинка.
![]() но в реально жизни все может быть еще хуже. (зависит от того как сделан апп сервер) можно просто сказать апп серверу чтобы Servlet Pool содержал только один ServletInstance. Но тогда ноятно теряеться весь паралеллизм. если предположить что сервлет делает очень СPU зависимую работу и процессор только один, то это не страшно (даже наоборот в таком случае это будет очень правильное решение, для того и лазейка оставлена) но в реальной то жизни сервлы делают не очень-то СPU Зависимую работу там в основном память и работа с источниками данных. да и современный сервер даже простой это много процесорно-много ядерное что-то... так что такие игры с конфигурацией они не рекомендуються настоятельно. Это сообщение отредактировал(а) ALKS - 18.5.2006, 14:40 |
|||
|
||||
vasko |
|
|||
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 6.5.2006 Репутация: нет Всего: нет |
ALKS, сокет у меня асинхронный, поэтому при записи и чтение больших тормозов не будет....
По поводу разных инстансов - по этому поводу имеются вопросы: Будет ли для разных инстансов вызываться свой инит или он вызовется сто пудово один раз для всех инстансов? У разных инстансов одного и того же сервлета один ServletContext или нет? Если я в одном инстансе в ServletContext сохраню сокет, а в другом инстансе достану - будет ли он валиден? Или лучше (для быстродействия) статиком его сделать? |
|||
|
||||
ALKS |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 354 Регистрация: 22.3.2006 Репутация: 6 Всего: 11 |
сервлет контекст. т.е. контекст конкретного сервлета. т.е. он будет разный у каждого сервлета.... наверное.... не уверен
![]() а вот при создание нового инстанса сервлета и помещении его в Servlet Pool будет однократно вызван инит. ну т.е. инит это как конструктор. вот в этом я уверен ![]() Добавлено: вот из описания к Interface ServletContext: There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog and possibly installed via a .war file.) Это сообщение отредактировал(а) ALKS - 18.5.2006, 15:41 |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Рискну выразить мнение, что инстанс сервлета - всегда один.
SingleThreadModel - давно и окончательно признано неприемлемым. Привязывать сокет к сервлету на мой взгляд просто неудобно. Сокет может закрыться, значит нужен монитор, который восстановит соединение. Доступ к сокету очевидно должен быть синхронизированным, возможно очередь нужна. |
|||
|
||||
ALKS |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 354 Регистрация: 22.3.2006 Репутация: 6 Всего: 11 |
это кем когда и почему оно непреемлемо? и JRun4 100% так работает.
и зачем тогда <load-on-startup> элемент в элементе <servlet> в web.xml? если он всегда один? |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Применение SingleThreadModel - устаревшая концепция (именно имплементация этого интерфейса и является сигналом контейнеру создавать пул инстансов). Потому что два инстанса сервлета ничем не лучше, чем один.
Сервлет не должен хранить в себе состояние пользователя. Оно хранится в сессии, которая создается для каждого пользователя. Методы сервлета (doGet..) должны содержать только локальные переменные, тогда сервлет будет потокобезопасным. И в этом случае обрабатывать одновременно несколько потоков пользователей без разницы, одним инстансом или несколькими. При таком подходе нет причин иметь больше одного инстанса. Это я своими словами, а линк не могу пока найти. ![]() Это сообщение отредактировал(а) COVD - 18.5.2006, 16:50 |
|||
|
||||
vasko |
|
|||
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 6.5.2006 Репутация: нет Всего: нет |
Сокет мне для работы необходим, так как нужен обмен данными с другим приложением (кому интересно, то обсуждение было в "Асинхронный ответ" http://forum.vingrad.ru/index.php?showtopic=94893 )
Судя из сказанного, сокет необходимо будет делать сингтоном или статиком. А как в сервелтах работают с БД? Я просто в java с ними не работал, но ведь наверняка там тоже есть соединение с БД.... Как их шарят между инстансами в GET, POST? Или народ не беспокоит количество одновременно открытых соединений с БД? По поводу только локальных переменных. А как же быть например с HttpSession? ведь что произойдет без синхронизации в примере: от клиента практически одновременно пошли два запроса GET с парам. 1 и 2 к сервлету А и на сервере обработались двумя инстансам сервлета А: метод GET
Я думаю без синхронизации такой код не валиден...... |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Два запроса - это два разных потока.
Все в этом коде будет выполняться независимо, в разных разделах памяти. Это справедливо, если в используете в вычислениях только входные параметры (httpServletRequest) и локальные переменные (session должна быть описана как локальная, т.е. Session session = ..., но она и по сути локальная, нет нужды ее описывать как глобальную) А вот если вы обращаетесь в ходе обработки запроса к базе данных, то надо использовать или пул соединений (чтобы каждому потоку свое соединение), или синхронизировать доступ к соединению, если оно одно на всех (что не очень хорошо, но вполне рабочий вариант, если нагрузка не велика). Это сообщение отредактировал(а) COVD - 18.5.2006, 18:01 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |