Zend Cloud + WebDav + Яндекс.Диск

В нашем проекте встала задача выделения отдельного сервера под хранение и отдачу статических данных (картинок, музыки и видео). В этом посте я расскажу о том, как я писал свой адаптер хранения на Zend SimpleCloud API. Основаня фишка в том, что он стандартизирован и при желании его можно будет поменять на Amazon S3 не переписывая код. Также данный клиент поддерживает работу с новым сервисом от Яндекса – Яндекс.Диск.

Задача

Итак, проблема состояла в том, что наше веб-сервер занимался всем что угодно. И генерировал странички пользователям, и отдавал статику (включая видео, музыку и картинки), и ресайзил изображения. Было принято решения сделать наконец из веб-сервера веб-сервер, а именно вынести все эти операции на job-сервер, а сам статичный контент на сервер статики.

Архитектура

Сервера статики располагются отдельно, клиенты коннектятся к ним по HTTP протоколу и забирают картинки как обычно. Заливку картинок осуществляет либо само веб-приложение по протоколу WebDav либо демон, который выполняет задачи из очереди. В качестве протокола общения с серверами статики будем использовать WebDav, в качестве сервера очередей – Gearman.

Конфигурируем nginx

Nginx из deb-пакетов (который есть в репозитариях) нам не подойдёт, т.к. надо установить его вместе с модулем http_dav_module. Скачиваем, компилируем и устанавливаем сервер с требуемым модулем:

Обращаем внимание на строчки:
adding module in ./dav-ext
+ ngx_http_dav_ext_module was configured

Дальше по идее надо бы использовать make install, но мы не будем этого делать, чтобы не замусоривать систему. Надо убедиться, что у нас удалён старый nginx И поставить утилиту checkinstall, которая сделает нам deb-пакет и поставит его.

Дальше надо сконфигурировать nginx, я просто приведу свой конфиг.

Отлично, теперь можем побаловаться с ним. Единственный момент, nginx не поддерживает запрос OPTIONS+PROPFIND, поэтому подключить обычный WebDav клиент к нему не получитсяб но если вы скомпили его с nginx-dav-ext-module, то можете подконнектиться к нему любым клиентом. Например я проверял в Ubuntu с помощью Nautilus.

Чтобы работать с ним из PHP я разработал специальный адаптер ZendExtra_Cloud_SimpleStorage_Adapter_WebDav. Самое интересное, что его можно подключить к Zend_Cloud и потом при необходимости перейти на другое хранилище (например Amazon S3 без переписывания кода). Стандарты рулят! 🙂

Итак вот список реализованных команд WebDav: PUT DELETE MKCOL COPY MOVE

А вот списко реализованный функций со стороны Zend: fetchItem(), storeItem(), deleteItem(), copyItem(), moveItem(), renameItem(), listItems() + дополнение в виде createFolder()

ZendExtra_Cloud_SimpleStorage_Adapter_WebDav.php

А вот пример работы с ним:

Example.php

Фишки

  • Листинг директорий сделан двумя видами. Если вы скомпилили nginx с модулем nginx-dav-ext-module и он поддерживает методы PROPFIND и OPTIONS то юзайте обычный синтаксис. Это подходит и для сторонних служб, типа Яндекс-Диска. Если же модуля нет, то в массиве options передавайте параметр “mode” => ‘get’ и адаптер будет парсить ответ от nginx, полученный по get запросу. Отсюда зависимость от Zend_Dom
  • По-умолчанию такие операции, как копирование, перемещение и переименование осуществляются прямо на сервере (без загрузки файлов клиенту). Это быстро и удобно. Однако может возникнуть ситуация, когда команды MOVE и COPY выключены в nginx. Тогда используйте параметр native => true, В массиве options функций moveItem(), renameItem(), copyItem().
  • Пока не уверен где писать логику выбора сервера в случае наличия кластера из статических серверов. На данный момент она будет в адаптере но я раздумываю о том, чтобы вынести её. В этом случае адаптер будет работать с одним сервером, а не с многими, как сейчас.

Исходники

Исходникик доступны на GitHub:

https://github.com/netandreus/exlibris/tree/master/application/lib/ZendExtra/Cloud/StorageService/Adapter

Яндекс-Диск клиент для Zend Framework

В клиенте реализована поддержка Яндекс-Диска (да в принципе и любого другого сервиса с авторизацией). Вот небольшой примерчик работы с ним.

yandexDiskExample.php

<?php

// Init storage / ** @var ZendExtra_Cloud_StorageService_Adapter_WebDav $storage ** / $storage = Zend_Cloud_StorageService_Factory::getAdapter(array( Zend_Cloud_StorageService_Factory::STORAGE_ADAPTER_KEY => ‘ZendExtra_Cloud_StorageService_Adapter_WebDav’, ZendExtra_Cloud_StorageService_Adapter_WebDav::SERVERS_KEY   => array( ‘static1.site.ru’ => array(‘host’ => ‘webdav.yandex.ru’, ‘protocol’ => ‘https’, ‘port’ => ’80’) ), ZendExtra_Cloud_StorageService_Adapter_WebDav::DEFAULT_SERVER_KEY => ‘static1.site.ru’ ));

// Отображает список файлов в каталоге
$files = $storage->listItems(‘/testfolder/’);

 

Ссылки

WebDav и Nginx

Хочется взять и расстрелять, или ликбез о том, почему не стоит использовать make install

Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социальной сети starlook.ru
Zend_SimpleCloud
Zend_Dom_Query

create_full_put_path on;

6 Comments

  1. круто. всегда тоже хотелось вынести статику на отдельный сервер. а тут уже готовое решение

  2. А можно пример для я-диска только без ZEND ? Просто на php. Как залить файл на я-диск и получить от него ссылку на скачивание ?

  3. Андрей, на сколько я понял, статья на хабре была актуальна для сервиса narod.ru. Но это не суть, потому как я таки надыбал файлик webDAV class со всеми необходимыми ф-циями. Почти со всеми. Нет только возможности изменять св-ва залитого файла – сделать его публичным и получить ссылку на его скачивание. Могли бы вы мне в этом вопросе помочь?

    1. Ну можно попробовать) А для какого сервиса вы делаете интеграцию? Или это для своего webDAV-сервера?

Leave a Reply to Alexx Cancel reply