Saturday, February 09, 2008

Yaws — веб-сервер на Erlang

В самом начале обещал рассказать про веб-приложения на эрланге. Наверное, пора сворачивать ближе к теме.

В качестве веб-сервера для Erlang-приложений лучшим вариантом является написанный на эрланге же веб-сервер Yaws. Чем он хорош — он довольно сильно заточен под высо­копро­изво­ди­тельные приложения, и динамические страницы там удобно генерировать на эрланге.

Сначала насчет производительности:

Картинка известная, подробнее узнать, как она получена можно тут.  По горизонтали это количество параллельных запросов  к серверу (очень медленных клиентов), по вертикали — сколько кб/с при этом параллельно может отдавать сервер одному быстрому клиенту. Красненькое это yaws, синенькое и зелененькое это Apache, который после нескольких тысяч тихо умирает.

Конечно, Apache сравнивать с yaws не очень честно — все-таки апач продукт сложный и намного более многофункциональный, с кучей дополнительных модулей и настроек, и, в общем-то использовать его для отдачи статических страниц не очень принято. Однако ж картинка все-таки очень показательна, возможность держать много параллельных соединений важна в любом случае, да и с динамикой дела у yaws должны быть тоже хорошо (см. например Erlang vs PHP на Computer Language Shootout).

Пару слов об установке Yaws — с линуксом проблем, конечно, нет, на винду поставить тоже можно из-под Суgwin, но чтобы избежать лишней головной боли, обратите внимание, чтобы в пути к эрлангу и директории home не было пробелов (а последняя по умолчанию в "Documents And Settings" находится). Еще пара полезных замечаний про процесс установки есть тут.

 

Настраивается yaws с помощью конфиг-файла, там все довольно тривиально — дефолтный файл можно пока особенно не менять, разве что установить root директорию (параметр docroot).

Простейшее приложение с использованием yaws:

<head><title>Hello world using Yaws</title></head>
<body>
<erl>
out(A) ->
   case queryvar(A, "name") of
      {ok, Name} ->
        {html, "<div style=\"font-size: 12pt;\"> Hello, " ++ Name ++"</div>"};

      undefined ->
        {html, "<b> Name parameter required </b>"}
    end.
</erl>
</body>

 

Сохраняем его как hello.yaws в root директории.

hello-yaws

.yaws файл, как уже видно, это просто HTML шаблон. Каждый блок между тегами <erl> и </erl> компилируется в отдельный Erlang модуль. Каждый такой блок должен содержать функцию out/1, которой в качестве параметра передается структура, содержащая параметры запроса. Есть много вариантов как можно возвращать ответ, наиболее интересны два:

использованный выше

{html, HtmlString}

Где HtmlString — просто кусок HTML в виде строки, как в примере выше.

И чуть более удобный

{ehtml, Term}

Где Term — тот же HTML в виде терма Erlang, где тэги представляются кортежами или списками кортежей. Например, вот такой терм

{p, [],
    [
        {b, [], "Hello World"},
        {a, [{href, "http://www.example.com"}], 
           "link"}
    ]
}

преобразуется сервером в HTML-строку

<p>
  <b>Hello World</b>
  <a href="http://example.com">link</a>
</p>

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

Еще Yaws, кроме того что является просто веб-сервером, предоставляет немало дополнительных инструментов, таких как автоматическая поддержка сессий, cookie, механизмов удаленного вызова процедур на основе SOAP и JSON-RPC.

Для полноценного фреймворка — аналога Ruby on Rails и прочих, API Yaws, конечно, не дотягивает (для этого есть библиотека ErlyWeb), но для небольших приложений этого должно быть вполне достаточно.