forum.bitel.ru http://forum.bitel.ru/ |
|
[BUG] zoneTraffics cache abuse http://forum.bitel.ru/viewtopic.php?f=6&t=6041 |
Страница 1 из 1 |
Автор: | Cromeshnic [ 27 окт 2011, 08:50 ] |
Заголовок сообщения: | [BUG] zoneTraffics cache abuse |
BGRadiusVoip version 5.1 build 167 from 14.06.2011 11:40:22 При большой нагрузке встаёт колом. Начинаем разбираться: - В innotop висят такие запросы: Код: SELECT zone, SUM(round_session_time) FROM log_session_22_201110 WHERE lid=2 GROUP BY zone Руками такой запрос выполняется за 5-6 секунд. Много. По jstack с помощью декомпилера определяем, что потоки блокируются на: Код: synchronized (this.itemZoneTrafficCache) , пока один поток обновляет кэш трафиков по зонам для логина (необходимый, как я понимаю, для тарификации): Код: Calendar cacheTime = (Calendar)this.loginsWithZoneTrafInit.get(Integer.valueOf(loginId)); if ((cacheTime == null) || (TimeUtils.monthsDelta(time, cacheTime) != 0) || (time.getTimeInMillis() - cacheTime.getTimeInMillis() > 300000L)) { try { String tableName = ServerUtils.getModuleMonthTableName("log_session", time.getTime(), this.mid); if (!ServerUtils.tableExists(con, tableName)) break label261; String query = "SELECT zone, SUM(round_session_time) FROM " + tableName + " WHERE lid=? GROUP BY zone"; PreparedStatement ps = con.prepareStatement(query); ps.setInt(1, loginId); synchronized (this.itemZoneTrafficCache) { Map traffic = new HashMap(); ResultSet rs = ps.executeQuery(); while (rs.next()) { traffic.put(Integer.valueOf(rs.getInt(1)), Integer.valueOf(rs.getInt(2))); } ps.close(); this.itemZoneTrafficCache.setZoneTraffic(Integer.valueOf(loginId), traffic); } this.loginsWithZoneTrafInit.put(Integer.valueOf(loginId), time); } catch (Exception e) { e.printStackTrace(); } } else { this.loginsWithZoneTrafInit.put(Integer.valueOf(loginId), time); } Казалось бы, почему так часто обновляется кэш из базы - ведь судя по коду он должен обновляться, только если последние 5 минут (300000L ms) по нашему логину вообще не было сессий. (Тут я, если честно, вообще не понял, зачем нужны эти 5 минут, если кэш актуализируется на лету при добавлении новой сессии, ну да ладно) Смотрим, откуда берется time: Код: Calendar time = new GregorianCalendar(); int sessionTime = request.getIntAttribute(-1, 46, Integer.valueOf(0)).intValue(); time.add(13, -sessionTime); session.setStartTime(time); session.setSessionTime(sessionTime); session.setItemZoneTrafficCache(initZoneTraffics(login.getId(), con, session.getStartTime())); Т.е. time в initZoneTraffics - время старта сессии, а не текущее или время окончания сессии. Т.е. сессии длительностью > 5 минут заведомо попадают мимо кэша, кидают в базу 6-секундный запрос и объявляют кэш устаревшим, пока следующая сессия не обновит time для кэша на более актуальный. Поскольку сессии обрабатываются в многопоточной среде, при этом лочится куча следующих сессий, пока наконец одной не удастся установить нормальное время для кэша. Затем всё повторяется снова. По факту у меня, встав колом один раз, сервер в таком состоянии остаётся очень надолго: Вложение: Почему такое происходит только у меня: Мы решили собирать статистику по операторам, для чего завели отдельный экземпляр модуля VoiceIP со своим радиусом. В итоге имеем большую нагрузку и всего 2 логина voiceip, на которые всё валится. Видимо когда эти проблемы с кэшем размазаны на множество логинов, они так себя не проявляют. Уменьшил количество потоков обработки до 30 - всё то же самое. Вот как-то так. Может стоит убрать эти 5 минут? Или брать time - текущим временем? |
Автор: | Cromeshnic [ 27 окт 2011, 09:05 ] |
Заголовок сообщения: | Re: [BUG] zoneTraffics cache abuse |
зы. Использовать штатные средства для операторской отчетности не предлагать ![]() У нас телефония размазана между Phone и VoiceIP, поэтому так опрятнее (если бы работало ещё...) |
Автор: | Amir [ 18 ноя 2011, 20:46 ] |
Заголовок сообщения: | Re: [BUG] zoneTraffics cache abuse |
Со временем там вроде бы все нормально, проблема возникает из-за множества звонков на малом количестве логинов. Выложили 176 билд: немного оптимизировали загрузку кэша, добавили параметр - таймаут кэша radius.zoneTrafficCacheTime=в секундах |
Страница 1 из 1 | Часовой пояс: UTC + 5 часов [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |