web-dev-qa-db-ja.com

Golang実動Webアプリケーションの構成

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

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

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

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

より安定した生産セットアップはありますか?

私の意図はさておき-私は次のプロジェクトのためにGoを利用したRESTバックエンドサーバーを計画しており、投資する前にGoがプロジェクトをライブで実行できることを確認したいそれに多く。

116
Chaseph

Goプログラムはポート80でリッスンし、HTTP要求を直接処理できます。代わりに、Goプログラムの前でリバースプロキシを使用して、ポート80でリッスンし、ポート4000でプログラムに接続することができます。後者を行う理由はたくさんあります。 Goプログラムをルートとして使用し、同じホスト上で他のWebサイト/サービスを提供する、SSL終了、ロードバランシング、ロギングなど.

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

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

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を使用します。 Upstartがプログラムを制御するために、これを/etc/init/myapp.confに配置しました。

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はこのようなものに対して非常に安定していることが証明されています。

131
Mostafa

nginxの場合:

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

nginxはこれを非常に簡単にします。ただし、net/http、多くの「車輪の再発明」があり、グローバルHTTPヘッダーのようなものには、おそらく避けることができる定型的なものが含まれます。

supervisord Goバイナリの管理用。 UbuntuのUpstart(Mostafaが言及)も優れていますが、比較的知られず、よく文書化されているため、supervisordが好きです。

スーパーバイザー、私にとって:

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

単純な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には、トラブルシューティングを容易にするためにログを追跡できる独立したジャーナリングシステムがあります。

6
mixdev

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

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

  1. このコマンドはエスカレートする必要があります。 Sudo必要に応じて
  2. プログラムのすべての新しいバージョンは、setcapによる再認証が必要な新しいバイナリになります。

setcap documentation

cap_net_bind_serviceドキュメント

4
Emperor_Earth