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


Автор: mantracoder 13.10.2008, 08:44
Добрый день!

Экспериментирую со скоростью закачки какого-либо файла посредством сервлета. Код написан на коленке за минут 10, посему качество оного предлагается оставить в стороне от обсуждаемой проблемы. Лимит по скорости грубо задается размером массива, который ссыпается в исходящий поток раз в секунду. Закачка работает правильно, лимит скорости соблюдается. Проблема заключается в том, что в единицу времени доступна только 1 закачка. Т.е. если попытаться открыть второе окно и дернуть нужный линк, то вторая закачка если и появится, то останется в подвешенном состоянии, пока не завершится первая. Третья параллельная попытка закачки не дает даже диалога сохранения, пока не завершится одна из двух предыдущих закачек.

Код

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String fileName = request.getParameter("file");
        if (fileName == null) {
            return;
        }
        
        File sourceFile = new File("C:/temp/" + fileName);
        if (!sourceFile.exists() || !sourceFile.isFile()) {
            return;
        }
        
        response.setHeader("Content-Disposition", "attachment; filename=\"" + sourceFile.getName() + "\"");
        response.setHeader("Content-Type", "application/octet-stream");
        response.setHeader("Content-Length", String.valueOf(sourceFile.length()));

        FileInputStream in;
        
        try {
            in = new FileInputStream(sourceFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        }
        
        try {
            
            byte[] buffer = new byte[10240];
            int available = 0;

            while ((available = in.available()) > 0) {
                
                if (available > buffer.length) {
                    available = buffer.length;
                }

                in.read(buffer, 0, available);
                response.getOutputStream().write(buffer, 0, available);
                
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


Изначально я думал, что проблема может быть в блокировании ресурса одним из потоков. Однако если убрать из этого кода любое упоминание файлов и потоков, проблема остается. "Соревнуются" первые 2 запроса к сервлету, третий "висит" до окончания одного из двух предыдущих.

Где-то мне попадалось на глаза утверждение, что разрешается не более 2 конкурентных запросов к одному и тому же ресурсу с одного IP-адреса. И если это действительно так, то как обойти это ограничение?

Автор: skhilkov 13.10.2008, 10:17
А может просто попробовать в отдельных потоках сделать раздачу? Ты ведь сервлет усыпляешь слипами (если я правильно понимаю). 
Сделай что-нибудь типа (я не компилировал, просто навскидку написал.... так что если ошибки вылезут... я не виноват )))  )

Код

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Runnable job = new Runnable()
{
       public void run()
{
        String fileName = request.getParameter("file");
        if (fileName == null) {
            return;
        }
        
        File sourceFile = new File("C:/temp/" + fileName);
        if (!sourceFile.exists() || !sourceFile.isFile()) {
            return;
        }
        
        response.setHeader("Content-Disposition", "attachment; filename=\"" + sourceFile.getName() + "\"");
        response.setHeader("Content-Type", "application/octet-stream");
        response.setHeader("Content-Length", String.valueOf(sourceFile.length()));
        FileInputStream in;
        
        try {
            in = new FileInputStream(sourceFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        }
        
        try {
            
            byte[] buffer = new byte[10240];
            int available = 0;
            while ((available = in.available()) > 0) {
                
                if (available > buffer.length) {
                    available = buffer.length;
                }
                in.read(buffer, 0, available);
                response.getOutputStream().write(buffer, 0, available);
                
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
}
    };

    (new Thread(r)).start();
}

Автор: redrick 13.10.2008, 11:25
Цитата(mantracoder @  13.10.2008,  08:44 Найти цитируемый пост)
Где-то мне попадалось на глаза утверждение, что разрешается не более 2 конкурентных запросов к одному и тому же ресурсу с одного IP-адреса. И если это действительно так, то как обойти это ограничение?

ну это явно не так: например если мы сидим 100 человек под одним ипишником - мы же можем зайти на один и тот же сайт без проблем.

мне кажется дело в порочности sleep(), хотя палюбому сервер должен заводить новый тред для нового запроса 

Автор: alexadr 13.10.2008, 14:10
Я бы посоветовал для начала залогировать каждую строчку сервлета, чтобы понять где толком начинаюца тормоза, - где оно подвисает.

Плюс возможно какие-то проблемы при чтении двумя потоками одного и того же файла(это если в данном случае два клиента скачивают одно и тоже).

Ну и ешо конечно sleep надо менять на:

Код

synchronized(lock) {
   lock.wait(someTime);
}

Автор: necromancer 14.10.2008, 13:37
а может дело в браузере через который дергается закачка? =)
у меня с сервера одновременно льют до 100 потоков и никто не тормозит.
А вот браузер может ограничивать кол-во каким либо образом.
либо же тормозить может система локально, т.е. загрузка проца на 100% при чтении/записи из потоков не дает времени браузеру обработать 3-й клик.

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