Быстрый старт для нетерпеливых
- Загрузите и разархивируйте исходные коды из раздела Загрузка.
- Настройте ODBC-подключение так, чтобы оно указывало на БД, мониторинг которой вы хотите осуществлять.
- Настройте PHP для работы с графикой при помощи пакета JpGraph.
- Модифицируйте скрипт "goqc" для соответствия вашей среде.
- Для создания рабочей нагрузки для БД используйте JMeter или Rational® Performance tester.
- Настройте удаленного агента для сравнения производительности БД при работе с локальными подключениями и в сетевой среде.
Тёмные политические искусства: игра в поиск виноватых
Обеспечение надёжной работы корпоративной БД администраторы считают делом чести. Поэтому получая претензии к низкой скорости работы БД и сбоям в программах, они испытывают сильный стресс. В статье описано, как для избежания ложных обвинений и быстрого выявления и разрешения возникших проблем получить график состояния БД в режиме реального времени (см. рисунок 1).
Рисунок 1. Статус БД в режиме реального времени
По оси X мы откладываем время, левая ось Y – время ответа в секундах, а правая ось Y – количество подключенных пользователей. Из рисунка 1 прекрасно видно, что несмотря на большую нагрузку в виде одновременно подключенных 300 пользователей, БД работает довольно хорошо, а время ожидания ответа не превышает 1.5 секунды. С учётом того, что симулятор работает на ноутбуке с одним жёстким диском, эти показатели можно считать выдающимися. Такой график показывает, что БД работает без проблем. Если же что-то сломается, то вы оперативно узнаете об этом и сможете найти источник проблемы.
Контроль качества БД и статистические выборки данных
Для получения показанного на рисунке 1 графика необходимы данные о состоянии сервера. Statistical Process Control позволит без проблем собрать данные и отобразить их на Web-странице. Более подробную информацию о Statistical Process Control вы найдёте в разделе Ресурсы. Именно этот разрекламированный профессором Деммингом процесс улучшения качества и поднял качество товаров с ярлыком "made in Japan" до нынешних высот.
При сборе данных следует учитывать два момента:
- Частоту сбора результатов – в соответствии с теоремой Найквиста
- Влияние процесса сбора результатов на сами результаты – в соответствии с принципом неопределённости Гейзенберга
В соответствии с теоремой Найквиста, для получения точной выборки данных о некоем событии, длящемся, скажем, 20 секунд, срез данных надо делать каждые 10 секунд. Это значит, что если вы хотите получать информацию о перебоях в работе БД с точностью до одной минуты, то делать выборки из БД надо каждые 30 секунд. В прилагаемом скрипте выборка данных производится каждые 2 секунды, что обеспечивает быстрый отклик, однако генерирует довольно большие объёмы информации за небольшие интервалы времени.
Рассмотрим вопрос влияния процесса сбора результатов на сами результаты. Я воспользовался принципом неопределённости Гейзенберга для определения местоположения ключей от своей машины – и установил, что они находятся где-то во вселенной. Гейзенберг вёл речь о позиции и моменте движения элементарных частиц, однако идея ясна. Когда сервер БД замедляется, то толпа людей, заходящих на него с целью проверить это и найти причину, лишь усугубит проблему. Инструменты в данном примере передают работу по отображению страницы со статусом другому серверу. Эта архитектура удерживает "наблюдателей" на расстоянии от сервера БД, так что те не усугубляют существующую проблему.
Quality Control Sampling Agent
Задача агента Quality Control Sampling Agent проста – получать статус БД и записывать эти данные в таблицу БД. Почти любые данные о сервере БД можно получить из табличных функций DB2® или из БД Informix® sysmaster database.
Архитектура размещения агента показана на рисунке 2. Здесь есть как локальный, так и удалённый агенты. В примере создаётся только один агент. Для создания двух агентов схему и код надо изменять.
Рисунок 2. Архитектура размещения собирающего данные агента
Зачем использовать одновременно и локального, и работающего через сеть удалённого агентов? Поскольку вы стремитесь изолировать проблему, чтобы найти ее решение, а не просто констатируете ее наличие, различия во времени отклика локального и удалённого агентов позволят вам выявить проблемы в работе сети. Представьте себе радость сетевых администраторов, с которой они примут желающего сообщить им о проблемах в сети администратора БД.
В разделе Загрузка есть две разновидности агента. В каталоге Informix лежит агент esql/c. В каталоге ODBC хранится агент DB2, в целях достижения максимальной переносимости написанный на PHP.
Программа выполняет следующие шаги:
- Запускает таймер.
- Подключается к БД.
- Измеряет время, затраченное на подключение к БД.
- Создаёт в таблице transtimes новую строку, содержащую текущее время, уникальный ключ и время подключения.
- Собирает всю необходимую статистику о БД и симулирует простую транзакцию.
- В созданную на 4-м шаге строку записывает собранную на 5-м шаге статистику вместе с потраченным на выполнение 5-го шага временем.
График на рисунке 1 показывает количество подключений, скорость подключения и время, затраченное на операции вставки/обновления. В используемую агентом Informix схему (листинг 1) таблицы также включён объём выделенной и используемой виртуальной памяти. Это - иллюстрация простого интерфейса для работы с сервером, предоставляемого Informix sysmaster и табличными функциями DB2. Собирая данные, вам не придётся при помощи sed, awk, grep и perl пробиваться сквозь огромные объемы данных, полученных в результате запуска команды onstat или выполнения моментальных снимков БД.
На 5-м шаге симулируется простая транзакция, обеспечивающая типичную для системы рабочую нагрузку. Эта транзакция даёт информацию о том, что предстоит испытать типичному пользователю данной системы. Например, в принимающей телефонные звонки OLTP-системе симуляцией типичной транзакции мог бы быть поиск клиента в БД. Если БД, за которой вы следите, предназначена для поддержки принятия решений, и типичные запросы в ней длинны и сложны, не надо запускать агента контроля качества (QC) со сложнейшими запросами. Помните о принципе неопределённости Гейзенберга. Большой запрос DSS от агента контроля качества лишь замедлит работу всей БД.
Листинг 1. Схема, используемая в версии агента контроля качества Informix esqlc
-- (c)2006 copyright Martin Lurie, sample code, not supported
create database oltpqc;
database oltpqc;
drop table transtimes;
-- the DB2 identity datatype is similar to Informix serial
-- in the php version of the code a simple integer was used and
-- php increments the transkey, this gives maximum portability
create table transtimes ( transkey serial primary key,
timestamp datetime year to second,
connect_time float,
session_count integer,
vblkused integer,
vblkfree integer ,
query_insert_time float
);
|
Используемая для агента контроля качества на PHP схема DB2 показана в листинге 2.
Листинг 2. Схема DB2, используемая для агента контроля качества на PHP
-- (c)2006 copyright Martin Lurie, sample code, not supported
create database oltpqc;
connect to oltpqc;
drop table transtimes;
create table transtimes ( transkey int primary key,
timestamp date,
connect_time float,
session_count integer,
query_insert_time float
);
|
При сборе данных вы не ограничены этой схемой. Вы можете включить в таблицу с выборкой любые данные, которые захотите собирать при помощи агента. Этот проект был создан из-за "поиска виноватых" между разработчиками программ и администраторами БД. Собранная информация продемонстрировала линейную зависимость между количеством пользователей и потреблением памяти. Полученные данные позволили прекратить споры и изменить приложение таким образом, чтобы оно прекращало устанавливать новые соединения, если время ответа существенно замедлилось.
В листинге 3 приведена табличная функция, запрашивающая количество пользователей, подключенных к DB2. В разделе Ресурсы вы найдёте информацию об использовании остальных табличных функций и, в случае Informix, БД sysmaster.
Листинг 3. Запрос табличной функции DB2 для получения количества одновременно работающих пользователей
-- (c)2006 copyright Martin Lurie, sample code, not supported
select local_cons +rem_cons_in from table (snapshot_dbm (-1))as snapshot_dbm
|
Для получения информации о сервере Informix вместо табличных функций использует БД sysmaster. Запрос количества пользователей, осуществляемый Informix, показан в листинге 4.
Листинг 4. Запрос Informix sysmaster для получения количества одновременно работающих пользователей
/* this sql is from the esqlc program, so the result set is
stored in a host variable. */
select count(*)
into :sessioncount
from sysmaster:syssessions;
|
Код агента чрезвычайно прост. "Секрет" получения связи с БД ODBC для платформы PHP заключён в файле odbc.ini. Большое количество документации о связи PHP ODBC можно найти в разделе Ресурсы. В листингах 5 и 6 приведены файлы odbc.ini для DB2 и Informix соответственно. При наличии времени вместо использования ODBC вы можете написать PHP с прямыми драйверами. В нашем же примере скорости работы ODBC вполне хватает, и оно здесь будет использоваться как в клиентах, так и для сбора данных для построения графика работы.
Листинг 5. Файл odbc.ini для настройки ODBC с DB2 под Linux
[ODBC Data Sources]
SAMPLE=IBM DB2 ODBC DRIVER
[SAMPLE]
Driver=/home/db2inst1/sqllib/lib32/libdb2.so
Description=DB2 Sample database
|
Листинг 6. Файл odbc.ini для настройки ODBC с Informix под Linux
[ODBC Data Sources]
SAMPLE=INFORMIX DB2 ODBC DRIVER
Driver=/home/db2inst1/sqllib/lib32/libdb2.so
Description=Informix smaple odbc.ini
[ODBC Data Sources]
Infdrv1=IBM INFORMIX ODBC DRIVER
Infdrv2=IBM INFORMIX ODBC DRIVER
;
; Define ODBC Database Driver's Below - Driver Configuration Section
;
[Infdrv1]
Driver=/home/informix/lib/cli/iclit09b.so
Description=IBM INFORMIX ODBC DRIVER
Database=stores_demo
LogonID=odbc
pwd=odbc
Servername=ids_server1
[Infdrv2]
Driver=/home/informix/lib/cli/iclit09b.so
Description=IBM INFORMIX ODBC DRIVER
Database=oltpqc
LogonID=informix
pwd=useYourOwnPassword
Servername=k_ids
Trace=0
TraceFile=/tmp/odbctrace.out
InstallDir=/home/informix
|
Система раннего обнаружения: генерация предупреждений
Было бы неплохо администратору узнавать о снижении скорости работы БД до того, как к нему пойдут звонки от пользователей. Узнавать о проблемах первым – это ответственность и дело чести администратора БД. Речь идет не о поиске виновных, а об обеспечении бесперебойной работы БД.
Код oltpqc предполагает наличие в командной строке позиционного параметра, определяющего пороговое значение для возникновения тревоги. Это значение определяется в миллисекундах. Когда время ожидания ответа превысит данное значение, запустится скрипт Unix/Linux. Код для создания предупреждений показан в листингах 7 и 8 соответственно для esqlc и PHP.
Листинг 7. Код ESQLC для генерации предупреждений при превышении лимита времени ожидания ответа
/* code to capture the positional paramter from the command line */
if (argc == 2 ) {
thresholdms = atoi ( argv[1] );
#ifdef PRTDIAG
printf( "argv[1] %s thresholdms %d \n", argv[1], thresholdms );
#endif
printf( "(c)copyright 2005 - alarm %d milli-seconds \n", thresholdms );
}
else
{
printf(
"(c)copyright 2005 - USAGE: %s threshold_millisec\n", argv[0] );
printf( "example: %s 1500\n" , argv[0] );
printf( "generates an alarm when response time is over 1.5 seconds\n" );
return -1 ;
}
/* ... lines deleted .... */
/* logic to run a shell script and pass in the response time data
to the shell script */
asprintf ( &alarmstring , "./slowalarm.sh %f %f " ,
elapsed_con, elapsed_wrk );
if ( ( elapsed_wrk+elapsed_con ) > (float)thresholdms/(float)1000 )
system ( alarmstring);
#ifdef PRTDIAG
printf ( "times elapsed_wrk %f , elapsed_con %f , thres %f \n",
elapsed_wrk,elapsed_con, ( (float)thresholdms/(float)1000 ) );
#endif
|
Листинг 8. Код PHP для генерации предупреждений при превышении лимита времени ожидания ответа
//check to see if alarm should be sounded
if (($third_time - $first_time)*1000 > $thresholdms)
{
echo "DATABASE SLOW ALERT - CONNECT AND QUERY TIMES" ;
echo "GREATER THAN $thresholdms MILISECONDS\n\n";
system ("alert.sh");
}
|
Публикация результатов наблюдений, непригодность электронных таблиц
Для этого проекта принципально важна возможность публиковать данные в интернете. Без правильного распространения и интерпретации ценность полученных из наблюдений данных невелика. До недавнего ремени для построения графиков в режиме реального времени лучше всего подходили электронные таблицы. Почтовая рассылка таблиц с информацией о состоянии сервера – занятие довольно утомительное. Однако если таблица настроена на динамическое обновление и повторное подключение к БД, то каждое обновление данных на каждом из наблюдающих за базой компьютеров будет отнимать у неё драгоценные циклы. На рисунке 3 показана электронная таблица анализа количества пользователей и времени ожидания ответа, однако приведена она исключительно в ознакомительных целях; пользоваться такими таблицами категорически не рекомендуется.
Рисунок 3. Использование электронных таблиц для отображения собранных данных; обратите внимание на ось Y
Замечательное место для публикации информации о состоянии сервера БД, полученной от агента контроля качества – Web-сайт. График, изображенный на рисунке 4, получен с помощью пакета JpGraph (дополнительную информацию о нём можно найти в разделе Ресурсы). Этот PHP-код даёт вам в руки превосходный инструментарий для построения графиков. Для работы с ним вам придётся установить некоторые модули, в том числе gd и php-gd. Создание графиков для Informix оказалось намного проще создания графиков DB2. Именно здесь раскрывается элегантность использования PHP и ODBC-подключения к БД в целях достижения переносимости.
Рисунок 4. Отображение статуса БД с помощью PHP-пакета для создания графиков JpGraph
Обратите внимание, что фоном для графика в JpGraph вы можете сделать любой рисунок в формате jpg. На рисунке 4 на фоне видна спортивная машина, спонсором которой выступает Informix.
График статуса БД автоматически обновляется. Отображение состояния БД на статической странице не имеет смысла. Однако в данном случае никакие модные технологии, вроде AJAX, не применяются, исключительно простой HTML. Взгляните на листинги 9 и 10 и подумайте, чем так "плох" один и "хорош" другой? В листинге 9 периодически выполняется следующее задание: php qcgraph.php > foo.jpg
Листинг 9. "Хорошая" автоматически обновляемая страница HTML
<META >-EQUIV=Refresh CONTENT="3; URL=index.html">
<h1>Database Real Time Status</h1>
Click the refresh button if the graph does not appear below.
<hr>
<img src="foo.jpg">
<hr>
<!-- this page assumes a cron job is running periodically that
performs the following: php qcgraph.php > foo.jpg -->
|
Листинг 10. "Плохой" листинг страницы с автоматическим обновлением – он работает, но так делать не надо
<META HTTP-EQUIV=Refresh CONTENT="10; URL=auto.html">
<h1>Database Real Time Status</h1>
<img src="qcgraph.php">
<hr>
|
Вы уже, пожалуй, поняли, что "плохой" код автоматического обновления при большом количестве желающих полюбоваться на график сильно нагрузит сервер. На это указывают принцип неопределённости Гейзенберга вместе с законом Мерфи. Проверка состояния БД создаёт для сервера лишнюю работу. Когда что-то в работе севера идет "не так", множество любопытных, запуская свои браузеры чтобы взглянуть на сервер, усугубляют проблему.
В "хорошем" коде из листинга 9 нагрузка на сервер минимизирована. Все видят одну и ту же картинку со статусом в формате jpg, и все любопытствующие создают нагрузку исключительно на Web-сервер. А Web-серверу даже не обязательно находиться на той же машине, где находится БД. Остаётся только периодически обновлять создаваемый JpGraph jpg-файл. Расписание для этого можно создать с помощью cron, в прилагаемом примере используется команда Linux watch.
Определение производительности сервера: нагрузочное тестирование при помощи Apache JMeter
Пора собрать все элементы в один скрипт. Для получения интересного графика и уверенности, что он показывает именно то, что надо, надо создать рабочую нагрузку на БД. С этой задачей неплохо справятся Apache JMeter, и само собой, IBM Rational Performance Tester. В нашем примере в качестве генератора нагрузки для получения графиков использовался пакет JMeter.
Создайте тестовую программу и проведите нагрузочное тестирование БД. Сделайте это даже если вы не собираетесь заниматься мониторингом скорости работы и созданием графиков. Даже если всё, чему вы научитесь в этой статье – это тестировать приложение под нагрузкой перед выпуском его в свет, я уже не зря её писал.
Тестирование сервера под нагрузкой до появления сбоев позволит вам оценить границы производительности системы. Обязательно стоит измерить количество пользователей и сложность запросов и транзакций. Вооружившись графиками потенциальных возможностей сервера и прогнозами роста нагрузок, вы выиграете битву за его обновление до наступления кризиса.
Скрипт из листинга 11 запускает все элементы монитора производительности вместе со средой для нагрузочного тестирования сервера. Категорически рекомендуется для запуска сложных групп приложений использовать скрипты-оболочки, это помогает избежать опечаток и прочих ошибок.
Возможно, многие будут шокированы тем, что в скрипте прокомментирован каждый шаг...
Листинг 11. Собираем всё вместе с автоматическим нагрузочным тестированием.
# (c)copyright 2006 Martin Lurie Sample code, not supported
echo must run as root... so we can restart the httpd and informix
# read foo just makes the script pause till you hit enter
# todo: automate a user id check instead of this prompt
read foo
# everyone tails the server log on the screen, right ?
xterm -exec tail -f /opt/informix/online.log &
. /opt/informix/iunset
# pick up the ids v10 env
. /opt/informix/ifx_env
# stop the server in case it is active
su informix -c "onmode -yuk"
# start the server
su informix -c oninit
# now pick up the csdk 2.8x environment - better yet - get
# the bug fixed version of the 2.9 csdk
. /opt/informix/iunset
. /home/informix/ifx_env
/etc/init.d/httpd restart
# must install php graph libraries
cd /var/www/html/
xterm -exec watch -d -n4 "php ./qcgraph.php > foo.jpg" &
mozilla http://karmiel/index.html&
cd /home/lurie/edrive/src/esql/oltpqc
xterm &
xterm -exec watch -d -n 5 ./oltpqc 1500 &
cd /home/lurie/tmp/jakarta-jmeter-2.2/bin/
./gojm &
|
На рисунке 5 изображен Jmeter, выполняющий JDBC-запросы. Среднее время ожидания ответа на этом графике – 573 миллисекунды. Некоторым такой скорости хватает. Однако если взглянуть на стандартное отклонение, составляющее 796 миллисекунд, то реакция пользователей может оказаться не слишком радостной. Хорошо то, что стандартное отклонение (красная линия), стремится вниз. Разброс времени ожидания уменьшается, и при нажатии клавиши Enter пользователей ждёт уменьшение разброса. При внимательном изучении линии среднего значения (черная пунктирная линия) и показателей рабочей нагрузки становится ясно, что сервер находится на стадии запуска соединения. Когда пул соединений с JMeter будет полностью установлен, ответы от сервера пойдут быстрее.
Рисунок 5. Генерация нагрузки JMeter, страница с графиком результатов
На рисунке 6 показаны периодически возникающие длинные задержки при подключении. Большая часть администраторов БД решают, что это некие долговременные контрольные точки, однако к немалому их удивлению все контрольные точки в файле online.log равны 0 секунд. В чём же проблема?
Рисунок 6. Периодически возникающая проблема долгого времени ожидания ответа
Как оказалось, эта проблема к БД не относится. Если система "подвисает" секунд на 8-10, а потом продолжает работать как ни в чём не бывало, проблема наверняка в DNS. Проблема долгого ожидания времени подключения исчезла после решения временных проблем с DNS (в данном случае было достаточно переподключить ноутбук к LAN, чтобы он смог получить доступ к серверу DNS).
Вы познакомились с несколькими технологиями организации мониторинга БД. Код в них портабельный благодаря использованию стандартного API (ODBC), а публикуеые в интернете графики создаются с помощью JpGraph. Измерение производительности вашей среды при помощи программы нагрузочного тестирования необходимо для того, чтобы управлять серверами – и не дать серверам управлять вами.
Всегда можно купить то, что не хочется делать самому. Если перспектива создания своими руками монитора реального времени пугает вас, обратите внимание на IBM Tivoli® Monitor. В нём есть много предопределённых агентов и консоль, позволяющая подробно анализировать конкретные случаи. На рисунке 7 показан пример Tivoli Monitoring.
Рисунок 7. Tivoli Monitoring для тех, кто предпочитает купить, а не делать все вручную
В исходный код примера можно внести немало усовершенствований. При сбоях сети или БД клиент oltpqc продолжает ждать ответ. Неплохо было бы ограничить время ожидания ответа и отправлять предупреждение в случае возникновения ошибки.
Для диагностики и решения проблем с сетью или сервером существует множество инструментов. Для определения здоровья системы на уровне ОС стоит начать с команд sar, vmstat и top. Обратите внимание на использование ресурсов процессора и работу с памятью – именно здесь обычно теряется скорость. Утилиты ping, netstat, nmap и ethereal позволяют провести диагностику работы сети.
Если в работе ОС проблем не замечено, то утилиты Informix onstat и DB2 snapshotпомогут вам собрать информацию о работе БД. Эти утилиты хорошо задокументированы, а в интернете есть немало примеров работы с ними – достаточно сделать запрос в google.
Я надеюсь, что статья оказалась полезной для вас и научила вас изолировать проблемы. Нет смысла обвинять БД, когда мониторинг БД позволяет в реальном времени видеть настоящие источники проблем.
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| Исходный код для мониторинга | oltpqc.zip | 10КБ | HTTP |
Другие файлы для загрузки
Научиться
- Оригинал статьи
"DB2/Informix and open source: Database defense against the dark political arts
" (EN).
-
Deming и статистический контроль процессов (wikipedia.org): узнайте больше об Эдвардсе Деминге (W. Edwards Deming) и его работе из области статистического контроля процессов.(EN)
-
Обновление выборки и частота Найквиста (wikipedia.org): узнайте больше о частоте Найквиста.(EN)
-
Принцип неопределённости Гейзенберга – почему ключи от моей машины могут оказаться в любой точке вселенной (wikipedia.org): прочтите о принципе неопределённости Гейзенберга.(EN)
-
"Доступ SQL к данным мониторинга DB2" (EN) (developerWorks, май 2003): узнайте как с помощью табличных функций SQL получать срезы данных мониторинга БД.
-
Использование БД Informix sysmaster для мониторинга статуса БД: узнайте о БД sysmaster.(EN)
-
"Подключение приложений PHP к IBM DB2 Universal Database" (EN) (developerWorks, июль 2001): комбинируя PHP с IBM DB2 Universal Database, создавайте Web-приложения.(EN)
-
JpGraph – превосходный PHP-пакет для создания графиков: узнайте о JpGraph.(EN)
-
Другие статьи, написанные этими авторами статьи на developerWorks.(EN)
- Раздел
developerWorks Information Management: узнайте больше о DB2. Здесь вы найдёте техническую документацию, руководства, файлы для загрузки, информацию о продуктах и многое другое.
-
Будьте в курсе последних событий с технических событий developerWorks и вебкастов.(EN)
Получить продукты и технологии
-
Загрузите
пробное ПО от IBM - здесь вы найдёте инструменты для разработчиков и промежуточное ПО от DB2, Informix, Lotus®, Rational®, Tivoli и WebSphere®.(EN)
-
Постройте свой следующий проект с помощью пробного ПО от IBM, которое можно загрузить прямо с сайта developerWorks.(EN)
Обсудить
- Примите участие в обсуждении материала на форуме.
-
Поучаствуйте в блогах developerWorks и вступите в сообщество developerWorks.(EN)
Марти Льюри (Marty Lurie) начал свою компьютерную карьеру, набивая тонны перфокарт в попытках написать Fortran на IBM 1130. Его каждодневная работа – это проектирование систем для IBM's Informix, но, если поднажать, то он, конечно, признается, что чаще всего он просто играет с компьютерами. Его любимая программа - это та, которую он написал, чтобы соединить свою беговую дорожку с лэптопом (из-за чего лэптоп потерял два фунта, а его уровень холестерина снизился на 20%). Марти получил сертификаты IBM DB2 DBA, IBM Business Intelligence Solutions Professional и Informix Professional.
Эйрон Льюри (Aron Lurie) учился в 9 классе, когда он написал эту статью. К тому времени у него уже было свое дело по Web-разработкам, а с 4 класса он занимался изучением новых языков программирования. Его основной клиент – это Hebrew College, где он занимает должность Web-мастера. Также недавно он стал Web-мастером школьной газеты, и, вдобавок, местного отделения USY. В свободное время - Эйрон член лыжной команды Newton South. К сожалению, он пока еще не нашел пути сочетания увлечений компьютером и лыжами.