28 июля 2009 г.

Прием платежей для Спокойно.Ру с помощью ОСМП

Как это было, теперь страшно вспоминать.

Первое обращение в ОСМП датировано 20 февраля 2009. Сейчас, замечу, практически август.

Поле subject в почтовой переписке выглядит сейчас примерно так:
Ha: Re: Ha: Re: Ha: Re: Ha: Re: Ha: Re: Ha: Re: >>: Fwd: Ha: Re: Ha: Re: Ha: Re: Тестирование в системе ОСМП.

Сначала было тестирование платежных шлюзов — на это ушло буквально пару дней.

Затем — несколько месяцев бумажной волокиты.

Еще 3 недели обновления автоматов.

Затем снова бумажная волокита — нашлась ошибка в документах.

Долгое ожидание подписи генерального директора.

Первая приятная новость с начала работы — анонс на сайте ОСМП.

Очередное обновление автоматов.

Запуск. Первый платеж. Комом. В суппорт. И вот оно — долгожданное счастье. Дорогие автоинструкторы наконец могут оплатить свое размещение на spokoino.ru

Но, тем не менее, это одна из лучших и крупнейших платежных систем. И без нее было бы всё по-другому.

Новый сайт студии

Наконец, это свершилось.

Мы были в шоке, но сделать нормальный сайт собственной студии, где мы сами себе хозяева, гораздо труднее, чем коммерческий заказ средней сложности. Тем не менее, несколько дней приятной работы, умопомрачительные фотосессии (смотреть раздел «Команда») — и получился хороший сайт, который вполне отражает нашу сущность. Всепоглощающий подход в работе над каждым проектом напрямую отражен в нашем портфолио, где каждый проект подан в индивидуальном стиле.

Что-либо еще комментировать особого смысла нет — пройдите на http://futurecolors.ru и оцените.

23 июля 2009 г.

Спокойно в Питере

Слоны на Невском Рады поделиться хорошей новостью: наш проект Спокойно.ру обзавёлся петербургским филиалом.

Как и раньше, наша цель — сделать выбор инструктора по вождению простым и удобным, поэтому мы хотим привлечь на сайт максимальное количество автоинструкторов, чтобы будущим ученикам не пришлось обходить в поисках наставника десятки разрозненных сайтов. Автоинструкторы северной столицы, приглашаем вас зарегистрироваться, чтобы разместить свои объявления, в отличие от московской версии, это бесплатно.

Все посетители из Санкт-Петербурга, заходящие по адресу spokoino.ru, будут переадресованы на версию для СПб. Либо можно переключить версии сайта с помощью ссылок под логотипом на любой из страниц.

21 июля 2009 г.

Организация среды веб-разработки

Продуктивность коллектива веб-студии напрямую зависит от удобства среды разработки. У нас сложилась стройная система организации работы с проектами, включающая в себя набор таких неотъемлемых компонентов, как IDE, SCM, PM-система, багтрекер и development-сервер. Этим постом я бы хотел начать цикл статей, посвященных настройке и использованию этих компонентов в нашей студии.

В первой части я расскажу о самом основном — среде разработки (о том, как мы организовали совместный доступ к проектам).

Идеи



  1. Среда разработки должна быть единой для всех сайтов.

  2. Девелоперы не должны тратить время на настройку каждый своей серверной части.

  3. Работает ли над проектом  один человек или несколько — контроль версий необходим.

  4. Если рабочий каталог (IDE workspace) находится на сервере, то можно поработать и дома, не тратя время на повторную настройку окружения на домашнем десктопе или ноуте.


Google следит за тобой и за мной

С момента запуска Google Latitude мы очень ждали появления публичного API, но он все никак не появлялся.

Поэтому на коленках было сооружено нечто, что позволило нам получить вот такую интересную картинку моей поездки в Питер на праздники 9 мая. Все, что я взял с собой — был телефон Nokia N95 с выключенным GPS, но запущенной Google Maps с поддержкой Latitude.

latitude

Особенно интересна была поездка на пароме в Кронштадт, но об этом — как-нибудь в другой раз.

Стоит заметить, что сейчас дела обстоят намного проще, благодаря тому, что Google теперь позволяет опубликовывать свой гео-статус и получать его примерно по такому url: http://www.google.com/latitude/apps/badge/api?user=user_id&type=json

Подробнее про Google Latitude.

Приглашаем всех желающих инвестировать дальнейшую разработку.

14 июля 2009 г.

Выравнивание колонок с помощью CSS

Задача


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

forms_1

13 июля 2009 г.

Организация распределенного дискового хранилища с возможностью неограниченного расширения с применением технологий LVM и ATAoE

Задача

Когда диски были маленькие, а Интернет большой, владельцы частных FTP-серверов сталкивались со следующей проблемой:
На каждом жестком диске создавалась папочка Video или Soft, и получалось так, что добавив новый жесткий диск, приходилось делать на нем папочки Video2, Soft2, etc.
Задача поменять жесткий диск на диск большего объема приводила к тому, что данные нужно было куда-то переносить, все это происходило нетривиально и с большими downtime'ами.
Разработанная нами система в 2005 году позволила собрать надежный и быстрый массив в 3 терабайта, масштабируемый, расширяемый, в режиме онлайн, добавляя диски или целые сервера с дисками.
Цена всего решения составляла 110% от стоимости самих дисков, т.е. по сути, бесплатной, с небольшим overhead.

Вот примерная схема устройства нашего хранилища:


Реализация

Идея такова: есть supervisor и есть ноды. Supervisor — это паблик сервер, на который заходят клиенты, у него есть несколько гигабитных bonding интерфейсов наружу, и несколько — внутрь, к нашим нодам. Супервайзор берет экспортированные с помощью vblade по ATAoE массивы или отдельные диски, делает поверх них LVM и делает доступным этот раздел по FTP. Также супервайзор является сервером бездисковой загрузки для нод, и на нем же находится вся файловая система нод, с которой после загрузки они общаются по NFS. Ноды — это чисто диски, загрузка по PXE, далее запускается наш etherpopulate и все диски экспортируются.

1. Настройка для удаленной загрузки нод


устройство ноды
ftp node # ls /diskless/
bzImage  node  pxelinux.0  pxelinux.cfg


ядро, директория node - rootfs, конфиги для pxe
ftp node # ls /diskless/node/
bin  boot  dev    etc  lib  mnt  proc  root  sbin  sys  tmp  usr    var
ftp node # chroot /diskless/node/
ftp / # which vblade
/usr/sbin/vblade
ftp node # chroot /diskless/node/
ftp / # which vblade
/usr/sbin/vblade
ftp / # vblade
usage: vblade [ -m mac[,mac...] ] shelf slot netif filename
ftp / #


все это будет доступно на нодах
ftp node # cat /diskless/pxelinux.cfg/default
DEFAULT /bzImage
APPEND ip=dhcp root=/dev/nfs nfsroot=172.18.0.193:/diskless/node idebus=66


конфиг dhcpd, не забываем запустить
ftp etc # more dhcp/dhcpd.conf
option domain-name "domain.com";
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
option space PXE;
option PXE.mtftp-ip               code 1 = ip-address;
option PXE.mtftp-cport            code 2 = unsigned integer 16;
option PXE.mtftp-sport            code 3 = unsigned integer 16;
option PXE.mtftp-tmout            code 4 = unsigned integer 8;
option PXE.mtftp-delay            code 5 = unsigned integer 8;
option PXE.discovery-control      code 6 = unsigned integer 8;
option PXE.discovery-mcast-addr   code 7 = ip-address;

subnet 172.16.0.0 netmask 255.255.0.0 {
}

subnet 172.18.0.192 netmask 255.255.255.192 {
    class "pxeclients" {
        match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
        option vendor-class-identifier "PXEClient";
        vendor-option-space PXE;
        option PXE.mtftp-ip 0.0.0.0;
        filename "pxelinux.0";
        next-server 172.18.0.193;
    }

    host node-1 {
        hardware ethernet 00:13:d4:68:b2:7b;
        fixed-address 172.18.0.194;
    }
    
    host node-2 {
        hardware ethernet 00:11:2f:45:e9:fd;
        fixed-address 172.18.0.195;
    }
    
    host node-3 {
        hardware ethernet 00:07:E9:2A:A9:AC;
        fixed-address 172.18.0.196;
    }
}


конфиг tftpd
ftp etc # more /etc/conf.d/in.tftpd
# /etc/init.d/in.tftpd

# Path to server files from
INTFTPD_PATH="/diskless"
INTFTPD_USER="nobody"

# For more options, see tftpd(8)
INTFTPD_OPTS="-u ${INTFTPD_USER} -l -vvvvvv -p -c -s ${INTFTPD_PATH}"


запущен tftpd?

ftp etc # ps -ax  |grep tft
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
5694 ?        Ss     0:00 /usr/sbin/in.tftpd -l -u nobody -l -vvvvvv -p -c -s /diskless
31418 pts/0    R+     0:00 grep tft


конфиг для nfs, не забываем запустить.
ftp etc # more exports
/diskless/node 172.18.0.192/255.255.255.192(rw,sync,no_root_squash)


Настройка для удаленной загрузки закончена, все ноды прописаны.

2. Программная часть для автоматизации сборки массивов


софтина, которая запускается на нодах, делает raid-массивы md* и экспортирует их по ataoe на supervisor.
ftp# chroot /diskless/node
ftp etc # cat /usr/sbin/etherpopulate


#!/usr/bin/perl

my $action = shift();

#system('insmod /lib/modules/vb-2.6.16-rc1.ko')
# if ( -f '/lib/modules/vb-2.6.16-rc1.ko');

# Get information on node_id's of ifaces
my @ifconfig = `ifconfig`;
my $int;
my %iface;
foreach my $line (@ifconfig) {
 if ($line =~ /^(\S+)/) {
  $int = $1;
 }
 if ($line =~ /inet addr:(\d+\.\d+\.\d+\.)(\d+)/ && $1 ne '127.0.0.' && $int) {
  $iface{$int} = $2;
  $int = "";
 }
}

my $vblade_kernel = ( -d "/sys/vblade" )?1:0;
if ( $vblade_kernel ) {
 print " Using kernelspace vblade\n" if ($action eq "start");
} else {
  print " Using userspace vblade\n" if ($action eq "start");
}

# Run vblade
foreach my $int (keys %iface) {
 my $node_id = $iface{$int};
 open(DATA, "/etc/etherpopulate.conf");
 while () {
  chomp;
  s/#.*//;
  s/^\s+//;
  s/\s+$//;
  next unless length;

  if ($_ =~ /^node-$node_id\s+(\S+)\s+(\S+)\s+(\S.*)/) {
   my $cfg_action = $1;
   my $command = $2;
   my $parameters = $3;
   
   # Export disk over ATAoE
   if ($action eq $cfg_action && $command eq "ataoe" && $parameters =~ /(\S+)\s+(\d+)/) {
    my $disk_name = $1;
    my $disk_id = $2;
    if ($vblade_kernel) {
     if ( $disk_name =~ /([a-z0-9]+)$/ ) {
      my $disk_safe_name = $1;
      system("echo 'add $disk_safe_name $disk_name' > /sys/vblade/drives");
      system("echo 'add $int $node_id $disk_id' > /sys/vblade/$disk_safe_name/ports");
     }
    } else {
     system("/sbin/start-stop-daemon --background --start --name 'vblade_$node_id_$disk_id' --exec /usr/sbin/vblade $node_id $disk_id eth0 $disk_name");
    }
    print " Exporting disk: $disk_name [ $node_id $disk_id ] via $int\n";
   }
   
   # Execute specified command
   if ($action eq $cfg_action && $command eq "exec") {
    system($parameters);
   }
  }
 }
 close(DATA);
}


конфиг для etherpopulate при участии трех нод. * еще два доп. диска с каждой ноды экспортируются для других целей (backup на raid1)

ftp sbin # more /diskless/node/etc/etherpopulate.conf
# ----------------------
# Node 194 160gb
node-194    start    exec    /sbin/mdadm -A /dev/md0 -f /dev/hd[a-h] /dev/hdl
node-194    start    ataoe    /dev/md0    0    # Vblade FTP array
node-194    start    ataoe    /dev/hdk    1    # Vblade BACKUP disk
node-194    stop    exec    /usr/bin/killall vblade
node-194    stop    exec    /sbin/mdadm -S /dev/md0
# ----------------------
# Node 195 200 gb
node-195    start    exec    /sbin/mdadm -A /dev/md0 /dev/hd[a-b] /dev/hd[e-f] /dev/hd[g-h] /dev/sd[a-c]
node-195    start    ataoe    /dev/md0    0    # Vblade FTP array
node-195    start    ataoe    /dev/sdd    1    # Vblade BACKUP disk
node-195    stop    exec    /usr/bin/killall vblade
node-195    stop    exec    /sbin/mdadm -S /dev/md0
# ----------------------
# Node 196 200 gb
node-196    start    exec    /sbin/mdadm -A /dev/md0 /dev/hd[a-f]
node-196    start    ataoe    /dev/md0    0    # Vblade FTP array
node-196    stop    exec    /usr/bin/killall vblade
node-196    stop    exec    /sbin/mdadm -S /dev/md0

3. Заключительные работы


заставляем винты на нодах работать на максимальной скорости в ущерб надежности
hd*_args="-d1 -X69 -udma5 -c1 -W1 -A1 -m16 -a16 -u1"


Убедимся в ядре для supervisor'а. На самих нодах экспорт в ATAoE происходит в userland, с помощью vblade.
ftp good # grep -i OVER_ETH .config
CONFIG_ATA_OVER_ETH=y


на самих нодах сразу после загрузки и запуска etherpopulate в соответствии с конфигом
node-195 ~ # cat /proc/mdstat
Personalities : [linear] [raid0] [raid1] [raid5] [raid4] [raid6] [multipath] [faulty]
md0 : active raid5 hda[0] sdc[8] sdb[7] sda[6] hdh[5] hdg[4] hdf[3] hde[2] hdb[1]
1562887168 blocks level 5, 64k chunk, algorithm 2 [9/9] [UUUUUUUUU]

unused devices:
node-195 ~ # ps -ax | grep vblade | grep md
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
2182 ?        Ss   2090:41 /usr/sbin/vblade 195 0 eth0 /dev/md0

node-195 ~ # mount
rootfs on / type rootfs (rw)
/dev/root on / type nfs (ro,v2,rsize=4096,wsize=4096,hard,nolock,proto=udp,addr=172.18.0.193)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
udev on /dev type tmpfs (rw,nosuid)
devpts on /dev/pts type devpts (rw)
none on /var/lib/init.d type tmpfs (rw)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec)


собираем lvm из дисков на supervisor'е, в дальнейшем это делать не нужно, просто по vgscan будет находиться готовый к монтированию раздел
ftp / # ls -la /dev/etherd/*
c-w--w----  1 root disk 152,     3 Jun  7  2008 /dev/etherd/discover
brw-rw----  1 root disk 152, 49920 Jun  7  2008 /dev/etherd/e194.0
brw-rw----  1 root disk 152, 49936 Jun  7  2008 /dev/etherd/e194.1
brw-rw----  1 root disk 152, 49920 Jun  7  2008 /dev/etherd/e195.0
brw-rw----  1 root disk 152, 49936 Jun  7  2008 /dev/etherd/e195.1
brw-rw----  1 root disk 152, 49920 Jun  7  2008 /dev/etherd/e196.0
cr--r-----  1 root disk 152,     2 Jun  7  2008 /dev/etherd/err
c-w--w----  1 root disk 152,     4 Jun  7  2008 /dev/etherd/interfaces


С первых двух нод экспортировалось по 1 массиву и по 1 диску, с третьей ноды — только массив.
Перед тем, как эти устройства можно использовать на супервайзоре для LVM, нужно сделать «специальную« разметку, чтобы LVM добавил некоторые внутренние идентификаторы на диск.

# pvcreate /dev/etherd/e194.0
...
...


Диски готовы к использованию. Создаем Volume Group.
# vgcreate cluster /dev/etherd/e194.0 /dev/etherd/e195.0 /dev/etherd/e196.0


Хоть группа становится сразу активной, в принципе ее можно включать
# vgchange -a y cluster


и выключать
# vgchange -a n cluster


Чтобы что-то добавить в volume group используйте
# vgextend cluster /dev/*...


Создаем Logical Volume hyperspace на все доступное место. Каждый PE по дефолту равен 4mb. Так
# vgdisplay cluster | grep "Total PE"
Total PE              1023445
# lvcreate -l 1023445 cluster -n hyperspace


Посмотреть, что получилось можно vgdisplay, lvdisplay, pvdisplay.
Расширять все можно с помощью vgextend, lvextend, resize_reiserfs.
Подробнее здесь http://tldp.org/HOWTO/LVM-HOWTO/

Имеем в итоге /dev/cluster/hyperspace и делаем ему mkreiserfs и mount. Все готово. Настройку фтп-сервера опустим. Та-да!


Повторное использование


На самом супервайзоре в случае его перезагрузки достаточно выполнять
more runme.sh
#!/bin/sh
vgscan
vgchange -a y
mount /dev/cluster/hyperspace /mnt/ftp

чтобы использовать заранее созданный массив.

Недостатки



  • конкретно в нашем случае ошибка была с выбором самих жестких дисков. Почему-то выбор пал на Maxtor и почти вся партия в 30 дисков за год пошла бэдами;

  • не использовалась горячая замена, т.к. это был все еще IDE. В случае с hotplug SATA нужно было бы на уровне mdadm на самих нодах настроить уведомление о выходе дисков из строя;

  • proftpd нужно запускать только после того, как в файловую систему супервайзора примонтируется lvm из ataoe устройств. если proftpd запускался раньше, то он не понимал, что произошло вообще;

  • долго экспериментировали с ядерным и userspace'ным vblade на нодах, но тогда это была заря развития ataoe и все работало, как повезет. но работало;

  • в качестве файловой системы можно использовать или reiserfs или xfs - только они поддерживали на тот момент онлайн-ресайз если диск под ними увеличился;

  • тогда только-только стали появляться патчи, которые позволяли расширять в онлайне raid-5 массив md

  • существовало ограничение на ataoe по 64 слота на "полку". Полок можно было сделать штук 10, т.е. , в принципе, какие-то ограничения были, типа 640 НОД :)

  • есть много нюансов с производительностью, но все они решаемы в той или иной степени. в кратце - не бойтесь, когда поначалу скорость будет не очень, нет предела совершенству;

Выводы


Решение, безусловно интересное, и хочется сделать его уже на терабайтных винтах, hotplug sata и с новыми свежими версиями софта. Но кто пойдет на такой подвиг, неизвестно. Может быть, ты, %username%?

Ссылки по теме


http://tldp.org/HOWTO/LVM-HOWTO/
http://sourceforge.net/search/?words=ataoe&type_of_search=soft&pmode=0&words=vblade&Search=Search
http://www.gentoo.org/doc/en/diskless-howto.xml

10 июля 2009 г.

Катайте баллоны от Граффити Маркета


Когда примерно год назад к нам обратился наш знакомый, торгующий в оффлайне краской для граффити, у него уже был запущен некий интернет-магазин, дела в котором шли из рук вон плохо:
  • из-за отсутствия интеграции со складской программой товары приходилось заводить вручную, каталог товаров за счет этого был местами с пробелами, а информация по наличию товара быстро устаревала;
  • те товары, которые были изначально чьими-то силами импортированы с помощью скриптов, были перенесены в ужасном качестве, со специальными символами и заглавными буквами;
  • корзина и процесс оформления покупки были организованы неудобно, а также не существовало никакого интерфейса, через который можно было бы работать с готовыми заказами;
  • и, самое главное, движок был дыряв настолько, что уже при первой встрече с заказчиком нам за 5 минут удалось продемонстрировать ему все логины и пароли всех зарегистрированных покупателей, включая его самого :)

В итоге мы конечно получили этот заказ. О том, как магазин разрабатывался, и чем на тот момент мы были рады похвастаться, можно прочитать в нашем портфолио. В процессе разработки, был забавный момент, когда все товары экспортировались на Яндекс.Маркет, а в тот момент там отдельной категории под краску не существовало, и товары распределялись по категориям исходя из названий, подробнее есть пост на Хабрахабрe.

Итак, прошел год, и отчасти благодаря нашему проекту, магазин существенно разросся, появилось еще два магазина — один в центре Питера, второй — у нас, в Москве, на Таганке. Количество и размер заказов увеличился примерно в 20 раз, интернет-магазин стал активно работать по регионам России, осуществляя доставку в самые отдаленные уголки нашей родины, давая возможность всем и каждому приобщиться к миру граффити. А посещаемость сайта сейчас измеряется тысячей уникальных хостов в день, хотя когда мы только начинали, она была в районе 50 человек. Также приятно, что по запросу «граффити» в Яндексе магазин занимает второе место, сразу после Википедии :)

Для связи всех этих магазинов в единую локальную сеть, чтобы иметь общую бухгалтерию и складскую-кассовую систему, заказчик тоже обратился к нам и мы организовали изящное и недорогое решение с шифрованными IPSEC-туннелями на базе нескольких D-Link DIR-130, их оказалось вполне достаточно. А главный босс по отдельному VPN-каналу имеет возможность даже из дома наблюдать за продажами, как в онлайне, так и в оффлайне.

Теперь, если у нашей студии появляется потребность что-нибудь перекрасить (об этом — в будущих постах), нам никогда не откажут в паре баллонов отличной краски.

Про нас пишут


Мы решили собрать ссылки на статьи, где писали про наш проект «Спокойно.ру».

В середине июня, спустя 5 месяцев после запуска самой первой версии сайта, мы сделали анонс нашего проекта на Хабрахабре. Многим хабравчанам наш ресурс понравился, мы получили массу положительных отзывов и интересных предложений по дальнейшему развитию, большинство из которых мы постараемся воплотить в жизнь. Хотя публиковаться решили в блоге «Я пиарюсь», не забыли осветить и техническую сторону разработки. Про самые интересные моменты мы обязательно ещё расскажем подробней в последующих постах в этом блоге.

На следующий день мы дали интервью обозревателю Елене Шотган и вскоре стали стали сайтом дня на Рамблере. Из статьи можно узнать, чем «Спокойно.ру» кардинально отличается от конкурентов и в чём его сильные стороны как для инструкторов, так и для будущих водителей.

Благодаря этим двум статьям за несколько дней сайт посетило около 10 тысяч человек и про нас написали заметки на сайтах, освещающих новые интернет-проекты, таких как: Andrey2, Catalogr, Startupster, .RUformator. Спасибо им и всем, кто оставлял комментарии и пожелания.

Мы решили не останавливаться на этом и написали про себя на Автокадабре (это такая социальная сеть владельцев транспортных средств). На волне интереса к теме выбора автоинструктора и обучения вождению попали в обзор крупного автомобильного ресурса Avto.ru.

По мере появления обзоров наших проектов в интернете мы будем добавлять ссылки на них в этот пост.

UPD. Появилась заметка про наш сайт в Лавке Интересностей и Полезностей.
http://avto.ru/review/post_15961.html

8 июля 2009 г.

Рупор будущего

Итак, мы в эфире.

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

Мы постараемся писать интересно и как можно чаще. Само собой будем рады комментариям и критике со стороны читателей.

Так что подписываемся на РСС и не забываем про Твитер.