Golang üretim web uygulaması yapılandırması


120

Üretimde arka uçlara git çalıştıranlar için:

Go web uygulamasını çalıştırmak için yığınınız / yapılandırmanız nedir?

Bir sunucuyu çalışır durumda tutmak için standart kütüphane net / http paketini kullananların yanı sıra bu konuda pek bir şey görmedim. İstekleri bir Go sunucusuna iletmek için Nginx kullanarak okudum - Go ile nginx

Bu bana biraz kırılgan geliyor. Örneğin, makine yeniden başlatılırsa (ek yapılandırma komut dosyaları olmadan) sunucu otomatik olarak yeniden başlamaz.

Daha sağlam bir üretim düzeni var mı?

Niyetim bir yana - Bir sonraki projem için Go destekli bir REST arka uç sunucusu planlıyorum ve projeye çok fazla yatırım yapmadan önce Go'nun projeyi canlı olarak başlatmak için uygun olduğundan emin olmak istiyorum.


3
"makine yeniden başlatıldıysa (ek yapılandırma komut dosyaları olmadan) sunucu otomatik olarak yeniden başlamaz." Bunun yapılabileceğini sanmıyorum. İdeal olarak hizmet için init / systemd / upstart betikleri oluşturmuştunuz. Bu, herhangi bir unix daemon'un kontrol edilmesi için önerilen yoldur.
Intermernet

Haklısın. Sanırım bunu, yükleme sırasında bu özellikleri otomatik olarak ayarlayan apache gibi bir sunucunun aksine kastettim.
Chaseph

Yanıtlar:


134

Go programları 80 numaralı bağlantı noktasını dinleyebilir ve HTTP isteklerini doğrudan sunabilir. Bunun yerine, Go programınızın önünde bir ters proxy kullanmak isteyebilirsiniz, böylece program 80 numaralı bağlantı noktasını dinler ve programınıza bağlantı noktası, örneğin 4000 üzerinden bağlanır. İkincisini yapmanın birçok nedeni vardır: çalıştırmak zorunda olmamak Go programınız kök olarak, aynı ana bilgisayarda başka web sitelerine / hizmetlere hizmet veriyor, SSL sonlandırma, yük dengeleme, günlük kaydı vb.

Önde HAProxy kullanıyorum . Herhangi bir ters proxy çalışabilir. Nginx aynı zamanda harika bir seçenektir (HAProxy'den çok daha popülerdir ve daha fazlasını yapabilir).

Belgelerini ( HTML sürümü ) okursanız, HAProxy'nin yapılandırılması çok kolaydır . haproxy.cfgBaşlangıç ​​pontuna ihtiyacınız olması durumunda, Go projelerimden biri için tüm dosyam aşağıdaki gibidir.

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 daha da kolay.

Servis kontrolü ile ilgili olarak, Go programımı bir sistem servisi olarak çalıştırıyorum. Bence bunu herkes yapıyor. Sunucum Ubuntu'yu çalıştırdığı için Upstart kullanıyor. Bunu /etc/init/myapp.confUpstart'ın programımı kontrol etmesi için koydum :

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

Diğer bir husus da konuşlandırmadır. Seçeneklerden biri, programın ikili dosyasını ve gerekli varlıkları göndererek dağıtmaktır. Bu oldukça harika bir çözüm IMO. Diğer seçeneği kullanıyorum: sunucuda derleme. (Sözde “Sürekli Entegrasyon / Dağıtım” sistemi kurduğumda ikili dosyalarla dağıtıma geçeceğim.)

Sunucuda, projem için uzaktaki bir Git deposundan kod çeken, Go ile oluşturan, ikili dosyaları ve diğer varlıkları kopyalayan ~/myapp/ve hizmeti yeniden başlatan küçük bir kabuk betiğim var .

Genel olarak, her şey diğer herhangi bir sunucu kurulumundan çok farklı değildir: kodunuzu çalıştırmanın ve HTTP isteklerine hizmet etmesini sağlamanın bir yolunu bulmanız gerekir. Pratikte, Go bu tür şeyler için çok kararlı olduğunu kanıtladı.


9
Mükemmel cevap! Önerilen bir temel kurulum için gereken her şeyin iyi örnekleri.
Intermernet

Günlük döndürme konusunda ne yaparsınız? Süpervizör kullanmamın neredeyse tek nedeni bu, ancak çok fazla oturum açıldığında acı çekiyor.
fiorix

@fiorix, log rotasyonu hakkında farklı bir SO sorusu açabileceğinizden oldukça eminim, ancak yine de unix kullanıyorsanız ve standart araçları kullanmak istiyorsanız, logrotate: linuxcommand.org/man_pages/logrotate8.html adresine bakın . Bu, iyi bilinen hizmetlerin çoğu (apache, yum, vb.) Tarafından kullanılır ve yapılandırılması oldukça kolaydır.
Doody P

Go'da kendi ters proxy'nizi oluşturmak ne kadar kolay olurdu? Bu, nginx veya haproxy kullanmaktan çok daha kötü bir fikir olabilir mi? Demek istediğim, Go harika HTTP / HTTPS / HTTP / 2 desteğiyle geliyor.
thomasrutter

58

nginx için:

  • Go uygulamama HTTP proxy'sini ters çevir
  • Statik dosya işleme
  • SSL sonlandırma
  • HTTP üstbilgileri (Cache-Control, vb.)
  • Günlüklere erişim (ve dolayısıyla sistem günlüğü rotasyonundan yararlanma)
  • Yeniden yazmalar (www, http: //, https: //, vb.)

nginx bunu çok kolaylaştırır ve doğrudan Go sayesinde hizmet verebilmenize rağmen net/http, birçok "tekerleği yeniden icat etme" vardır ve global HTTP başlıkları gibi şeyler muhtemelen kaçınabileceğiniz bazı standart metinler içerir.

Go ikili programımı yönetmek için süpervizör . Ubuntu'nun Upstart'ı (Mostafa tarafından belirtildiği gibi) da iyidir, ancak nispeten distro-agnostik olduğu ve iyi belgelendiği için süpervizörü severim.

Supervisord, benim için:

  • Go ikili programımı gerektiği gibi çalıştırır
  • Bir çarpışmadan sonra ortaya çıkarır
  • Çevresel değişkenlerimi (oturum kimlik doğrulama anahtarları vb.) Tek bir yapılandırmanın parçası olarak tutar.
  • DB'mi çalıştırır (Go ikili programımın onsuz çalışmadığından emin olmak için)

8

Bir arka plan programı olarak çalışan basit bir go uygulaması isteyenler için , Upstart yerine systemd (birçok linux dağıtımı tarafından desteklenir) kullanın.

Adresinde bir servis dosyası oluşturun

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

Giriş

[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

Ardından hizmeti etkinleştirin ve başlatın

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

systemd, kolay sorun giderme için günlükleri takip etmenizi sağlayacak ayrı bir günlük tutma sistemine sahiptir.


5

İkili programınızı bir sokete İnternet etki alanı ayrıcalıklı bağlantı noktalarına (1024'ten küçük bağlantı noktası numaraları) kullanarak bağlayabilirsiniz. setcap

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

  1. Bu komutun yükseltilmesi gerekiyor. sudogerektiği gibi
  2. Programınızın her yeni sürümü, tarafından yeniden yetkilendirilmesi gereken yeni bir ikili dosyayla sonuçlanacaktır. setcap

setcap belgeleme

cap_net_bind_service belgeleme

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.