воскресенье, 28 октября 2012 г.

Удобная FreeBSD

Я привык к Linux, однако на работе приходится пользоваться FreeBSD. Чтобы работать в ней стало более-менее удобно, мне нужна поддержка UTF-8, привычные vim-lite вместо классического vi и bash вместо sh или csh.

Отредактируем файл /etc/login.conf, чтобы описание класса russian приняло следующий вид:
russian|Russian Users Accounts:\
:charset=UTF-8:\
:lang=ru_RU.UTF-8:\
:tc=default:
Перекомпилируем файл:
# cap_mkdb /etc/login.conf
И назначим себе класс russian:
# pw usermod -n mylogin -L russian
Теперь поставим bash и vim-lite из портов:
# cd /usr/ports/shells/bash
# make install
# cd /usr/ports/editors/vim-lite
# make install
Убедимся, что bash появился в списке доступных оболочек в файле /etc/shells, и при необходимости добавим туда строчку с полным путём к выполняемому файлу bash:
/usr/local/bin/bash
Теперь выберем себе оболочку с помощью команды chsh (change shell), прописав полный путь к bash в соответствующей строчке:
$ chsh
Осталось настроить вызов vim по команде vi. Для этого в файле ~/.profile пропишем псевдоним:
alias vi='vim'
Заодно выставим переменную PAGER в значение less (less позволяет листать обратно):
PAGER=less
Теперь при подключении по ssh мы получаем консоль, работающую в UTF-8, привычный bash с удобным автодополнением, поддержку UTF-8 в редакторе, вызываемом по команде vi (родной vi из FreeBSD не умеет работать с UTF-8, редактор ee - тоже) и поддержку визуального режима редактирования в нём.

Для настройки UTF-8 в системной консоли FreeBSD можно воспользоваться заметкой UTF-8 в консоли FreeBSD.

Другие полезные настройки описаны здесь Русификация FreeBSD (UTF-8).

воскресенье, 21 октября 2012 г.

Настройка тайлового сервера TileStache

Ещё один тайловый сервер, который я нашёл в дистрибутиве Debian - это TileStache. Он, как и TileLite, тоже написан на Python. Это ещё один комбайн "всё в одном": он поддерживает отрисовку тайлов с помощью Mapnik, кэширование тайлов, в том числе сторонних, и содержит встроенный веб-сервер (по сути он им и является). В отличие от TileLite, этот тайловый сервер может обслуживать несколько слоёв сразу, в том числе, может брать тайлы слоя из стороннего тайлового сервера.

Настройка в режиме самостоятельного веб-сервера

Итак, ставим его:
# apt-get install tilestache
Создаём сценарий инициализации /etc/init.d/tilestache:
#!/bin/sh

### BEGIN INIT INFO
# Provides:          tilestache
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts TileStache server
# Description:       starts TileStache server using start-stop-daemon
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=tilestache
PID=/var/run/tilestache.pid
DAEMON=/usr/bin/tilestache-server
DAEMON_OPTS="--config /etc/tilestache.cfg -p 8000"

test -x $DAEMON || exit 0

set -e

case "$1" in
  start)
        echo "Starting $NAME: "
        start-stop-daemon --start --make-pidfile --background --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
        echo "done."
        ;;
  stop)
        echo "Stopping $NAME: "
        start-stop-daemon --stop --pidfile $PID --retry 5
        rm -f $PID
        echo "done."
        ;;
  restart)
        echo "Stopping $NAME: "
        start-stop-daemon --stop --pidfile $PID --retry 5
        rm -f $PID
        echo "done..."
        sleep 1
        echo "Starting $NAME: "
        start-stop-daemon --start --make-pidfile --background --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
        echo "done."
        ;;
  *)
        echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0

И прописываем в автозапуск:
# update-rc.d tilestache defaults
Копируем пример настройки сервера из файла /usr/share/doc/tilestache/examples/tilestache.cfg в файл /etc/tilestache.cfg и правим его до следующего вида:
{
  "cache":
  {
    "name": "Disk",
    "path": "/var/lib/tilestache",
    "umask": "0000"
  },
  "layers": 
  {
    "osm":
    {
        "provider": {"name": "mapnik", "mapfile": "/etc/mapnik-osm-data/osm.xml"},
        "projection": "spherical mercator"
    } 
  }
}
Создаём каталог для кэша тайлов:
# mkdir /var/lib/tilestache
Осталось запустить TileStache:
# /etc/init.d/tilestache start
Настройка Lighttpd для проксирования запросов к TileStache

Включаем модуль proxy веб-сервера Lighttpd:
# lighty-enable-mod proxy
Настраиваем модуль на проксирование каталога /osm в файле конфигурации модуля proxy /etc/lighttpd/conf-enabled/10-proxy.conf:
server.modules   += ( "mod_proxy" )
proxy.server = (
  "/osm" =>
  (
    (
      "host" => "127.0.0.1",
      "port" => 8000
    )
  )
)
Будьте внимательны, после строки /osm не должно быть косой черты, иначе тайловый сервер не будет работать должным образом.

Теперь ерезапустим Lighttpd:
# /etc/init.d/lighttpd restart
Настройка в режиме FastCGI для работы с Lighttpd

Теперь повторим уже опробованную ранее на TileLite методику запуска тайлового сервера в режиме FastCGI.

Создадим каталог для настроек TileStache, перенесём в него наш конфиг и поставим flup:
# mkdir /etc/tilestache
# mv /etc/tilestache.cfg /etc/tilestache
# apt-get install python-flup
В качестве образца для FastCGI-сервера возьмём файл /usr/bin/tilestache-server, скопировав его в каталог /etc/tilestache под именем tilestache.py:
# cp /usr/bin/tilestache-server /etc/tilestache/tilestache.py
Отредактируем его до следующего состояния:
#!/usr/bin/python

if __name__ == '__main__':
    from flup.server.fcgi import WSGIServer
    import TileStache

    application = TileStache.WSGITileServer(config='/etc/tilestache/tilestache.cfg', autoreload=True)
    WSGIServer(application).run()
Дадим права на выполнение:
# chmod +x /etc/tilestache/tilestache.py
И приступим к настройке модуля FastCGI в Lighttpd. Включим его:
# lighty-enable-mod fastcgi
И настроим следующим образом:
$HTTP["url"] =~ "^/osm/" {
  fastcgi.server +=
  (
    "" => 
    (
      (
        "bin-path" => "/etc/tilestache/tilestache.py",
        "socket" => "/tmp/tilestache.socket",
        "max-procs" => 1,
        "check-local" => "disable",
      )
    )
  )
}
В отличие от TileLite, этот сервер может обслуживать несколько слоёв одновременно, поэтому имя слоя нужно передавать в ссылке на запрашиваемый тайл. Поэтому настройка столь необычна. Она передаёт на обслуживание FastCGI-процессу корень веб-сервера лишь в том случае, если запрошена страница, адрес которой начинается с /osm/, то есть - имени слоя. Если нужно настроить несколько слоёв, потребуется доработать регулярное выражение таким образом, чтобы оно совпадало с именем каждого из слоёв.

Поскольку теперь TileStache будет запускаться Lighttpd, настроим права на доступ к каталогу /var/lib/tilestache:
# chmod www-data:www-data /var/lib/tilestache
Теперь остановим и отключим настроенный ранее TileStache, отключим модуль proxy и перезапустим веб-сервер:
# /etc/init.d/tilestache stop
# update-rc.d tilestache disable
# lighty-disable-mod proxy
# /etc/init.d/lighttpd restart
Нет в мире совершенства. Этот сервер хотя и настраивается легко и работает очень устойчиво, но работает во-первых очень медленно, а во-вторых, имеет утечки памяти. Поэтому для использования в нынешнем виде он не пригоден.

Количество, увы, не перешло в качество. Интересно, пользуются ли авторы своими творениями? Пользуются ли мэйнтейнеры из Debian GIS Project поддерживаемыми ими пакетами? Судя по отсутствию сценариев инициализации - нет. А если и пользуются, то скорее всего совместно с Apache и mod_wsgi. Но в таком случае я их не понимаю - раз уж от Apache никуда не деться, почему бы не воспользоваться mod_tile?

воскресенье, 14 октября 2012 г.

Настройка тайлового сервера TileLite

Ранее я уже описывал настройку системы для отрисовки тайлов OpenStreetMap на основе renderd, apache и mod_tile в своей заметке Установка renderd и mod_tile - системы отрисовки тайлов по запросу.

Сейчас же я хочу рассмотреть ещё одни тайловый сервер, основанный на Mapnik - сервер TileLite. Но прежде чем я это сделаю, хочу сразу сказать о достоинствах и недостатках обеих систем.

Система из renderd, apache и mod_tile хороша тем, что она представляет собой законченное решение, так как включает в себя функции отрисовки тайлов, кэширования тайлов и веб-сервер для отдачи тайлов. Ещё одно преимущество этой связки заключается в том, что она способна обслуживать сразу несколько слоёв. Недостатков у неё два - она сравнительно сложна, громоздка и отсутствует в официальном репозитории Debian.

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

Настройка в режиме самостоятельного веб-сервера

Поставим пакет tilelite:
# apt-get install tilelite
Создадим сценарий инициализации /etc/init.d/liteserv со следующим содержимым:
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts TileLite server
# Description:       starts TileLite server using start-stop-daemon
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=liteserv
PID=/var/run/liteserv.pid
DAEMON=/usr/bin/liteserv
DAEMON_OPTS="/etc/mapnik-osm-data/osm.xml --config /etc/liteserv.cfg"

test -x $DAEMON || exit 0

set -e

case "$1" in
  start)
        echo "Starting $NAME: "
        start-stop-daemon --start --make-pidfile --background --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
        echo "done."
        ;;
  stop)
        echo "Stopping $NAME: "
        start-stop-daemon --stop --pidfile $PID --retry 5
        rm -f $PID
        echo "done."
        ;;
  restart)
        echo "Stopping $NAME: "
        start-stop-daemon --stop --pidfile $PID --retry 5
        rm -f $PID
        echo "done..."
        sleep 1
        echo "Starting $NAME: "
        start-stop-daemon --start --make-pidfile --background --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
        echo "done."
        ;;
  *)
        echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac

exit 0

И добавим скрипт в автозапуск:
# update-rc.d liteserv defaults
Теперь скопируем пример файла конфигурации в каталог /etc:
# cp cp /usr/share/doc/tilelite/examples/tilelite.cfg /etc/liteserv.cfg
И поправим его до следующего состояния:
[tiles]
size = 256
buffer_size = 128
format = png
paletted = no
max_zoom = 22
debug = off
watch_mapfile = off
watch_interval = 2
max_failures = 6

[cache]
caching = on
cache_path = /var/lib/liteserv
cache_force = off
Создадим каталог для хранения кэша (почему-то он работает, только если указать соответствующую опцию командной строки):
# mkdir /var/lib/liteserv
И запустим его:
# /etc/init.d/liteserv start
Сервер будет ожидать подключений на локальном адресе 127.0.0.1, на TCP-порту 8000. Для изменения настроек можно указать соответствующие опции в сценарии init.d.

Настройка Lighttpd для проксирования запросов к TileLite

Можно настроить веб-сервер Lighttpd для проксирования запросов к TileLite:
server.modules   += ( "mod_proxy" )
proxy.server = (
  "/osm/" =>
  (
    (
      "host" => "127.0.0.1",
      "port" => 8000
    )
  )
)
Этот фрагмент можно вписать прямо в файл /etc/lighttpd/lighttpd.conf, но в Debian правильнее будет включить модуль proxy и вписать настройки в его файл конфигурации /etc/lighttpd/conf-enabled/10-proxy.conf. Для включения модуля используется следующая команда:
# lighty-enable-mod proxy
Можно поставить ещё пакет python-werkzeug и настроить количество одновременно работающих процессов TileLite в сценарии init.d. Хотя с такой настройкой TileLite у меня работал быстро, но работал он не долго - всего через несколько секунд он переставал отвечать на запросы.

Настройка в режиме FastCGI для работы с Lighttpd

Вместо этого я попробовал ещё один подход - запускать TileLite как сервер FastCGI. Для этого нужно поставить пакет python-flup:
# apt-get install python-flup
Теперь создадим скрипт для запуска TileLite как FastCGI-процесса и настроим Lighttpd. Перед созданием скрипта запуска я создал каталог /etc/liteserv, в который перенёс настроенный ранее конфиг liteserv.cfg из каталога /etc. Воспользовавшись примером WSGI-скрипта из каталога /usr/share/doc/tilelite/examples/tiles_app.py и примерами настройки FastCGI на сайте сервера Lighttpd, я наваял следующий FastCGI-скрипт для TileLite, который разместил в файле /etc/liteserv/liteserv.py:
#!/usr/bin/python

from tilelite import Server
from flup.server.fcgi_fork import WSGIServer

mapfile = '/etc/mapnik-osm-data/osm.xml'
config = '/etc/liteserv/liteserv.cfg'

application = Server(mapfile,config)
WSGIServer(application, maxChildren=3).run()
Две особенности этого скрипта - это использование flup.server.fcgi_fork вместо более обычного flup.server.fcgi и указание опции maxChildren=3. Они заставляют FastCGI-сервер работать в многопроцессном, а не в многопоточном режиме, при чём число одновременно работающих процессов не должно превышать 3. Эти настройки позволили мне достичь наибольшей стабильности в работе тайлового сервера на своём старом компьютере. Похоже, что моему компьютеру не хватает оперативной памяти, чтобы обрабатывать много запросов к базе данных сразу, а сам TileLite плохо работает в многопоточном режиме.

Теперь настроим Lighttpd. Для этого нужно включить модуль fastcgi:
# lighty-enable-mod fastcgi
И прописать в файл /etc/lighttpd/conf-enabled/10-fastcgi.conf следующие настройки:
fastcgi.server = (
  "/osm" => 
  (
    (
      "bin-path" => "/etc/liteserv/liteserv.py",
      "socket" => "/tmp/liteserv.socket",
      "max-procs" => 1,
      "check-local" => "disable"
    )
  )
)
Очень важно не дописывать к строчке /osm символа косой черты в конце - от этого TileLite сходит с ума и не обрабатывает запросы должным образом.

Наконец, поскольку теперь TileLite будет запускаться Lighttpd, настроим права на доступ к каталогу /var/lib/liteserv:
# chmod www-data:www-data /var/lib/liteserv
И перезапустим сервер, не забыв отключить настроенный до этого liteserv и настройку модуля proxy Lighttpd:
# /etc/init.d/liteserv stop
# update-rd.d liteserv disable
# lighty-disable-mod proxy
# /etc/init.d/lighttpd restart
В таком виде тайловый сервер в режиме FastCGI заработал более-менее стабильно.

Однако, поскольку этот тайловый сервер закидывает запросами PostgreSQL и не делает запросы повторно в случае ошибки, на моём компьютере TileLite работает довольно нестабильно. Поэтому я всё-же предпочёл продолжить использование renderd, apache и mod_tile.