20 декабря 2013

Tsung. Нагрузочное тестирование сервера MongooseIM.

Попробую привести очень краткую инструкцию по использованию инструмента tsung для тестирования

Ос клиенткой стороны, на которой запускаются тесты - Ubuntu 12.04. Сервер - неважно какой, лиш бы на нем был запущен и настроен MnongooseIM и к нему был правильно настроенный доступ.

Порядок действий:

Скачать дистрибутив tsung-1.5.0.tar.gz (последняя на данный момент версия) с сайта производителя: http://tsung.erlang-projects.org/dist/

Распаковать.
cd в папку с распакованным tsung
./configure
скорее всего будет ошибка о том, что  не установлен erlang:
configure: error: test Erlang program execution failed
sudo apt-get install erlang
вводим пароль суперпользователя.
соглашаемся на установку, нажав Y и ввод.
ждем.
./configure
теперь должно пройти без ошибок
make
ждем пока все скомпилируется
sudo make install
без sudo будет ошибка

после установки набираем в консоли tsung и видим, что приложение установлено:

По умолчанию путь к конфигурационному файлу и папка для логов: ~/.tsung/
Можем использовать его или задать пути через параметры -f и -l (см скриншот)
Если используем путь по умолчанию, то эту самую папку .tsung нужно создать.

Для запуска тестов все готово. Осталось только создать сценарий. Имя по умолчанию - tsung.xml

Сразу нужно сказать, что для графического представления результатов тестирования нужно установить дополнительные шаблоны perl:

sudo apt-get install gnuplot-nox libtemplate-perl libhtml-template-perl libhtml-template-expr-perl

Рассмотрим такой пример (это слегка отредактированный пример jabber.xml, который идет вместе с tsung в папке examples):

здесь:
строка 5 - клиент, с которого производятся запросы
строка 8 - сервер, на котором установлен MongooseIM, тип подключения - websocket. (На некоторых машинах tsung ругается и я ставил тип tcp - все работает так же ...)

и клиентов и серверов может быть несколько. В данном случае по одному. ip адрес для имени сервера должен быть прописан в /etc/hosts.

строка 11 - адрес того же сервера для мониторинга его нагрузки (память, нагрузка на CPU) и тип монитора. В данном случае это Erlang. Это значит, что на сервере должен быть установлен Erlang (и к серверу должен быть обеспечен доступ по ssh без паролей).

строка 15 - настройки "заселения" пользователей на сервер. Фаз заселения может быть несколько и они могут иметь разные скорость\поведение. В данном случае это значит, что в течении 20 секунд каждую секунду будет подключаться 1 пользователь.

строка 19 - число, которое будет подставляться в конец значений логина и пароля из строк 21 и 22. Имея такую комбинацию из строк 19, 21 и 22 мы получим 20 пользователей с логином от user001 до user0020 и соответствующими паролями. (Такие пользователи должны быть зарегистрированы на сервере. Можно руками через Spark, а можно попросить того, кто умеет делать это с помощью Erlang :))

строка 20 - адрес jabber сервера.
строка 23 - путь к вебсокету (относительно сервера). Часто путь к нему - это "/chat"

строка 26 - сессия. Probability - это вероятность или "вес" сессии. В данном случае сессия одна и это значение равно 100. Когда сессий несколько, то сумма их весов должна быть равна 100.

в строке 27 происходит подключение

строка 28 и все остальные thinktime - это время паузы (простоя) в секундах. Паузы иногда нужны, чтобы дать серверу время обработать запрос а иногда просто, чтобы подключенные пользователи "покурили". (поправьте меня кто-то. если я не прав ...)

строки 30 - 33 авторизация.  (По умолчанию в примере указан метод авторизации plain и я долго не мог подключиться, пока не поменял тип на  sasl plain, за что отдельное спасибо товарищу Piotr Nosek, который ответил на мой вопрос в stackoverflow)

строка 36 - запрос списка контактов

строка 40 - переход  в состояние online (до этого пользователь  в состоянии connected)

строка 45 - отправка сообщения случайному пользователю, который выбирается из списка тезх, чье состояние "online". Данное событие зациклено и повторяется 10 раз (строка 43). Длинна сообщения - 56 символов.

строка 50 - отправка сообщения, но уже случайному пользователю, который в состоянии offline.

строка 55 - отправка приглашения "в друзья" случайному online пользователю. В строке 58 происходит  отправка сообщения presence:subscribe, на которое приглашаемый должен ответить presence:subscribed

строка 62 - отключение от сервера.

Таким образом, каждую секунду к серверу подключается 1 пользователь, авторизируется, запрашивает список контактов, переходит в статус "online", 10 раз посылает случайному online пользователю сообщение из случайных 56 символов, 1 раз посылает случайному offline пользователю сообщение длинной 16 символов, приглашает случайного пользователя в друзья и отключается. Между всеми этими действиями пользователь "ждет" по паре секунд.

У всех запросов есть параметр - ack. Что это такое и как работает - отлично описано здесь. И вообще, документация в целом написана хорошо, но бывают частные случаи, в которых сложно разобраться, имея только документацию.

Итак, сценарий готов. Запускаем тест командой tsung start и ... и никакого чуда. В консоли просто появилось сообщение о пути в папке с логами.

Следить за процессом можно запустив в отдельном терминале команду

watch -n1 tsung status

По завершению теста увидим тут строку Tsung is not started.

Теперь можно посмотреть на результаты. Вот тут нам и пригодятся установленные ранее шаблоны. Переходим в папку с полученными логами:

cd /home/имя_пользователя/.tsung/log/папка_с_логами

и запускаем perl скрипт для генерации html отчета:

perl /usr/lib/tsung/bin/tsung_stats.pl

В результате в папке с логами появится файл и другие связанные с его существованием файлы. Открыв файл в браузере увидим несколько таблиц и графиков с результатами тестирования:



Для проведения простых тестов этого достаточно. Для разных вариантов сценариев, нагрузки и мониторинга нужно читать документацию.





28 октября 2013

Twitter REST API

Недавно мне понадобилось использовать "какой-нибудь рест апи" для написания тестового задания для ios. Все говорили, что это очень просто и любой джуниор разберется.

Для начала нужно иметь аккаунт в самом Twitter.
Затем нужно создать что-то типа учетки для приложения в Twitter (по ссылке https://dev.twitter.com/ - Ваша учетка - My applications - Create a new application).
Для приложения можно задать кое-какие даные и настройки, но это не важно и не все они обязательны. Мне достаточно было использовать только функцию поиска и поэтому хватало прав только для чтения.
Итак, после регистрации приложения у нас появляются всякие связанные с ним даные, но нам нужны только Consumer key и Consumer secret (по крайней мере в моем случае).

Что делать с этим далее подробно описано на страничке https://dev.twitter.com/docs/auth/application-only-auth

Если кратко, то чтоба апи нам ответило нужно предоставить ему наши специальным образом подготовленные ключ и секрет (key и secret) в POST запросе. Если этот запрос будет правильным, то  сервер вернет нам токен, коорый мы будем крепить к нашим последующим GET запросам для работы с апи.

Подготовка  ключа и секрета заключается в их склеивании со вставкой между ними двоеточия и перевод полученной строки в Base64 encode.

Шаг первый - подготовка данных для получения токена

Если у нас есть
Consumer key:         xvz1evFS4wEEPTGEFPHBog
Consumer secret:     L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
То соединяем их через двоеточие  и получаем
xvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Кодируем это дело в  Base64 (например онлайн кодером\декодером http://www.base64decode.org/) и получаем
eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==

Нужно сказать, что для экспериментов я пользовался замечательной бесплатной утилитой (а вернее приложением для google chrome) - Rest Console

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

Шаг второй - получение токена

Открываем Rest Console и заполняем следующие поля такими данными:
Request URI:
https://api.twitter.com/oauth2/token 
Content-Type:
application/x-www-form-urlencoded;charset=UTF-8
Encoding:
Accept-Encoding: gzip
RAW Body:
grant_type=client_credentials
Authorization Header:
Basic иТутВставляемПолученныйВПрошломШагеПерекодированныйКлючИСекрет
получится что-то вроде
Basic pQVS5hVJpoVaROVcN...YJeFZVURSNZBYoNBW2s=
Нажимаем POST и видим в Responce
  1. {
  2. "token_type": "bearer",
  3. "access_token": "ANTAA9tBBcBIT3i2Bo0Qu...Q3Rqn8OWRMp^Zs7JvnpS7G8x"
  4. }
Ура! Мы получили наш токен!

P.S. позже выяснилось, что все это можно упростить - задать
Request URI как https://api.twitter.com/oauth2/token?grant_type=client_credentials и дополнительно заполнить только Authorization.

Шаг третий - поиск

Теперь, когда токен получен можем отправлять GET запрос уже непосредственно для поиска по твитам.
Описание возможных параметров есть тут: https://dev.twitter.com/docs/api/1.1/get/search/tweets
Мы будем использовать самый простой - просто укажем ключевое слово.

Заполняем поля (не забываем снять чекбоксы с уже ненужных полей)
Request URI:
https://api.twitter.com/1.1/search/tweets.json?q=restkit
restkit здесь - это искомое слово. Можно вставить какое Вам угодно.
Encoding:
Accept-Encoding: gzip
Authorization Header:
Bearer иТутВставляемПолученныйВПрошломЗапросеТокен
получится что-то вроде
Bearer AAAAAAAAAA...QShJoaOc..JF%VRNB%oB%2s

Жмем GET и видим в Responce body наш долгожданный JSON с результатами поиска!

  1. {
  2. "statuses": [{
  3. "metadata": {
  4. "result_type": "recent",
  5. "iso_language_code": "en"
  6. },
  7. ...
Что делать с этим дальше - надеюсь найду время описать :)
 

28 мая 2013

Настройка Ubuntu 13.04

Только я привык ко всем чудесам убунту 12.04, как вышла новая версия - 13.04
Опять нужно все заново настроить, прикрутить, отключить. Я не самый опытный пользователь убунту (начал пользоваться недавно, благодаря одному из рабочих проектов), и мне эта процедура не кажется простой и понятной. Дальше список того, что я делал на ноутбуке (ACER aspire 4745g), чтобы все работало так, как мне нужно.

Экономия энергии при работе от батареи.

Eсть замечательная статья на хабре. Из нее я пробовал кое-что, но как по мне - нормально работает только отключение дискретной видеокарты.
В биосе включаем режим видео switchable
смотрим названия и коды устройств:
lspci | grep VGA
смотрим в каком состоянии какое устройство:
cat /sys/kernel/debug/vgaswitcheroo/switch
напротив активного устройства стоит +, напротив устройства, потребляющего питание стоит Pwr
отключаем неиспользуемые устройства:
echo OFF > /sys/kernel/debug/vgaswitcheroo/switch
добавляем эту строку в файл etc/rc.local

Настройка системы и установка всяких полезных утилит.

Есть очень хорошая статья, из которой я много чего почерпнул:

Удаление ненужных приложений (убунту ван и амазон),
sudo apt-get remove unity-lens-shopping

Установка твикеров и надстроек:

sudo add-apt-repository ppa:tualatrix/next 
sudo apt-get update 
sudo apt-get install ubuntu-tweak

sudo apt-get install dconf-tools

cd/tmp
wget https://launchpad.net/~diesch/+archive/testing/+files/unsettings_0.08ubuntu1_all.deb
sudo dpkg -i unsettings*

Отключение ненужных служб в "Автоматически запускаемых приложениях".
Сначала нужно включить отображение этих самых приложений:
sudo -i
cd /etc/xdg/autostart/
sudo sed --in-place 's/NoDisplay=true/NoDisplay=false/g' *.desktop

Использование файла подкачки только при 90% заполненности памяти:
прописываем vm.swappiness=10  в /etc/sysctl.conf

Классическое меню  (как Пуск):
sudo apt-get install classicmenu-indicator

Кнопки управления окном СПРАВА:
gsettings set org.gnome.desktop.wm.preferences button-layout "menu:minimize,maximize,close"

НОРМАЛЬНАЯ полоса прокрутки в окнах:
gsettings set com.canonical.desktop.interface scrollbar-mode normal

Иконки приложений в системном трее.

Не знаю почему, но отображение иконки приложения в трее убунту - это дело неочевидное. Нужно что-то настраивать и прописывать. До версии 13.04 существовал "белый список" приложений, которым можно сверкать иконкой в трее. Но в 13.04 этот список убрали. Почитав несколько десятков жалоб на это изменение я нашел пост, в котором написано как вернуть этот самый белый список:
sudo add-apt-repository ppa:timekiller/unity-systrayfix 
sudo apt-get update 
sudo apt-get upgrade
перезапускаем unity и выполняем (или используем dconf-editor):
gsettings set com.canonical.Unity.Panel systray-whitelist "['all']"
Это самый простой вариант - разрешить всем приложениям показывать иконку в трее. Мне он подходит.

Запуск .sh скриптов

Почему-то sh файлы открываются по умолчанию в текстовом редакторе, хотя в 12-й версии был выбор запускать их или открывать как текст. Чтобы вернуть этот выбор нужно сделать следующее:
Nautilus > File menu > Preferences > Behavior, выбрать для опции "Executable Text Files" значение "Run executable..." или "Ask each time".

11 апреля 2013

Полезные онлайн сервисы

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

09 апреля 2013

CSS3 стили в iFrame в IE8

Как оказалось, CSS3 стили не работают в Internet Explorer 8, если они прописаны на странице, которая открывается в iFrame. Вернее они-то работают, но нужно прописать определенные параметры в <meta> тег страницы-родителя.

26 марта 2013

Локализация datepicker в зависимости от атрибута lang

Недавно я описал как прикрутить datepicker к элементу input. Сама по себе задача не сложная. Интереснее оказалось решить вот что - как менять локализацию календарика в зависимости от языка страницы.

25 марта 2013

"Календарик" (Date Picker) на html форме

Можно вводить дату в форму вручную, а можно, написав несколько строчек, сделать так, чтобы при нажатии на поле ввода появлялся календарик, из которого можно удобно выбрать дату. Для этого используется виджет Datepicker из библиотеки jQuery

24 марта 2013

Валидация html формы - jQuery validationEngine

Задача стояла следующая - проводить элементарную валидацию html формы: не пустые поля, формат поля почты, полей с только цифрами и полей только с буквами. Делается это на клиентской стороне, силами jQuery.

23 марта 2013

Нашел редактор для работы с jQuery

Собственно-то ничего я и не искал - просто сидел себе на рабочем месте и медленно, но уверенно причесывал набросанный в Notepad++ мини-скрипт, написанный на jQuery. И тут коллега программист спросил меня почему я не использую "что-нибудь с автокомплитером, например аптана"?