Go – это язык программирования широкого назначения, который постепенно становится одним из самых популярных языков для разработки бэкенда. Сосредоточившись на простоте, разработчики Go создали язык, который можно выучить гораздо быстрее, чем многие другие языки для разработки веб-приложений. Go предоставляет много полезных функций, среди которых параллельная обработка запросов. Благодаря этому развертывать веб-приложений на Go очень просто.
Nginx является одним из самых популярных веб-серверов в мире благодаря невысокому потреблению ресурсов и надежной обработке нагрузкой. Многие из крупнейших и наиболее активно посещаемых сайтов в Интернете обслуживаются веб-сервером Nginx. При развертывании Nginx часто используется в качестве балансировщика нагрузки или обратного прокси-сервера для повышения безопасности и ошибкоустойчивости приложения. Сочетание бэкенда Go и веб-сервера Nginx может обеспечить высокопроизводительную и быструю работу веб-приложения.
В этом мануале мы создадим веб-приложение Hello World на Go и развернем его на сервере Ubuntu 18.04, используя Nginx в качестве обратного прокси-сервера.
Требования
- Сервер Ubuntu 18.04, настроенный согласно этому мануалу.
- Предварительно установленный язык Go. Установить его поможет мануал Установка Go и настройка локальной среды разработки в Ubuntu 18.04.
- Веб-сервер Nginx. В установке вам поможет этот мануал (пропустите шаг 5 по настройке блоков server – здесь мы создадим другие блоки).
- Доменное имя, направленное на ваш сервер. В этом вам поможет мануал Как настроить имя хоста. Здесь мы используем условный домен your_domain. Домен необходим, чтобы получить доверенный SSL-сертификат, с помощью которого приложение сможет поддерживать зашифрованные соединения.
- Получите доверенный сертификат с помощью мануала Создание сертификата Let’s Encrypt для Nginx в Ubuntu 18.04. В среде производства TLS/SSL-сертификат защитит трафик веб-приложения Go.
1: Создание приложения Go
Сначала нужно создать простое веб-приложение «Hello World» на Go. Оно будет работать по домену your_domain, а по your_domain/greet/ оно будет приветствовать пользователей. Если вы хотите узнать больше об основах программирования на Go, ознакомьтесь с нашей статьей Написание простой программы Go.
Сначала создайте в вашем каталоге GOPATH новый каталог для хранения исходного файла. Вы можете назвать папку как угодно, а мы назовем ее go-web:
mkdir $GOPATH/go-web
Если следовать структуре файлов, предложенной в мануале Установка Go и настройка локальной среды разработки в Ubuntu 18.04, у этого каталога будет путь ~/go/go-web.
Затем выполните следующую команду, чтобы вернуться в каталог GOPATH:
cd $GOPATH/go-web
Используйте nano или другой текстовый редактор, чтобы создать файл main.go. Он будет содержать исходный код веб-приложения:
nano main.go
Давайте напишем функции приложения Hello World. Для этого добавьте следующий код Go в новый файл main.go:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) {
name := r.URL.Path[len("/greet/"):]
fmt.Fprintf(w, "Hello %s\n", name)
})
http.ListenAndServe(":9990", nil)
}
Теперь давайте рассмотрим данный файл подробнее.
Сначала мы написали точку входа в приложение:
package main
…
Строка package main говорит компилятору Go скомпилировать этот файл как исполняемую программу, а не как библиотеку.
Далее идут операторы import:
…
import (
"fmt"
"net/http"
)
…
Этот фрагмент импортирует модули, необходимые для работы этого кода, включая стандартный пакет fmt и пакет net/http для веб-сервера.
Следующий фрагмент создает первый маршрут в функции main, которая является точкой входа любого приложения Go:
…
func main () {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
…
}
…
func main создает родительский маршрут /, который при запросе вернет текст Hello World.
Второй маршрут, как показано в следующем фрагменте, принимает параметр URL, в данном случае имя, которое будет отображаться в приветствии.
…
func main () {
…
http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) {
name := r.URL.Path[len("/greet/"):]
fmt.Fprintf(w, "Hello %s\n", name)
})
…
}
…
При этом URL.Path сохраняет значение, которое идет сразу после /greet/, и передает значение в качестве имени из параметра URL.
Последний фрагмент создает экземпляр сервера:
…
func main () {
…
http.ListenAndServe(":9990", nil)
}
Он запускает сервер и открывает приложение через порт 9990, используя встроенный http-сервер Go.
Изучив код в файле main.go, сохраните файл и выйдите из текстового редактора.
Затем создайте двоичный исполняемый файл вашего приложения с помощью команды:
go build main.go
Предыдущая команда скомпилирует main.go и создаст исполняемый файл по имени main.
Итак, вы создали тестовое веб-приложение Go. Затем затем мы создадим системный файл systemd, чтобы приложение работало в фоновом режиме даже тогда, когда вы выйдете с сервера.
2: Создание юнит-файла systemd
На этом этапе нужно создать юнит-файл systemd, чтобы приложение работало в фоновом режиме, даже когда пользователь выходит с сервера. Это обеспечит постоянную работу сервера и сделает вас на шаг ближе к развертыванию в среде производства.
Сначала создайте новый файл goweb.service в каталоге /lib/systemd/system, используя текстовый редактор:
sudo nano /lib/systemd/system/goweb.service
Чтобы установить параметры сервиса, добавьте в файл следующие строки.
[Unit]
Description=goweb
[Service]
Type=simple
Restart=always
RestartSec=5s
ExecStart=/home/user/go/go-web/main
[Install]
WantedBy=multi-user.target
Переменная ExecStart=/home/user/go/go-web/main указывает, что точка входа для этого сервиса находится через основной исполняемый файл, расположенный в каталоге /home/user/go/go-web, где user – это пользователь sudo. Благодаря Restart=always systemd всегда будет пытаться перезапустить программу, если она остановится. Следующая строка, RestartSec=5s, устанавливает время ожидания в 5 секунд между попытками перезапуска. WantedBy=multi-user.target указывает, в каком состоянии ваш сервер включит этот сервис.
Сохраните и выйдите из файла.
Теперь, когда вы написали юнит-файл сервиса, запустите веб-сервис Go:
sudo service goweb start
Чтобы проверить, работает ли сервис, используйте следующую команду:
sudo service goweb status
Вы должны получить такой вывод:
goweb.service - goweb
Loaded: loaded (/lib/systemd/system/goweb.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2019-07-17 23:28:57 UTC; 6s ago
Main PID: 1891 (main)
Tasks: 4 (limit: 1152)
CGroup: /system.slice/goweb.service
└─1891 /home/user/go/go-web/main
Читайте также: Основы Systemd: управление сервисами и журналирование
Теперь пора настроить обратный прокси-сервер Nginx.
3: Nginx как обратный прокси-сервер
На этом этапе нужно создать блок server для Nginx и настроить его как обратный прокси-сервер, чтобы приложение стало доступно в Интернете.
Сначала перейдите в каталог sites-available:
cd /etc/nginx/sites-available
Создайте новый файл, имя которого совпадает с именем вашего домена, по которому будет работать приложение. Здесь это домен your_domain:
sudo nano your_domain
Добавьте следующие строки в файл, чтобы определить настройки для your_domain:
server {
server_name your_domain www.your_domain;
location / {
proxy_pass http://localhost:9990;
}
}
Этот блок server использует proxy_pass для обслуживания веб-приложения Go по IP-адресу localhost и по порту 9990. Строка server_name указывает домен, направленный на ваш IP-адрес (в данном случае это your_domain и www.your_domain).
Затем нужно создать симлинк для этой конфигурации Nginx в папке sites-enabled, выполнив следующую команду:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/your_domain
Симлинк – это ярлык файла Новый ярлык всегда ссылается на исходный файл и обновляется вместе с ним, учитывает все изменения. Nginx нужна копия конфигурации в обоих каталогах.
Затем обновите конфигурации Nginx, выполнив команду reload:
sudo nginx -s reload
Чтобы убедиться, что развертывание работает, перейдите на страницу http://your_domain в браузере. На странице будет текстовая строка Hello World.
Примечание: Как уже упоминалось в требованиях к мануалу, вам нужно включить SSL/TLS. Это рекомендуется сделать на данном этапе. SSL/TLS обеспечит шифрование всего трафика между приложением и его посетителями, что особенно важно, если приложение запрашивает конфиденциальную информацию (логин или пароль). Чтобы узнать, как получить бесплатный SSL-сертификат для Nginx в Ubuntu 18.04, выполните этот мануал. После получения сертификата можете продолжить работу.
Вы настроили обратный прокси-сервер Nginx. Теперь приложение обслуживается по своему домену. Также вы защитили свое веб-приложение Go с помощью шифрования SSL/TLS. Пора убедиться, что все работает правильно.
4: Тестирование приложения
Давайте откроем приложение через безопасное соединение, чтобы убедиться, что все работает.
В браузере введите:
https://your_domain
Вы получите простое сообщение Hello World. Если вы указали в URL-адресе https:// и все же получили такое сообщение, значит приложение обслуживается через защищенное соединение.
Затем попробуйте перейти по второму маршруту, https://your_domain/greet/your-name, заменив your-name любым именем, которое вы хотите увидеть в приветствии.
Приложение вернет простое приветствие, в котором будет указанное вами имя – тот параметр, переданный в URL.
Если вы получили такие результаты, поздравляем – вы успешно развернули свое веб-приложение Go.
Заключение
В этом мануале вы создали простое веб-приложение Go на основе стандартных библиотек, настроили обратный прокси-сервер Nginx и получили SSL-сертификат для защиты своего приложения. Чтобы узнать больше о Go, читайте официальную документацию. Кроме того, вы можете узнать больше о программировании на Go в нашем Информатории.