Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Glassfish падает на потоковом видео


Автор: NikitOS9 31.8.2009, 22:53
используется glassfish 2.1, ejb3, toplink, postgreSQL.
на клиенте flex, и есть видео плеер. он обращается к сервлету и получает от него поток.
работает несколько запросов, после этого падает.
 
сервлет представляет собой примерно вот:

Код

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
..
    response.setContentLength((getBinData().getFileSize());
    BufferedOutputStream output = new BufferedOutputStream(response.getOutputStream());
    output.write(getBinData().getBytes());
    output.flush();
    output.close();
}


бинарные данные беруться из базы

Код

Bindata getBinData(){
...
   dbManager.getBinDataByID();
..
}


dbManager это бин

Код

@Stateless(name = "DBManagerBean")
public class DBManagerBean implements DBManager {
  @PersistenceContext(unitName = "cityJPA")
  private EntityManager em;
  .....
getBinDataByID(){
    BinData ret = null;
    try{
      ret = em.find(BinData.class, id);
    } catch (Exception ex){
      ex.printStackTrace();
    }
}
   .....


видео файлы размером пока 50 - 100 мегов. в формате flv 
оживляется перезагрузкой glassfish

в стеке есть такое
Caused by: org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:220)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
    at sun.reflect.GeneratedMethodAccessor112.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$StatementHandler.invoke(AbstractJdbc23PooledConnection.java:477)
    at $Proxy50.executeQuery(Unknown Source)
    at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:726)
    at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:501)
    ... 83 more
Caused by: java.io.EOFException
    at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:261)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1182)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:194)
    ... 93 more

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

что тут можно сделать ?

Спасибо



Автор: COVD 1.9.2009, 00:04
Почему бы не взять за основу например open source flash server http://www.osflash.org/red5 (ваше решение на мой взгляд неудачное)

Автор: AJetman 1.9.2009, 00:12
Glassfish и ему подобные контейнеры не предназначены для реализации подобных сервисов! Советую дальше и не пытаться и тем более еще выгружать данные из БД (как только БД еще не умерла?!).

Если у вас просто файлы FLV и вам, как я понял, необходимо скрыть названия файлов, то следуйте простой схеме и ничего у вас падать не будет:
1. Установить frontend-сервер: NGINX, а Glassfish будет выполнять у нас роль backend'a.
2. Все видеофайлы хранить в виде файлов, ни в коем случае не в базе.
3. При получении запроса на видеофайл отправлять в сервлете заголовок: 
Код

X-Accel-Redirect: АбсолютныйПутьКФайлу

Что скажет Nginx отдавать контент клиенту из вашего файла, а Glassfish завершит запрос и не будет лишний раз напрягаться.

Вот такая схема - одна из реализаций.

Вообще у Nginx есть еще и специальный модуль для стриминга FLV... Как и у Lighttpd и других серверов. 

Автор: NikitOS9 1.9.2009, 00:14
да изначально видео не предполагалось. фотографии и панорамы, это дописалось за пару часов. 
про red5 слышал, и видимо буду использовать, но это же тоже должно работать хоть медленно, а не валиться после пару запросов


Автор: AJetman 1.9.2009, 00:18
Цитата(NikitOS9 @ 1.9.2009,  00:14)
да изначально видео не предполагалось. фотографии и панорамы, это дописалось за пару часов. 
про red5 слышал, и видимо буду использовать, но это же тоже должно работать хоть медленно, а не валиться после пару запросов

Glassfish не может не валиться и скорее всего он умирает от недостаточного количества выделенной памяти в JVM. В коде 
Код
output.write(getBinData().getBytes());
 ваша программа сначала выгружает 100мб из БД в память JVM, затем выгружает ее в еще один буфер и затем происходить отдача...

Добавлено @ 00:19
red5 - глючная и довольно сложная в работе система. Рекомендую обратить внимание на более легковесные Nginx и Lighttpd. Или вас пугает, что это не Java-powered решения?

Автор: NikitOS9 1.9.2009, 00:32
нет не пугает. скрывать мне ничего не нужно, просто хранить в базе удобно, сервис - каталог фотографий, панорам и видео.
ну мне казалось что хранить файлы в базе это нормально, в postgresql максимальный объем записи 1 GB.
сервис находится на VPS, выделенная память 800 мегов, вполне возможно что из за этого

а как вариант создавать временные файлы и потом их отдавать, то есть если запрашивали такой файл, то не тащить его из базы, а отдать по линку из временно директории ?

Автор: serger 1.9.2009, 11:38
Ну можно же просто из blob брать поток и с ним работать (getBlobAsStream).. Не выгружая в память или файловую систему, если уж вы загнали всё в БД.

Автор: NikitOS9 1.9.2009, 15:34
да видимо можно, не знал про это.
а как связать сервлет или што нибуть с этим getBlobAsStream, так как видео плееру нужно указать урл, откуда брать видео поток


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)