Записки программиста, обо всем и ни о чем. Но, наверное, больше профессионального.

2013-08-08

Plone in production

Не так давно я написал заметку про установку Plone 4.3 на CentOS 6.4, добавив напоследок:
В следующий раз, если захочется, поглядим как сделать production сервер на этой основе — как и какой frontend поставить, как сделать балансировку с использованием ZEO, как настроить автозапуск служб, ротацию логов, резервное копирование, etc.

Вот, пришла пора. Если хочется, поглядим на сборку production сервера с вебсайтом Plone на борту. Букофф многа. Кто не знает, что такое ZMI, ZEO, frontend и подобная лабуда — уходите сейчас.

Конфигурация боевого сервера (назову его deploy.nhome.net) будет такая:
* 32-х разрядная CentOS 6.4 на двухядерной машине с 512 мегабайт оперативки;
* Plone 4.3 standalone (без ZEO), установленный «от рута»;
* Nginx 1.4.2 + ngx_cache_purge 2.1 в качестве фронтэнда.

Несколько слов о причинах именно такой конфигурации. Когда я размышлял о том, какие компоненты выбрать, я учитывал два факта: хостинг (VPS) должен быть недорогой, точнее один из самых недорогих — это раз; веб-сайт должен показывать превосходное быстродействие и хорошую надежность. Как вы понимаете, это взаимоисключающие требования — на ограниченных ресурсах сделать быстрый и надежный веб-сайт на Plone CMS.
Чтобы сделать быстро и надежно — нужен хороший фронтэнд с кешированием и устойчивостью к нагрузкам. Чтобы экономить ресурсы, сайт должен содержать минимум компонент и эти компоненты должны быть нежадными.
Думаю, теперь понятно, почему Plone сделан в версии standalone, а не ZEO. Хотя ZEO было бы гораздо надежнее и устойчивее. Ну, может быть, когда нибудь, ради интереса, я оттестирую конфигурацию с ZEO, хотя, IMHO, на практике standalone Plone закрывает 99% потребностей.
Также, понятно почему Nginx. Легкий, быстрый, мощный, надежный и умеет балансировать нагрузку, кешировать, проксировать. Проверен в боях.

Далее. Раскладка по службам

* порт 80 — HTTP веб-морда Nginx, запросы через reverse proxy отправляются на порт 8080 в Plone. Ответы кешируются в Nginx на 10 минут, и, очевидно, если ответ есть в кеше, Nginx, не спрашивая Plone, отправляет ответ посетителю из кеша. Запросы аутентифицированных пользователей не кешируются; для отделения овец от козлищ анонимных от авторизованных используется проверка на наличие специфичной cookie. Несмотря на наличие возможности авторизоваться на сайте через HTTP, делать этого настоятельно не рекомендуется. Оставьте паблик сервис для анонимусов.

* порт 443 — HTTPS веб-морда Nginx, для работы с сайтом авторизованных пользователей типа авторов, редакторов, контент-менеджеров. В общем, аналогично порту 80, за исключением того, что тут нет никакого кеша.

* порт 22 — SSH для сисадминов. Нюанс в том, что доступ к веб-управлятору ZMI можно получить только через SSH, пробросив порт 8080 сайта на свою машину.

Конец предисловия, к делу.

Как установить Plone на production сервер, я уже написал
В итоге имеем стоковый Plone 4.3 standalone, установленный «от рута». В файрволле открыты порты 8080, 80, 443.

Поправим buildout.cfg для включения нужных моему сайту пакетов:
su -l
pushd /usr/local/Plone/zinstance
nano buildout.cfg

[buildout]
…
find-links += 
    http://dist.plone.org/release/4.3.1 
    https://github.com/vasnake/customplone.app.locales/tarball/clubwindsurf/customplone.app.locales-4.3.2.dev1.tar.gz 
...
eggs =
...
    collective.quickupload
    collective.ptg.allnewest
    xhostplus.gallery
    customplone.app.locales
…
zcml =
    customplone.app.locales
    xhostplus.gallery
…
[instance]
...
environment-vars = zope_i18n_compile_mo_files true
…
[versions] 
...
customplone.app.locales = 4.3.2.dev1 

EOF

sudo -u plone_buildout /usr/local/Plone/zinstance/bin/buildout -nv

Теперь Plone готов к заливке в него данных сайта (сделанного ранее на девелоперском сервере). Заливку будем проводить так:
* экспорт всего сайта используя ZMI на разраб.сервере. У меня получился файл cms.zexp (обычно сайт при создании обзывают «Plone» но я обозвал его «cms», вот такой оригинал :)
* импорт сайта через ZMI production сервера.
Сделать это проще пареной свеклы:
su -l
mv /home/valik/cms.zexp /usr/local/Plone/zinstance/var/instance/import/
sudo -u plone_daemon /usr/local/Plone/zinstance/bin/instance fg 
потом браузером через ZMI (http://deploy.nhome.net:8080/manage_main) импортировал файл в Zope. Потом миграция http://deploy.nhome.net:8080/cms/@@plone-upgrade
и проверка работы сайта прощелкиванием.
Работает, как ни странно :)

Вообще, если прочесть must have книгу Professional Plone 4 Development - Martin Aspeli, то станет очевидно, что я выбрал способ деплоя сайта Плон не самый правильный. Зато самый легкий :)

Далее - автозапуск службы Plone.

Обеспечить автостарт сайта при запуске машины хоста.
Дока пишет:
You can start and stop Plone with your server by adding and init.d (Linux and other sys v heritage systems) or rc.d (BSD heritage) script that accepts start and stop commands. The Unified Installer has an init_scripts directory that contains sample initialization/stop scripts for several platforms. If you didn't use that installer, you may find the scripts on github.


Хотя дока настоятельно рекомендует это http://supervisord.org/
Я полагаю, Супервизор будет полезен при разворачивании кластера ZEO, для моих же ограниченных ресурсов это избыточно. Поэтому для standalone конфигурации я буду применять init_scripts:
su -l
pushd /tmp/Plone-4.3.1r1-UnifiedInstaller/init_scripts/RedHat-FedoraCore/
cp plone-standalone /etc/rc.d/init.d/plone
chmod 755 /etc/rc.d/init.d/plone
chkconfig --add plone
Перезапуск машины... сайт работает, что значит — задача автозапуска решена.

Далее - ротация логов Plone.

У Plone standalone два файла логов:
/usr/local/Plone/zinstance/var/log/
    instance.log
    instance-Z2.log
Для кластера логов будет больше и в разных местах, но мне пока пофиг, я пока без кластера.
Дока пишет
For Plone 4.2.2+, just add configuration settings like these to your buildout's zope2instance sections:
[client1]
recipe = plone.recipe.zope2instance
...
event-log-max-size = 5 MB
event-log-old-files = 5
access-log-max-size = 20 MB
access-log-old-files = 10
This will maintain five generations of event logs of maximum five megabytes in size and 10 generations of 20 megabyte access logs.

В моем билдауте нужная секция находится ближе к концу файла и выглядит так:
su -l
pushd /usr/local/Plone/zinstance
nano buildout.cfg
...
[instance] 
<= instance_base 
recipe = plone.recipe.zope2instance 
http-address = 8080 
environment-vars = zope_i18n_compile_mo_files true
...

А после предлагаемых правок, соответственно, так:
...
[instance] 
<= instance_base 
recipe = plone.recipe.zope2instance 
http-address = 8080 
environment-vars = zope_i18n_compile_mo_files true
event-log-max-size = 5 MB
event-log-old-files = 5
access-log-max-size = 30 MB
access-log-old-files = 9
...

Проверим...
service plone stop 
sudo -u plone_buildout /usr/local/Plone/zinstance/bin/buildout 
service plone start

На другой машине подергаем домашнуюю страницу сайта и поглядим на логи:
ab -kc 3 -t 30 http://deploy.nhome.net:8080/cms
в три потока в течение 30 секунд, для начала.
Тесты показали, что такая ротация логов работоспособна.

Далее - Установка Nginx

Народная мудрость гласит:
To add nginx yum repository, create a file named /etc/yum.repos.d/nginx.repo and paste one of the configurations below:
nano /etc/yum.repos.d/nginx.repo 

[nginx] 
name=nginx repo 
baseurl=http://nginx.org/packages/centos/6/i386/ 
gpgcheck=0 
enabled=1 

EOF

yum check-update 
yum install nginx
Без проблем, Nginx установлен.

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

Ротация логов nginx — тоже, все работает из коробки. Я только поправил то, что жирным выделено:
nano /etc/logrotate.conf
...
compress
delaycompress

nano /etc/logrotate.d/nginx 
/var/log/nginx/*.log {
        daily
        missingok
        rotate 10
        compress
        delaycompress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
        endscript
}
В целом, если логи складывать в /var/log/nginx/*.log
то ротация логов внимания не потребует.

Конфигурация Nginx.

Самый простой конфиг — проксирование запросов на Plone. После запуска этого конфига можно (нужно) закрыть файрволлом доступ к порту 8080.
nano /etc/nginx/conf.d/deploy.nhome.net.conf

upstream plone {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name www.deploy.nhome.net;
    rewrite ^/(.*) http://deploy.nhome.net/$1 permanent;
}

server {
    listen 80;
    server_name deploy.nhome.net;
    access_log /var/log/nginx/deploy.nhome.net.access.log;
    error_log /var/log/nginx/deploy.nhome.net.error.log;

    location / {
          proxy_pass http://plone/VirtualHostBase/http/deploy.nhome.net:80/cms/VirtualHostRoot/;
    }
}

EOF

/etc/init.d/nginx configtest
service nginx restart
netstat -tulnpv
В итоге фронтэнд есть и успешно проксирует Плон, что показывает прощелкивание сайта в браузере по URL http://deploy.nhome.net/
После поднятия фронтэнда на 80 порту закроем файрволлом все порты кроме 22, 80, 443
system-config-firewall-tui
service iptables restart
service network restart
iptables -L
iptables -L -vn
nano /etc/sysconfig/iptables 

Проблема: как обеспечить доступ к корню ZMI? Ведь проксирование сделано на внутрь сайта Plone, а сисадмину иногда надо залезать в корень админки ZMI.
Поскольку доступ к корню ZMI нужен только для администратора сайта, то не будем делать это легким способом. Пусть админ делает это через SSH
ssh -v valik@deploy -L 8080:localhost:8080 
тогда в браузере URL админки будет
К тому же
Never ever expose your zope-root or login using the zope-admin-Account via http since the zope-admins password is only uuencoded in a cookie!

Кстати, нам нужен HTTPS.

Для управления сайтом и материалами следует обращаться к сайту по закрытому каналу. Отсюда — включить HTTPS для авторизованных пользователей.
Вкурив народную мудрость, я получил следующий простой но работоспособный конфиг фронтэнда для работы с сайтом по HTTPS:
su -l
openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/www.pem -keyout /etc/ssl/certs/www.key
ls -la /etc/ssl/certs/
chmod 600 /etc/ssl/certs/www*
cp /etc/nginx/conf.d/example_ssl.conf /etc/nginx/conf.d/deploy.nhome.net_ssl.conf
nano /etc/nginx/conf.d/deploy.nhome.net_ssl.conf

#upstream plone {
#    server 127.0.0.1:8080;
#}

server {
    listen       443;
    server_name  deploy.nhome.net;
    keepalive_timeout 70;

    ssl                  on;
    ssl_certificate      /etc/ssl/certs/www.pem;
    ssl_certificate_key  /etc/ssl/certs/www.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    access_log /var/log/nginx/deploy.nhome.net_ssl.access.log;
    error_log /var/log/nginx/deploy.nhome.net_ssl.error.log;

    location / {
          proxy_pass http://plone/VirtualHostBase/https/deploy.nhome.net:443/cms/VirtualHostRoot/;
    }
}
nano /etc/nginx/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include   /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    include /etc/nginx/conf.d/*.conf;
}

EOF

service nginx restart
Проблемы. Поскольку сертификат самоподписанный, браузеры будут сопротивляться заходу на https://deploy.nhome.net/. Это лечится импортированием сертификата в список доверенных браузера. Еще одна проблема — когда на страницах сайта используются виджеты со сторонних ресурсов, браузеры могут по тихому игнорировать такое «подмешанное» содержимое, если оно не соответствует их представлению о безопасности. Это лечится своевременным нажатием разных кнопок в браузере, у каждого своих.
Но, в целом, доступ по HTTPS для редакторов сайта работает.

Теперь — Кеширование.

В дополнение к прекрасному кешированию Plone можно попробовать добавить внешний кеш. Кеширование в Plone позволяет достичь показателя 140 запросов в секунду, кому-то этого достаточно. Но можно лучше.
su -l
mkdir -p /var/cache/nginx/proxy
chown nginx /var/cache/nginx/proxy
chmod 700 /var/cache/nginx/proxy
nano /etc/nginx/conf.d/deploy.nhome.net.conf

# http {

    upstream plone {
        server 127.0.0.1:8080;
    }

    # proxy_cache_path path [ levels = levels ] keys_zone = name : size [ inactive = time ] [ max_size = size ] [ loader_files = number ] [ loader_sleep = time ] [ loader_threshold = time ]
    # Zone size should be set proportional to number of pages to cache. The size of the metadata for one page (file) depends on the OS; currently it is 64 bytes for FreeBSD/i386, and 128 bytes for FreeBSD/amd64
    # 1m = 1024 * 1024 / 128 = 8192 pages
    proxy_cache_path    /var/cache/nginx/proxy  levels=1:2 keys_zone=thecache:1m max_size=300m inactive=10m;
    proxy_temp_path     /var/cache/nginx/proxy_temp;

    # commenting this cause 'MISS' in cache log for Plone pages views
    proxy_ignore_headers Expires Cache-Control;

    # key for caching, default: proxy_cache_key $scheme$proxy_host$uri$is_args$args;
    proxy_cache_key $proxy_host$uri$is_args$args;
    # response will not be taken from a cache               
    proxy_cache_bypass $cookie___ac;
    # response will not be saved to a cache - when users are logged in (detect by cookie)
    proxy_no_cache $cookie___ac;

    log_format cache '$remote_addr $time_local '
                     '$upstream_cache_status '
                     'Cache-Control: $upstream_http_cache_control '
                     'Expires: $upstream_http_expires '
                     '"$request" $status '
                     '"$http_user_agent" $scheme$proxy_host$uri$is_args$args';

    # Redirect all www traffic to the www-less domain
    server {
        listen 80;
        server_name www.deploy.nhome.net;
        rewrite ^/(.*) http://deploy.nhome.net/$1 permanent;
    }

    server {
        listen 80;
        server_name deploy.nhome.net;

        access_log /var/log/nginx/deploy.nhome.net.access.log;
        # log for cache hits.
        access_log /var/log/nginx/deploy.nhome.net.cache.log cache;
        error_log /var/log/nginx/deploy.nhome.net.error.log;

        # proxy to Plone backend
        location / {
            # redirect PURGE requests from siteAdmin (root Zope access)
            rewrite  ^/cms/(.*)$  /$1  break;

            # bcause of Plone VHM - turn off replacing text in Location and Refresh headers
            proxy_redirect                  off;
            # set extra headers for backend
            proxy_set_header                Host $host;
            proxy_set_header                X-Real-IP $remote_addr;
            proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
            # maximum request Content-Length
            client_max_body_size            10m;
            # RAM buffer size for request body
            client_body_buffer_size         128k;
            # timeout for write to backend
            proxy_send_timeout              90;
            # buffer size for first part of backend response
            proxy_buffer_size               4k;
            # number and size of buffers for backend response, even pictures less that 128KB
            proxy_buffers                   4 32k;
            # buffers size busy sending response to client - half of proxy_buffers
            proxy_busy_buffers_size         64k;
            # buffer size for writing tmp file while buffering backend response
            proxy_temp_file_write_size      64k;
            # timeout for establishing a connection with backend
            proxy_connect_timeout           30;
            # timeout between two succesive reads from backend
            proxy_read_timeout              60;

            # turn cache on by cache name
            proxy_cache                     thecache;
            # make Plone's 'purge cache' possible
            proxy_cache_purge               PURGE from 127.0.0.1;
            # cache time for response 200, 301, and 302; 404; any
            proxy_cache_valid               10m;
            proxy_cache_valid               404 10m;
            proxy_cache_valid               any 10m;
            # change $proxy_host to 'plone' in key, bcause purge module can't get that variable
            proxy_cache_key                 plone$uri$is_args$args;

            # protocol and address of a backend
            proxy_pass http://plone/VirtualHostBase/http/deploy.nhome.net:80/cms/VirtualHostRoot/;
        }
    }

EOF

service nginx restart
tail -f /var/log/nginx/deploy.nhome.net.cache.log
Примечание: директива
proxy_cache_purge               PURGE from 127.0.0.1;
на данном этапе работать не будет, ее надо закомментировать. Позже я проясню эту тему. Заодно обратите внимание на переопределение ключа кеша
proxy_cache_key                 plone$uri$is_args$args;
Если не заменить «$proxy_host» на «plone» в определении ключа, то очистка (PURGE) кеша работать не будет.

Тестирование Apachebench-ем показывает выдачу из кеша со скоростью до 5000 запросов в секунду. Прекрасно, ящетаю :)

Проблема с попаданием в кеш страниц для авторизованных пользователей решается вот этими директивами:
    # response will not be taken from a cache               
    proxy_cache_bypass $cookie___ac;
    # response will not be saved to a cache - when users are logged in (detect by cookie)
    proxy_no_cache $cookie___ac;
Хорошо, что сайт не является какой-нибудь социальной сетью, где все страницы заточены под авторизованных. Там такой подход к кешированию не проходит.

Еще одна проблема кеширования – проблема инвалидации кеша при редактировании материалов сайта. Простое решение проблемы — сделать время жизни кеша небольшим — 1 минута.
можно сделать вывод, что опция
proxy_ignore_headers Expires Cache-Control;
в конфиге Nginx должна быть закомментирована. Тогда Nginx, уважая заголовки от Plone, будет кешировать то, что Плон хочет кешировать и не будет остальное. Управлять заголовками нужно в настройках сайта Плона, в разделе кеширования.
По умолчанию предполагается, что в кеш Nginx будет попадать только файлы, скрипты и стили. Но это не решение проблемы, это ее отодвигание.

Сложное но правильное решение — добавить в Nginx модуль ngx_cache_purge. Для этого придется перекомпилировать Nginx.
Как вариант, можно найти репозиторий пакетов для CentOS, где Nginx скомпилен уже с модулем purge:
Но я буду компилировать.

Сборка Nginx.

Сборка с добавкой модуля nginx_ngx_cache_purge
Текущую конфигурацию смотрим
nginx -V
и добавляем в нее
--add-module=/root/ngx_cache_purge-2.1
su -l
wget http://nginx.org/download/nginx-1.4.2.tar.gz
wget http://labs.frickle.com/files/ngx_cache_purge-2.1.tar.gz
tar -xvf nginx-1.4.2.tar.gz
tar -xvf ngx_cache_purge-2.1.tar.gz
cd nginx-1.4.2

nginx -V
    configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables'

./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables' --add-module=/root/ngx_cache_purge-2.1
    error: the HTTP rewrite module requires the PCRE library.

yum install -y httpd-devel pcre perl pcre-devel zlib zlib-devel GeoIP GeoIP-devel

# повторить конфигур

make
service nginx stop
make install
service nginx restart
Сборка и установка прошли успешно. Все наши конфиги сохранились.

Теперь нужно раскомментировать
proxy_cache_purge               PURGE from 127.0.0.1;
и настроить Plone так, чтобы при редактировании страниц он засылал в Nginx запрос на удаление из кеша старой страницы.
Для этого достаточно зайти сисадминским способом в управлятор ZMI и добраться до панели управления кешем:

В ней включить кеш, включить очистку «purging» и указать URL прокси:

В таком виде пурга отлично работает. Плон, после сохранения страницы, засылает пачку запросов PURGE, отлавливаемых модулем Nginx; модуль удаляет из кеша записи. Следующее обращение к странице в кеш не попадает и запрос направляется в Плон. Как доктор прописал.

Итого.

В итоге доступ к сайту происходит по следующий схеме:

Типичные посетители сайта обращаются по URL
к 80-му порту, обслуживаемому Nginx, который на 10 минут кеширует все ответы на такие запросы, что дает производительность до 5000 запросов в сек.
Если посетитель сайта пройдет аутентификацию, что не рекомендуется (ибо канал не шифруется), его общение с сайтом не будет кешироваться Nginx за счет наличия специальной куки в трафике. Запросы мимо кеша Nginx обслуживаются со скоростью до 140 запросов в сек.

Редактор материалов — contentmanager заходит по URL
на 443-му порт, обслуживаемый Nginx, который без кеширования проксирует такие запросы на Plone, порт 8080. Редактирование (сохранение) страниц сайта приводит к выдаче Плоном запроса PURGE к Nginx, что вызывает удаление из его кеша старого варианта страницы.

Администратор сайта, для управления настройками, создания резервный копий и просто доступа к ZMI обращается к сайту по URL
но только после того, как пробросит порт сайта через ssh
sh valik@deploy -L 8080:localhost:8080
на свою машину.


Неотъемлемой частью production сервера является мониторинг:
потребление ресурсов, сбои, обслуживаемые запросы, использование кеша/производительность и пр.
Тут все как всегда и ничего необычного.

Кстати, про потребление ресурсов:
в моем конфиге из 500 мегабайт оперативки занято 328 (около 150 — сервер Zope). Оставшаяся память (170) вся занята кешем и буферами (105 + 34). Своп не используется.

Список мониторных команд:
  • pstree -a
  • ps aux|less
  • netstat -ntlp
  • netstat -nulp
  • netstat -nxlp
  • free -m
  • less /proc/meminfo
  • vmstat
  • uptime
  • top
  • iostat
  • iostat -kx 2
  • mpstat 2 10
  • dstat --top-io –top-bio
  • vgs
  • pvs
  • lvs
  • df -h
  • mount
  • lsof
  • ss -s
  • dmesg
  • less /var/log/messages
  • less /var/log/secure
  • less /var/log/auth

Логи приложений
  • tail -f /var/log/nginx/deploy.nhome.net.cache.log
  • tail -f /var/log/nginx/*.log
  • tail -f /usr/local/Plone/zinstance/var/log/instance.log
  • tail -f /usr/local/Plone/zinstance/var/log/instance-Z2.log

monitoring platform
Munin, Zabbix, Nagios, New Relic… Anything will do.

centralized logs
Loggly, Airbrake, Graylog…


И напоследок про резервные копии и восстановление.

Несмотря на большое количество буков в инструкциях по созданию копий
идея стандартная — копируйте всю папку в которой развернут Plone. Трудность в том, что файл Data.fs заблокирован пока сайт работает. Чтобы его скопировать правильно и не потерять синхронности с blobstorage и придумали всякие сложные схемы. Кстати, этот файл еще и паковать надо регулярно
Чем активнее редактируют сайт, тем чаще следует паковать файл.

Лично мне проще раз в неделю, наряду с общим обслуживанием сайта, сделать экспорт всего сайта в файл cms.zexp и потом запаковать базу. Все вручную, через ZMI. Но если есть желание, то можно и автоматизировать эти две минутные процедуры.
Имея на руках файл cms.zexp и вышеприведенный текст, сайт восстанавливается с нуля за час времени.

Вот и сказочке конец, а кто слушал — молодец.

Материалы для самостоятельного изучения:



original post http://vasnake.blogspot.com/2013/08/plone-in-production.html

Комментариев нет:

Отправить комментарий

Архив блога

Ярлыки

linux (241) python (191) citation (186) web-develop (170) gov.ru (159) video (124) бытовуха (115) sysadm (100) GIS (97) Zope(Plone) (88) бурчалки (84) Book (83) programming (82) грабли (77) Fun (76) development (73) windsurfing (72) Microsoft (64) hiload (62) internet provider (57) opensource (57) security (57) опыт (55) movie (52) Wisdom (51) ML (47) driving (45) hardware (45) language (45) money (42) JS (41) curse (40) bigdata (39) DBMS (38) ArcGIS (34) history (31) PDA (30) howto (30) holyday (29) Google (27) Oracle (27) tourism (27) virtbox (27) health (26) vacation (24) AI (23) Autodesk (23) SQL (23) Java (22) humor (22) knowledge (22) translate (20) CSS (19) cheatsheet (19) hack (19) Apache (16) Manager (15) web-browser (15) Никонов (15) Klaipeda (14) functional programming (14) happiness (14) music (14) todo (14) PHP (13) course (13) scala (13) weapon (13) HTTP. Apache (12) SSH (12) frameworks (12) hero (12) im (12) settings (12) HTML (11) SciTE (11) USA (11) crypto (11) game (11) map (11) HTTPD (9) ODF (9) Photo (9) купи/продай (9) benchmark (8) documentation (8) 3D (7) CS (7) DNS (7) NoSQL (7) cloud (7) django (7) gun (7) matroska (7) telephony (7) Microsoft Office (6) VCS (6) bluetooth (6) pidgin (6) proxy (6) Donald Knuth (5) ETL (5) NVIDIA (5) Palanga (5) REST (5) bash (5) flash (5) keyboard (5) price (5) samba (5) CGI (4) LISP (4) RoR (4) cache (4) car (4) display (4) holywar (4) nginx (4) pistol (4) spark (4) xml (4) Лебедев (4) IDE (3) IE8 (3) J2EE (3) NTFS (3) RDP (3) holiday (3) mount (3) Гоблин (3) кухня (3) урюк (3) AMQP (2) ERP (2) IE7 (2) NAS (2) Naudoc (2) PDF (2) address (2) air (2) british (2) coffee (2) fitness (2) font (2) ftp (2) fuckup (2) messaging (2) notify (2) sharepoint (2) ssl/tls (2) stardict (2) tests (2) tunnel (2) udev (2) APT (1) CRUD (1) Canyonlands (1) Cyprus (1) DVDShrink (1) Jabber (1) K9Copy (1) Matlab (1) Portugal (1) VBA (1) WD My Book (1) autoit (1) bike (1) cannabis (1) chat (1) concurrent (1) dbf (1) ext4 (1) idioten (1) join (1) krusader (1) license (1) life (1) migration (1) mindmap (1) navitel (1) pneumatic weapon (1) quiz (1) regexp (1) robot (1) science (1) serialization (1) spatial (1) tie (1) vim (1) Науру (1) крысы (1) налоги (1) пианино (1)