การกำหนดค่าเว็บแอปพลิเคชันการผลิต Golang


120

สำหรับผู้ที่ใช้ Go แบ็กเอนด์ในการผลิต:

สแต็ก / การกำหนดค่าของคุณสำหรับการเรียกใช้แอปพลิเคชันเว็บ Go คืออะไร?

ฉันไม่ค่อยเห็นหัวข้อนี้มากนักนอกจากคนที่ใช้แพ็คเกจ net / http ของไลบรารีมาตรฐานเพื่อให้เซิร์ฟเวอร์ทำงานต่อไป ฉันอ่านโดยใช้ Nginx เพื่อส่งคำขอไปยังเซิร์ฟเวอร์ Go - nginx with Go

สิ่งนี้ดูเหมือนจะเปราะบางสำหรับฉัน ตัวอย่างเช่นเซิร์ฟเวอร์จะไม่รีสตาร์ทโดยอัตโนมัติหากเครื่องรีสตาร์ท (โดยไม่มีสคริปต์การกำหนดค่าเพิ่มเติม)

มีการตั้งค่าการผลิตที่มั่นคงกว่านี้หรือไม่?

นอกเหนือจากความตั้งใจของฉัน - ฉันกำลังวางแผนที่จะใช้เซิร์ฟเวอร์แบ็กเอนด์ Go ที่ขับเคลื่อนด้วย REST สำหรับโปรเจ็กต์ถัดไปของฉันและต้องการให้แน่ใจว่า Go จะทำงานได้จริงสำหรับการเปิดตัวโปรเจ็กต์จริงก่อนที่ฉันจะลงทุนกับมันมากเกินไป


3
"เซิร์ฟเวอร์จะไม่รีสตาร์ทโดยอัตโนมัติหากเครื่องรีสตาร์ท (โดยไม่มีสคริปต์การกำหนดค่าเพิ่มเติม)" ไม่คิดว่าจะทำได้ ตามหลักการแล้วคุณจะสร้างสคริปต์ init / systemd / upstart สำหรับบริการ นี่เป็นวิธีที่แนะนำสำหรับการควบคุม unix daemon
Intermernet

ใช่คุณเป็น ฉันเดาว่าฉันหมายถึงมันตรงกันข้ามกับเซิร์ฟเวอร์เช่น apache ที่ตั้งค่าคุณสมบัติเหล่านั้นโดยอัตโนมัติในเวลาติดตั้ง
Chaseph

คำตอบ:


134

โปรแกรม Go สามารถฟังบนพอร์ต 80 และตอบสนองคำขอ HTTP ได้โดยตรง คุณอาจต้องการใช้ reverse proxy หน้าโปรแกรม Go ของคุณแทนเพื่อให้มันฟังพอร์ต 80 และเชื่อมต่อกับโปรแกรมของคุณบนพอร์ตกล่าวว่า 4000 มีหลายเหตุผลในการดำเนินการอย่างหลัง: ไม่ต้องรัน โปรแกรม Go ของคุณเป็นรูทให้บริการเว็บไซต์ / บริการอื่น ๆ บนโฮสต์เดียวกันการยุติ SSL การโหลดบาลานซ์การบันทึก ฯลฯ

ฉันใช้HAProxyอยู่ข้างหน้า พร็อกซีย้อนกลับใด ๆ สามารถทำงานได้ Nginx เป็นตัวเลือกที่ยอดเยี่ยมเช่นกัน (เป็นที่นิยมมากกว่า HAProxy และสามารถทำอะไรได้มากกว่านี้)

HAProxy นั้นง่ายมากในการกำหนดค่าหากคุณอ่านเอกสารประกอบ ( เวอร์ชัน HTML ) haproxy.cfgไฟล์ทั้งหมดของฉันสำหรับหนึ่งในโปรเจ็กต์ Go ของฉันมีดังต่อไปนี้ในกรณีที่คุณต้องการเริ่มต้น

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

อีกประการหนึ่งคือการปรับใช้ ทางเลือกหนึ่งคือการปรับใช้โดยเพียงแค่ส่งไฟล์ไบนารีของโปรแกรมและทรัพย์สินที่จำเป็น นี่เป็นทางออกที่ยอดเยี่ยมมาก IMO ฉันใช้ตัวเลือกอื่น: คอมไพล์บนเซิร์ฟเวอร์ (ฉันจะเปลี่ยนไปใช้การปรับใช้กับไฟล์ไบนารีเมื่อฉันตั้งค่าระบบ“ การรวม / การปรับใช้อย่างต่อเนื่อง”)

ฉันมีเชลล์สคริปต์ขนาดเล็กบนเซิร์ฟเวอร์ที่ดึงโค้ดสำหรับโปรเจ็กต์ของฉันจากที่เก็บ Git ระยะไกลสร้างด้วย Go คัดลอกไบนารีและเนื้อหาอื่น ๆ ไปยัง~/myapp/และเริ่มบริการใหม่

โดยรวมแล้วสิ่งทั้งหมดไม่แตกต่างจากการตั้งค่าเซิร์ฟเวอร์อื่น ๆ มากนัก: คุณต้องมีวิธีเรียกใช้รหัสของคุณและให้มันตอบสนองคำขอ HTTP ในทางปฏิบัติ Go ได้พิสูจน์แล้วว่ามีความเสถียรมากสำหรับสิ่งนี้


9
ตอบโจทย์มาก! ตัวอย่างที่ดีของทุกสิ่งที่จำเป็นสำหรับการตั้งค่าพื้นฐานที่แนะนำ
Intermernet

คุณทำอะไรเกี่ยวกับการหมุนบันทึก? นั่นเป็นเหตุผลเดียวที่ทำให้ฉันใช้หัวหน้างาน แต่มันมีปัญหาเมื่อมีการบันทึกมากเกินไป
fiorix

@fiorix ฉันรักแน่ใจว่าคุณสามารถเปิดเป็นคำถามที่แตกต่างกันดังนั้นเกี่ยวกับการหมุนเวียนเข้าสู่ระบบ แต่ยังคงถ้าคุณอยู่ในยูนิกซ์และต้องการใช้เครื่องมือมาตรฐานตรวจสอบ logrotate: linuxcommand.org/man_pages/logrotate8.html สิ่งนี้ถูกใช้โดยบริการที่รู้จักกันดีหลายอย่าง (apache, yum ฯลฯ ) และค่อนข้างง่ายในการกำหนดค่า
Doody P

การสร้างพร็อกซีย้อนกลับของคุณเองใน Go นั้นง่ายแค่ไหน? นี่จะเป็นความคิดที่แย่กว่าการใช้ nginx หรือ haproxy หรือไม่? ฉันหมายความว่า Go มาพร้อมกับการสนับสนุน HTTP / HTTPS / HTTP / 2 ที่ยอดเยี่ยม
thomasrutter

58

nginx สำหรับ:

  • ย้อนกลับพร็อกซี HTTP ไปยังแอปพลิเคชัน Go ของฉัน
  • การจัดการไฟล์แบบคงที่
  • การสิ้นสุด SSL
  • ส่วนหัว HTTP (Cache-Control, et. al)
  • บันทึกการเข้าถึง (ดังนั้นจึงใช้ประโยชน์จากการหมุนเวียนบันทึกระบบ)
  • เขียนใหม่ (เปล่าไปยัง www, http: // ถึง https: // ฯลฯ )

nginx ทำให้สิ่งนี้ง่ายมากและแม้ว่าคุณจะสามารถให้บริการได้โดยตรงจาก Go ต้องขอบคุณnet/httpแต่ก็มี "การประดิษฐ์วงล้อขึ้นใหม่" มากมายและสิ่งต่างๆเช่นส่วนหัว HTTP ทั่วโลกเกี่ยวข้องกับแผ่นสำเร็จรูปบางอย่างที่คุณอาจหลีกเลี่ยงได้

หัวหน้างานสำหรับจัดการ Go binary ของฉัน Upstart ของ Ubuntu (ตามที่ Mostafa กล่าวถึง) ก็ดีเช่นกัน แต่ฉันชอบหัวหน้างานเพราะมันค่อนข้างไม่เชื่อเรื่องพระเจ้าและมีการบันทึกไว้อย่างดี

หัวหน้างานสำหรับฉัน:

  • รันไบนารี Go ของฉันตามต้องการ
  • นำมันขึ้นมาหลังจากความผิดพลาด
  • เก็บตัวแปรสภาพแวดล้อมของฉัน (คีย์การตรวจสอบสิทธิ์เซสชัน ฯลฯ ) เป็นส่วนหนึ่งของการกำหนดค่าเดียว
  • เรียกใช้ฐานข้อมูลของฉัน (เพื่อให้แน่ใจว่าไบนารี Go ของฉันไม่ทำงานหากไม่มี)

8

สำหรับผู้ที่ต้องการแอป go แบบธรรมดาที่รันเป็น daemon ให้ใช้systemd (รองรับโดย linux distros จำนวนมาก) แทน 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 มีระบบบันทึกประจำวันแยกต่างหากซึ่งจะช่วยให้คุณสามารถบันทึกข้อมูลเพื่อการแก้ไขปัญหาได้ง่าย


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.