2013-07-03 78 views
109

對於那些在生產中運行Go後端的人:Golang生產web應用程序配置

運行Go web應用程序的堆棧/配置是什麼?

除了使用標準庫net/http包來保持服務器運行的人之外,我對這個主題還沒有看到太多內容。我讀了使用Nginx將請求傳遞給Go服務器 - nginx with Go

這對我來說似乎有點脆弱。例如,如果機器重新啓動(沒有附加配置腳本),服務器不會自動重新啓動。

是否有更穩固的生產設置?

除了我的意圖 - 我計劃爲我的下一個項目提供一個Go動力的REST後端服務器,並且希望確保Go在我投入太多資金之前實時啓動項目。

+1

「如果機器重新啓動(不需要額外的配置腳本),服務器不會自動重啓。」我不認爲這可以做到。理想情況下,您已經爲該服務創建了init/systemd/upstart腳本。這是任何unix守護進程被控制的推薦方式。 – Intermernet

+0

你是對的。我想我的意思是與apache等服務器相反,它會在安裝時自動設置這些功能。 – Chaseph

回答

127

Go程序可以偵聽端口80並直接提供HTTP請求。相反,您可能希望在Go程序前面使用反向代理,以便在端口80上偵聽,並在端口4000上連接到您的程序。執行後者的原因很多:無需運行您的Go程序作爲root用戶,在同一主機上提供其他網站/服務,SSL終止,負載平衡,日誌記錄等。

我在前面使用HAProxy。任何反向代理都可以工作。 Nginx也是一個不錯的選擇(比HAProxy更受歡迎,能夠做更多)。

如果您閱讀其documentationHTML version),HAProxy配置非常簡單。我的一個Go項目的整個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。我已經把這個在/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 

另一個方面是部署。一種選擇是通過發送程序的二進制文件和必要的資源進行部署。這是一個非常好的IMO解決方案。我使用其他選項:在服務器上編譯。 (當我建立所謂的「持續集成/部署」系統時,我將切換到使用二進制文件進行部署。)

我在服務器上有一個小型shell腳本,它從遠程Git使用Go進行構建,將二進制文件和其他資產複製到~/myapp/,然後重新啓動服務。總的來說,整個事情與任何其他服務器設置並沒有太大的不同:你必須有一種方法來運行你的代碼,並讓它服務於HTTP請求。在實踐中,Go被證明對這個東西非常穩定。

+7

很好的回答!推薦的基本設置所需的一切的好例子。 – Intermernet

+0

你對日誌輪換做什麼?這幾乎是我使用supervisord的唯一原因,但是當日志過多時會受到影響。 – fiorix

+0

@fiorix,我敢肯定你可以打開一個關於日誌旋轉的不同的SO問題,但是如果你使用的是unix並且想要使用標準工具,請查看logrotate:http://linuxcommand.org/man_pages/logrotate8。 HTML。許多衆所周知的服務(apache,yum等)都使用它,並且配置起來相當簡單。 –

56

nginx的爲:

  • 反向HTTP代理,我去申請
  • 靜態文件處理
  • SSL終止
  • HTTP標頭(緩存控制,等)
  • 訪問日誌(並且因此利用系統日誌旋轉)
  • 重寫(裸到www,http://到https://等)

nginx使這個非常容易,儘管你可以直接從Go提供服務,這要歸功於net/http,還有很多「重新發明輪子」,像全局HTTP頭等東西涉及一些你可能會避免的樣板文件。

supervisord用於管理我的Go二進制文件。 Ubuntu的Upstart(正如Mostafa所提到的)也很好,但是我喜歡supervisord,因爲它相對不受啓發,並且有很好的文檔記錄。

Supervisord,對我來說:

  • 運行需要我去二進制
  • 崩潰
  • 握住我的環境變量(會話身份驗證密鑰等)作爲一個單一的一部分後主動提起配置。
  • 運行我的數據庫(以確保我的圍棋二進制是不是沒有它運行)
4

您可以使用二進制綁定一個套接字到互聯網域名特權端口(小於1024的端口號)setcap

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

  1. 這個命令需要進行升級。 sudo必要
  2. 程序的每一個新版本將導致一個新的二進制文件,將需要通過setcap

setcap documentation

cap_net_bind_service documentation

2

重新授權對於那些誰想要簡單的去應用程序運行作爲一個守護進程,使用systemd(由許多Linux發行版支持)而不是Upstart。

創建於

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有獨立的日誌系統,可以讓你的尾巴日誌簡單的故障排除。

相關問題