Обслуживание Go-приложений при помощи Martini на сервере Nginx в Ubuntu

Веб-фреймворки – это инструменты для быстрой разработки приложений. Они часто берут на себя конфигурирование нижнего уровня, что позволяет разработчикам сосредоточиться на функциональности и презентации приложения.

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

Данное руководство покажет, как быстро собрать приложение Go с помощью Martini на сервере Ubuntu 12.04.

Установка Go с помощью GVM

Пакеты Go можно найти в стандартных репозиториях Ubuntu 12.04. Но в них может содержаться устаревшая версия, а Martini требует Go не старше версии 1.1.

Потому для установки Go рекомендуется использовать пакетный менеджер gvm (Go Version Manager). Но сначала нужно установить несколько зависимостей:

sudo apt-get update
sudo apt-get install curl git mercurial make binutils bison gcc

Установив зависимости менеджера gvm, можно загрузить и запустить установочный скрипт gvm со страницы проекта на GitHub:

bash < <(curl -s https://raw.github.com/moovweb/gvm/master/binscripts/gvm-installer)

Это загрузит и установит скрипты и файлы gvm в скрытый каталог по имени .gvm. Чтобы установить необходимую версию Go при помощи gvm, выполните следующую команду, чтобы скрипт стал доступен в текущей сессии оболочки:

source ~/.gvm/scripts/gvm

Теперь команда gvm доступна в текущей сессии. Используйте её для установки Go 1.2.

gvm install go1.2

Эта команда установит версию Go, совместимую с Martini. Сделайте эту версию дефолтной:

gvm use go1.2 --default

Настройка окружения Go

Теперь нужно настроить окружение Go. Для корректной сборки Go требует определенным образом подготовленного окружения; к примеру, каталог проекта должен содержать подкаталоги bin, src и pkg.

Создайте эту структуру в домашнем каталоге:

cd ~
mkdir -p go/{bin,pkg,src}

Теперь нужно исправить путь Go, указав в нём путь к этому каталогу, а также добавить каталог go/bin:

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

Можно добавить эти строки в .bashrc, чтобы они выполнялись в каждой новой сессии:

echo "export GOPATH=$HOME/go" >> ~/.bashrc
echo "export PATH=$PATH:$GOPATH/bin" >> ~/.bashrc

Теперь можно приступать к работе над первым приложением Martini.

Создание приложения Martini

Для начала попробуйте создать простое приложение «Hello world», чтобы ознакомиться с доступными функциями Martini.

Назовём приложение hello.go и поместим его в одноименный каталог в каталоге ~/go/src:

cd ~/go/src
mkdir hello
nano hello/hello.go

В этот файл нужно добавить код приложения Go.

Импортируйте пакет Martini, задав его расположение.

package main
import "github.com/codegangsta/martini"

Создайте главную функцию, в которой будет содержаться основной код программы:

package main
import "github.com/codegangsta/martini"
func main() {
server := martini.Classic()
server.Get("/", func() string {
return "<h1>Hello, world!</h1>"
})
server.Run()
}

Рассмотрим подробнее код функции main().

server := martini.Classic()

Эта строка определяет переменную server и присваивает ей объект Classic. Функция classic() создаёт экземпляр Martini, содержащий стандартные настройки и функциональность.

server.Get("/", func() string {
return "<h1>Hello, world!</h1>"
})

Этот блок кода настраивает url-обработчик и отвечает на get-запросы HTTP к ресурсу / (это root-расположение URL-а). Другими словами, этот код выполняется, когда пользователь запрашивает IP-адрес или домен сервера.

Функция возвращает строку, которая затем передается обратно в тело ответа и отображается в окне браузера пользователя.

server.Run()

Эта строка отвечает за запуск сервера Martini для прослушивания запросов и маршрутизации трафика.

Сохраните и закройте файл.

После этого нужно загрузить пакет Martini, чтобы Go мог запустить только что созданную программу:

go get github.com/codegangsta/martini

Эта команда загрузит пакет в указанную точку системы, и Go в дальнейшем сможет найти его.

Запустите приложение:

go run hello.go

Martini обслуживает приложения на порте 3000. Чтобы получить доступ к приложению в браузере, укажите в ссылке IP сервера и порт:

http://your_ip:3000

На экране появится:

Hello, world!

Настройка маршрутизации и параметров

Итак, первое приложение успешно запущено. Теперь можно улучшить его работу при помощи функций маршрутизации Martini.

Данное приложение уже содержит один маршрут – это базовый URL. Эту стандартную настройку нужно изменить, чтобы приложение могло принимать ввод от пользователя.

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

Под базовым URL-адресом добавьте еще один:

. . .
server.Get("/", func() string {
return "<h1>Hello, world!</h1>"
})
server.Get("/:who", func(args martini.Params) string {
return "<h1>Hello " + args["who"] + "</h1>"
})
. . .

Новый обработчик отвечает на любой запрос, идущий за базовым URL-ом до следующего слеша. Вместо определённой URL-строки он использует заполнитель :who. Этот заполнитель является параметром, который будет принимать то значение, что пользователь ввёл после первого символа слеша.

Также следует обратить внимание на то, что объявление функции теперь принимает аргумент args типа martini.Params, что даёт доступ к параметру who.

Этот обработчик содержит такую же строку return, только доступ к параметру задаёт синтаксис args[“who”]. Это позволяет добавить значение who в строку.

Сохраните изменения и снова запустите приложение; вы можете получить доступ к странице, которая отвечает на базовый URL. Однако теперь также можно, к примеру, приветствовать пользователей по имени; для этого нужно добавить в базовый URL свое имя:

http://your_ip:3000/Peter

На экране появится:

Hello, Peter!

В строку можно внести несколько слов; для этого нужно заменить пробелы комбинацией символов %20, например:

http://your_ip:3000/is%20a%20rather%20fine%20greeting

На экране появится:

Hello is a rather fine greeting

Проксирование приложения при помощи Nginx

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

Установить Nginx можно из стандартных репозиториев Ubuntu:

sudo apt-get install nginx

Теперь нужно выполнить базовую настройку Nginx, чтобы веб-сервер передавал запросы серверу Martini.

Отредактируйте стандартный конфигурационный файл Nginx:

sudo nano /etc/nginx/sites-enabled/default

Измените директиву server_name, укажите в ней свой IP или домен.

server_name your_ip_or_domain;

Затем нужно отредактировать location /, чтобы запросы передавались на сервер Martini. Раскомментируйте раздел location / и добавьте в него новый код:

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
}

Сохраните и закройте файл.

Перезапустите сервер, чтобы обновить настройки:

sudo service nginx restart

Теперь сервер фронт-энда настроен и готов принимать соединения и передавать их приложению. Запустите программу.

Ранее для запуска программы использовался следующий синтаксис:

go run program_name

Теперь вместо этого нужно установить, чтобы иметь возможность запускать её по имени. Для этого наберите:

go install hello

Это скомпилирует и сохранит программу в каталоге ~/go/bin. Запустите программу:

hello

Это запустит сервер Martini, прослушивающий запросы на порте 3000.

Чтобы получить доступ к командной строке, нужно запустить сервер Martini в фоновом режиме. Остановите программу, нажав CTRL-C, а затем введите:

hello &

Теперь можно использовать командную строку во время работы приложения.

Введите IP или домен сервера, чтобы получить доступ к приложению. Если после домена добавить слеш и любое имя, на экране появится следующее:

http://your_ip_or_domain/John
Hello, John!

Заключение

Martini быстро обрабатывает запросы Go. Вместо постоянного переписывания всего кода Martini создаёт функции, которые логически расширяют уже существующую функциональность сервера.

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

Tags: , , , ,

Добавить комментарий