У меня проблема с масштабированием количества одновременных пользователей в моей системе. Судя по моим тестам, масштабирование количества одновременных пользователей напрямую увеличивает продолжительность запроса в линейной зависимости.
Я запускаю веб-приложение Java, развернутое на (виртуальной) машине Ubuntu Quad Core с 16 ГБ ОЗУ. Я использую Apache Tomcat 7 и базу данных MySQl 5.5. Tomcat и MySQL используют настройки по умолчанию — я их никак не настраивал.
Я использую Apache Benchmark для запуска ряда тестов, которые в конечном итоге создают SQL-запрос для возврата одной строки данных, где размер ответа очень мал.
Я использую Spring JDBCTemplate и Apache Commons BasicDataSource. Конфигурация Spring bean показана ниже.
<!-- READ ONLY CONNECTION TO DATABASE -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="username">
<value>${database.username}</value>
</property>
<property name="password">
<value>${database.password}</value>
</property>
<property name="url">
<value>${database.url}/${database.schema}</value>
</property>
<property name="timeBetweenEvictionRunsMillis" value="7200000" />
<property name="minEvictableIdleTimeMillis" value="3600000" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="5" />
<property name="defaultAutoCommit" value="false" />
<property name="defaultReadOnly" value="true" />
</bean>
<bean id="myDao" class="...">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
Мой метод Java, который создает пару запросов, помечен @Transactional.
Вот результаты моих тестов:
- 1 запрос занимает 0,2 секунды.
- 10 запросов (выполняемых одновременно) занимают 0,9 секунды.
Таким образом, вы можете видеть, что мое приложение не масштабируется. Я не уверен, в чем может быть причина проблемы. Может ли кто-нибудь увидеть, что я делаю неправильно, или предложить способы дальнейшего изучения этого вопроса?
Заранее спасибо,
Фил
Обновить
Дополнительные показатели:
1 Request, Concurrency 1 = 0.22s 10 Requests, Concurrency 10 = 0.6s (mean), 0.5(min) 100 Requests, Concurrency 100 = 7 (mean), 3.7(min) 300 Requests, Concurrency 300 = 12s (mean), 4.3(min) 300 Requests, Concurrency 300 = 18s (mean), 6.4(min)
Размер ответа 1кб.
Попытка одинаковых запросов и изменение параллелизма:
300 Requests, Concurrency 8 = total time: 14.9s 300 Requests, Concurrency 20 = total time: 15.3s 300 Requests, Concurrency 300 = total time: 24s
Таким образом, уменьшение параллелизма до 8 завершает 10 секунд быстрее, чем параллелизм 300. Увеличение с 8 замедляет транзакции. 8 кажется наиболее оптимальным параллелизмом.