GolangプロダクションWebアプリケーションの構成


120

本番環境でGoバックエンドを実行している場合:

Go Webアプリケーションを実行するためのスタック/構成は何ですか?

サーバーの稼働を維持するために標準ライブラリnet / httpパッケージを使用している人以外は、このトピックについてはあまり知りません。Nginxを使用してリクエストをGoサーバーに渡す-Go with nginx

これは少し壊れやすいようです。たとえば、マシンが再起動された場合(追加の構成スクリプトなしで)、サーバーは自動的に再起動しませんでした。

より確かな生産体制はありますか?

余談ですが、次のプロジェクトのためにGo搭載のRESTバックエンドサーバーを計画しており、多額の投資をする前に、Goがプロジェクトをライブで実行できるようにしたいと考えています。


3
「マシンが再起動された場合(追加の構成スクリプトなしで)サーバーは自動的に再起動しませんでした。」これはできるとは思いません。理想的には、サービスのinit / systemd / upstartスクリプトを作成します。これは、UNIXデーモンを制御するための推奨される方法です。
Intermernet 2013

その通りその通り。インストール時にこれらの機能を自動的にセットアップするapacheなどのサーバーとは対照的に、それを意味していると思います。
Chaseph 2013

回答:


134

Goプログラムはポート80でリッスンし、HTTPリクエストを直接処理できます。代わりに、Goプログラムの前でリバースプロキシを使用して、ポート80でリッスンし、ポート(たとえば4000)でプログラムに接続することができます。後者を実行する理由はたくさんあります。実行する必要がないからです。ルートとしてGoプログラム、同じホスト上で他のウェブサイト/サービスを提供、SSL終了、負荷分散、ロギングなど

HAProxyを使用していますは前で。リバースプロキシはすべて機能します。Nginxも優れたオプションです(HAProxyよりもはるかに人気があり、より多くのことが可能です)。

HAProxyのドキュメントHTMLバージョン)を読むと、設定が非常に簡単です。haproxy.cfg開始点が必要な場合に備えて、私のGoプロジェクトの1つのファイル全体が続きます。

global
        log     127.0.0.1       local0
        maxconn 10000
        user    haproxy
        group   haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend http
        bind :80
        acl  is_stats  hdr(host)       -i      hastats.myapp.com
        use_backend    stats   if      is_stats
        default_backend        myapp
        capture        request header Host     len     20
        capture        request header Referer  len     50

backend myapp
        server  main    127.0.0.1:4000

backend stats
       mode     http
       stats    enable
       stats    scope   http
       stats    scope   myapp
       stats    realm   Haproxy\ Statistics
       stats    uri     /
       stats    auth    username:password

Nginxはさらに簡単です。

サービスコントロールに関しては、Goプログラムをシステムサービスとして実行しています。みんなそうだと思います。私のサーバーはUbuntuを実行しているため、Upstartを使用しています。私はこれ/etc/init/myapp.confをUpstartが私のプログラムを制御するために入れました:

start on runlevel [2345]
stop on runlevel [!2345]

chdir /home/myapp/myapp
setgid myapp
setuid myapp
exec ./myapp start 1>>_logs/stdout.log 2>>_logs/stderr.log

別の側面は展開です。1つのオプションは、プログラムのバイナリファイルと必要なアセットを送信するだけでデプロイすることです。これは非常に優れたソリューションIMOです。私は他のオプションを使用します:サーバーでコンパイルします。(いわゆる「継続的インテグレーション/デプロイメント」システムをセットアップするときに、バイナリファイルを使用したデプロイメントに切り替えます。)

サーバーの小さなシェルスクリプトを使用して、リモートGitリポジトリからプロジェクトのコードをプルし、Goでビルドして、バイナリやその他のアセットを ~/myapp/に、サービスを再起動します。

全体として、他のサーバー設定と全体的にそれほど違いはありません。コードを実行してHTTPリクエストを処理する方法が必要です。実際には、Goはこのようなものに対して非常に安定していることが証明されています。


9
正解です。推奨される基本的なセットアップに必要なすべての良い例。
Intermernet 2013

ログのローテーションについてはどうしますか?これが、私が監視プログラムを使用する唯一の理由ですが、あまりにも多くのログが発生している場合には問題があります。
fiorix 2013年

@fiorix、ログローテーションに関する別のSO質問を開くことができると確信していますが、UNIXを使用していて標準ツールを使用したい場合は、logrotateを確認してください:linuxcommand.org/man_pages/logrotate8.html。これは、よく知られたサービス(apache、yumなど)の多くで使用されており、かなり簡単に構成できます。
Doody P

Goで独自のリバースプロキシを作成するのはどれほど簡単でしょうか。これはnginxやhaproxyを使用するよりもかなり悪い考えでしょうか?つまり、Goには優れたHTTP / HTTPS / HTTP / 2サポートが付属しています。
thomasrutter 2017年

58

nginx for:

  • GoアプリケーションへのリバースHTTPプロキシ
  • 静的ファイルの処理
  • SSL終了
  • HTTPヘッダー(Cache-Controlなど)
  • アクセスログ(したがって、システムログのローテーションを活用)
  • 書き換え(wwwにネイキッド、http://からhttps://になど)

nginxはこれを非常に簡単にします。Goから直接サービスを提供できますがnet/http、「ホイールの再発明」が多く、グローバルHTTPヘッダーなどには、おそらく回避できるボイラープレートが含まれます。

監督Goバイナリの管理を。UbuntuのUpstart(Mostafaによる言及)も良いですが、比較的分散的であり、十分に文書化されているため、私は監視プログラムが好きです。

監督、私にとって:

  • 必要に応じてGoバイナリを実行します
  • クラッシュ後にそれを表示します
  • 環境変数(セッション認証キーなど)を単一の構成の一部として保持します。
  • 私のDBを実行します(私のGoバイナリがそれなしで実行されていないことを確認するため)

8

シンプルなgoアプリをデーモンとして実行したい場合は、Upstartの代わりにsystemd(多くのLinuxディストリビューションでサポートされています)を使用してください。

でサービスファイルを作成します

touch /etc/systemd/system/my-go-daemon.service

入る

[Unit]
Description=My Go App

[Service]
Type=simple
WorkingDirectory=/my/go/app/directory
ExecStart=/usr/lib/go run main.go 

[Install]
WantedBy=multi-user.target

次に、サービスを有効にして開始します

systemctl enable my-go-daemon
systemctl start my-go-daemon
systemctl status my-go-daemon

systemdには個別のジャーナリングシステムがあり、ログを追跡してトラブルシューティングを簡単に行うことができます。


5

バイナリをソケットを使用してインターネットドメインの特権ポート(1024未満のポート番号)にバインドできます。 setcap

setcap 'cap_net_bind_service=+ep' /path/to/binary

  1. このコマンドはエスカレートする必要があります。sudo必要に応じて
  2. プログラムの新しいバージョンごとに新しいバイナリが生成されるため、次の方法で再認証する必要があります。 setcap

setcap ドキュメンテーション

cap_net_bind_service ドキュメンテーション

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.