部署 Go 項目的 N 種方法

Go 語言(Golang)以其簡單、高效和易于部署的特點,成為了很多企業開發和部署服務的首選語言。無論是微服務架構,還是命令行工具,Go 的編譯方式和標準庫使得部署變得更加輕松。本文將介紹部署 Go 語言項目的幾種常見方法,以幫助開發者根據不同的需求選擇合適的部署方案。

本文以部署 Go Web 程序為例,介紹了在 CentOS7 服務器上部署 Go 語言程序的若干方法。

獨立部署

Go 語言支持跨平臺交叉編譯,也就是說我們可以在 Windows 或 Mac 平臺下編寫代碼,并且將代碼編譯成能夠在 Linux amd64 服務器上運行的程序。

對于簡單的項目,通常我們只需要將編譯后的二進制文件拷貝到服務器上,然后設置為后臺守護進程運行即可。

編譯

編譯可以通過以下命令或編寫 makefile 來操作。

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/bluebell

下面假設我們將本地編譯好的 bluebell 二進制文件、配置文件和靜態文件等上傳到服務器的/data/app/bluebell目錄下。

補充一點,如果嫌棄編譯后的二進制文件太大,可以在編譯的時候加上-ldflags "-s -w"參數去掉符號表和調試信息,一般能減小 20% 的大小。

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o ./bin/bluebell

如果還是嫌大的話可以繼續使用 upx 工具對二進制可執行文件進行壓縮。

我們編譯好 bluebell 項目后,相關必要文件的目錄結構如下:

├── bin
│   └── bluebell
├── conf
│   └── config.yaml
├── static
│   ├── css
│   │   └── app.0afe9dae.css
│   ├── favicon.ico
│   ├── img
│   │   ├── avatar.7b0a9835.png
│   │   ├── iconfont.cdbe38a0.svg
│   │   ├── logo.da56125f.png
│   │   └── search.8e85063d.png
│   └── js
│       ├── app.9f3efa6d.js
│       ├── app.9f3efa6d.js.map
│       ├── chunk-vendors.57f9e9d6.js
│       └── chunk-vendors.57f9e9d6.js.map
└── templates└── index.html

nohup

nohup 用于在系統后臺不掛斷地運行命令,不掛斷指的是退出執行命令的終端也不會影響程序的運行。

我們可以使用 nohup 命令來運行應用程序,使其作為后臺守護進程運行。由于在主流的 Linux 發行版中都會默認安裝 nohup 命令工具,我們可以直接輸入以下命令來啟動我們的項目:

sudo nohup ./bin/bluebell conf/config.yaml > nohup_bluebell.log 2>&1 &

其中:

  • ./bluebell conf/config.yaml是我們應用程序的啟動命令
  • nohup ... &表示在后臺不掛斷的執行上述應用程序的啟動命令
  • > nohup_bluebell.log表示將命令的標準輸出重定向到 nohup_bluebell.log 文件
  • 2>&1表示將標準錯誤輸出也重定向到標準輸出中,結合上一條就是把執行命令的輸出都定向到 nohup_bluebell.log 文件

上面的命令執行后會返回進程 id

[1] 6338

當然我們也可以通過以下命令查看 bluebell 相關活動進程:

ps -ef | grep bluebell

輸出:

root      6338  4048  0 08:43 pts/0    00:00:00 ./bin/bluebell conf/config.yaml
root      6376  4048  0 08:43 pts/0    00:00:00 grep --color=auto bluebell

此時就可以打開瀏覽器輸入http:// 服務器公網 ip: 端口查看應用程序的展示效果了。

supervisor

Supervisor 是業界流行的一個通用的進程管理程序,它能將一個普通的命令行進程變為后臺守護進程,并監控該進程的運行狀態,當該進程異常退出時能將其自動重啟。

首先使用 yum 來安裝 supervisor:

如果你還沒有安裝過 EPEL,可以通過運行下面的命令來完成安裝,如果已安裝則跳過此步驟:

sudo yum install epel-release

安裝 supervisor

sudo yum install supervisor

Supervisor 的配置文件為:/etc/supervisord.conf ,Supervisor 所管理的應用的配置文件放在 /etc/supervisord.d/ 目錄中,這個目錄可以在 supervisord.conf 中的include配置。

[include]
files = /etc/supervisord.d/*.conf

啟動 supervisor 服務:

sudo supervisord -c /etc/supervisord.conf

我們在/etc/supervisord.d目錄下創建一個名為bluebell.conf的配置文件,具體內容如下。

[program:bluebell]  ;程序名稱
user=root  ;執行程序的用戶
command=/data/app/bluebell/bin/bluebell /data/app/bluebell/conf/config.yaml  ;執行的命令
directory=/data/app/bluebell/ ;命令執行的目錄
stopsignal=TERM  ;重啟時發送的信號
autostart=true  
autorestart=true  ;是否自動重啟
stdout_logfile=/var/log/bluebell-stdout.log  ;標準輸出日志位置
stderr_logfile=/var/log/bluebell-stderr.log  ;標準錯誤日志位置

創建好配置文件之后,重啟 supervisor 服務

sudo supervisorctl update

查看 bluebell 的運行狀態:

sudo supervisorctl status bluebell

輸出:

bluebell                         RUNNING   pid 10918, uptime 0:05:46

最后補充一下常用的 supervisr 管理命令:

supervisorctl status       
supervisorctl shutdown     
supervisorctl start 程序名  
supervisorctl stop 程序名   
supervisorctl reload

接下來就是打開瀏覽器查看網站是否正常了。

搭配 nginx 部署

在需要靜態文件分離、需要配置多個域名及證書、需要自建負載均衡層等稍復雜的場景下,我們一般需要搭配第三方的 web 服務器(Nginx、Apache)來部署我們的程序。

正向代理與反向代理

正向代理可以簡單理解為客戶端的代理,你訪問墻外的網站用的那個屬于正向代理。

反向代理可以簡單理解為服務器的代理,通常說的 Nginx 和 Apache 就屬于反向代理。

Nginx 是一個免費的、開源的、高性能的 HTTP 和反向代理服務,主要負責負載一些訪問量比較大的站點。Nginx 可以作為一個獨立的 Web 服務,也可以用來給 Apache 或是其他的 Web 服務做反向代理。相比于 Apache,Nginx 可以處理更多的并發連接,而且每個連接的內存占用的非常小。

使用 yum 安裝 nginx

EPEL 倉庫中有 Nginx 的安裝包。如果你還沒有安裝過 EPEL,可以通過運行下面的命令來完成安裝:

sudo yum install epel-release

安裝 nginx

sudo yum install nginx

安裝完成后,執行下面的命令設置 Nginx 開機啟動:

sudo systemctl enable nginx

啟動 Nginx

sudo systemctl start nginx

查看 Nginx 運行狀態:

sudo systemctl status nginx

Nginx 配置文件

通過上面的方法安裝的 nginx,所有相關的配置文件都在 /etc/nginx/ 目錄中。Nginx 的主配置文件是 /etc/nginx/nginx.conf

默認還有一個nginx.conf.default的配置文件示例,可以作為參考。你可以為多個服務創建不同的配置文件(建議為每個服務(域名)創建一個單獨的配置文件),每一個獨立的 Nginx 服務配置文件都必須以 .conf結尾,并存儲在 /etc/nginx/conf.d 目錄中。

Nginx 常用命令

補充幾個 Nginx 常用命令。

nginx -s stop    
nginx -s reload  
nginx -s quit    
nginx -t

Nginx 反向代理部署

我們推薦使用 nginx 作為反向代理來部署我們的程序,按下面的內容修改 nginx 的配置文件。

worker_processes  1;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       80;server_name  localhost;access_log   /var/log/bluebell-access.log;error_log    /var/log/bluebell-error.log;location / {proxy_pass                 http://127.0.0.1:8084;proxy_redirect             off;proxy_set_header           Host             $host;proxy_set_header           X-Real-IP        $remote_addr;proxy_set_header           X-Forwarded-For  $proxy_add_x_forwarded_for;}}
}

執行下面的命令檢查配置文件語法:

nginx -t

執行下面的命令重新加載配置文件:

nginx -s reload

接下來就是打開瀏覽器查看網站是否正常了。

當然我們還可以使用 nginx 的 upstream 配置來添加多個服務器地址實現負載均衡。

worker_processes  1;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;upstream backend {server 127.0.0.1:8084;}server {listen       80;server_name  localhost;access_log   /var/log/bluebell-access.log;error_log    /var/log/bluebell-error.log;location / {proxy_pass                 http://backend/;proxy_redirect             off;proxy_set_header           Host             $host;proxy_set_header           X-Real-IP        $remote_addr;proxy_set_header           X-Forwarded-For  $proxy_add_x_forwarded_for;}}
}

Nginx 分離靜態文件請求

上面的配置是簡單的使用 nginx 作為反向代理處理所有的請求并轉發給我們的 Go 程序處理,其實我們還可以有選擇的將靜態文件部分的請求直接使用 nginx 處理,而將 API 接口類的動態處理請求轉發給后端的 Go 程序來處理。

下面繼續修改我們的 nginx 的配置文件來實現上述功能。

worker_processes  1;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       80;server_name  bluebell;access_log   /var/log/bluebell-access.log;error_log    /var/log/bluebell-error.log;location ~ .*\.(gif|jpg|jpeg|png|js|css|eot|ttf|woff|svg|otf)$ {access_log off;expires    1d;root       /data/app/bluebell;}location / {root /data/app/bluebell/templates;index index.html;try_files $uri $uri/ /index.html;}location /api {proxy_pass                 http://127.0.0.1:8084;proxy_redirect             off;proxy_set_header           Host             $host;proxy_set_header           X-Real-IP        $remote_addr;proxy_set_header           X-Forwarded-For  $proxy_add_x_forwarded_for;}}
}

前后端分開部署

前后端的代碼沒必要都部署到相同的服務器上,也可以分開部署到不同的服務器上,下圖是前端服務將 API 請求轉發至后端服務的方案。

上面的部署方案中,所有瀏覽器的請求都是直接訪問前端服務,而如果是瀏覽器直接訪問后端 API 服務的部署模式下,如下圖。

此時前端和后端通常不在同一個域下,我們還需要在后端代碼中添加跨域支持。

這里使用github.com/gin-contrib/cors庫來支持跨域請求。

最簡單的允許跨域的配置是使用cors.Default(),它默認允許所有跨域請求。

func main() {router := gin.Default()router.Use(cors.Default())router.Run()
}

此外,還可以使用cors.Config自定義具體的跨域請求相關配置項:

package mainimport ("time""github.com/gin-contrib/cors""github.com/gin-gonic/gin"
)func main() {router := gin.Default()router.Use(cors.New(cors.Config{AllowOrigins:     []string{"https://foo.com"},AllowMethods:     []string{"PUT", "PATCH"},AllowHeaders:     []string{"Origin"},ExposeHeaders:    []string{"Content-Length"},AllowCredentials: true,AllowOriginFunc: func(origin string) bool {return origin == "https://github.com"},MaxAge: 12 * time.Hour,}))router.Run()
}

優點

  • 完全自動化,減少人工操作。
  • 方便的版本控制和回滾。

缺點

  • 初期配置可能較為復雜。
  • 需要正確設置云服務器和訪問權限。

總結

Go 語言的部署方式有很多種,每種方法適用于不同的場景和需求。以下是一些常見的部署方式總結:

  1. 直接部署二進制文件:適合小型項目和簡單的部署環境。
  2. 使用 Docker:適合跨平臺部署,能夠更好地管理依賴。
  3. 使用 Kubernetes:適合大規模微服務架構,具備高可用性和自動擴展能力。
  4. 使用云服務平臺:適合不想管理基礎設施的開發者,提供自動化管理和擴展能力。
  5. 使用 CI/CD 管道:適合需要自動化部署和頻繁更新的項目。

根據你的項目需求和技術棧選擇合適的部署方式,能夠有效提高開發和運維效率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/920918.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/920918.shtml
英文地址,請注明出處:http://en.pswp.cn/news/920918.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【ARM】MDK工程切換高版本的編譯器后出現error: A1167E\A1159E\A1137E\A1517E\A1150E報錯

1、 文檔目標解決工程從Compiler 5切換到Compiler 6進行編譯時出現一些非語法問題上的報錯。2、 問題場景對于一些使用Compiler 5進行編譯的工程,要切換到Compiler 6進行編譯的時候,原本無任何報錯警告信息的工程在使用Compiler 6進行編譯后出現了一些非…

AtCoder Beginner Contest 421

文章目錄A MisdeliveryB Fibonacci ReversedC AlternatedD RLE MovingE YachtF Erase between X and YG Increase to make it IncreasingAtCoder Beginner Contest 421A Misdelivery Mansion AtCoder has N rooms numbered from room 1 to room N. Each room i is inhabited b…

數據結構:冒泡排序 (Bubble Sort)

目錄 從最簡單的操作開始 如何利用這個原子操作實現一個具體的小目標? 我們來手動模擬一下: 如何從一個小目標擴展到最終目標? 代碼的逐步完善 第一階段:定義函數框架和我們需要的“原子操作” 第二階段:實現“…

教育項目管理工具新趨勢:可視化與自動化如何提升效率?

課程項目不同于普通商業項目,它涉及 “教研設計→內容開發→師資準備→市場推廣→學員服務” 全鏈路,環節多、角色雜、周期跨度大。傳統的 Excel 表格、口頭溝通不僅難以追蹤進度,更易造成信息斷層。而看板工具憑借 “可視化流程、輕量化協作…

計算兩個二值圖像的交集計算交點數量的基礎上,進一步使用 DBSCAN 算法對交點進行聚

好的,如果你需要在計算交點數量的基礎上,進一步使用 DBSCAN 算法對交點進行聚類,以合并距離較近的點,可以按照以下步驟實現: 計算交點:使用 cv2.bitwise_and 計算兩個二值圖像的交集,并提取交點…

Linux中的IP命令詳解

華子目錄 1.ip命令是什么1.1ip命令的由來1.2ip命令的安裝包1.2ip選項(基本不用) 2.查看網絡信息2.1顯示全部網絡接口信息2.2顯示單個網絡接口信息2.3顯示單個接口狀態2.4查看路由表2.5查看arp緩存 3.設置網卡ip地址3.1啟用或停用網卡3.2設置默認網關3.3新…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘tox’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘tox’問題 摘要 在使用 PyCharm 2025 控制臺執行 pip install 命令時,開發者經常會遇到如下錯誤: ModuleNotFoundError: No module nam…

拆分TypeScript項目的學習收獲:處理編譯緩存和包緩存,引用本地項目,使用相對路徑

最近需要將工作中的一個TS包拆出一部分代碼,以便在多個團隊和項目中共享。原以為這會是一項特別簡單的工作,但是也花了兩天才大致拆成功。因此記錄一下,也給有類似需求的同學一點經驗。 所拆項目的大致功能:整個項目的結構大致分為…

瑞芯微RK3576平臺FFmpeg硬件編解碼移植及性能測試實戰攻略

本文介紹瑞芯微RK3576平臺,FFmpeg硬件編解碼移植及性能測試方法。 FFmpeg簡介與實測數據 FFmpeg簡介 FFmpeg是一套多媒體框架,能夠解碼、編碼、轉碼、復用、解復用、流、過濾和播放數字音頻、視頻,提供了錄制、轉換以及流化音視頻的完整解…

【網絡安全入門基礎教程】網絡安全零基礎學習方向及需要掌握的技能

最近總有同學問我,0基礎怎么學網絡安全?0基礎可以轉行做網絡安全嗎?網絡安全有哪些學習方向?每個方向需要掌握哪些技能?今天給大家簡單寫一下。 我的回答是先了解,再入行。 具體怎么做呢? 首…

Altium Designer中的Net-Tie:解決多網絡合并與電氣隔離的利器

Altium Designer中的Net-Tie:解決多網絡合并與電氣隔離的利器 在復雜的PCB設計中,我們常常會遇到一些特殊的電氣連接需求。例如,需要將兩個或多個邏輯上獨立但物理上需要連接的網絡(如不同電源域的GND)在特定點進行連接(單點連接),同時又要保持其網絡標識的獨立性。 …

計算機畢設項目 基于Python與機器學習的B站視頻熱度分析與預測系統 基于隨機森林算法的B站視頻內容熱度預測系統

💕💕作者:計算機源碼社 💕💕個人簡介:本人八年開發經驗,擅長Java、Python、PHP、.NET、Node.js、Spark、hadoop、Android、微信小程序、爬蟲、大數據、機器學習等,大家有這一塊的問題…

百勝軟件×OceanBase深度合作,賦能品牌零售數字化實踐降本增效

8月28日,由OceanBase主辦的“2025零售數據底座創新大會”在上海舉行。大會重磅發布了由愛分析、OceanBase攜手王歆、沈剛兩位行業專家聯合編制的《零售一體化云數據庫白皮書》。白皮書系統梳理了從“大促流量應對”到“AI應用落地”的全流程方法論,并為不…

2025年Java在中國開發語言排名分析報告

引言 在軟件定義世界的2025年,編程語言的戰略價值已超越工具屬性,成為產業數字化轉型的核心支撐與開發者思維模式的延伸載體。TIOBE指數作為全球技術市場變化的重要晴雨表,通過追蹤工程師分布、課程設置、供應商動態及搜索引擎數據&#xff0…

TDengine 日期時間函數 DAYOFWEEK 使用手冊

DAYOFWEEK 函數使用手冊 函數描述 DAYOFWEEK 函數用于返回指定日期是一周中的第幾天。該函數遵循標準的星期編號約定,返回值范圍為 1-7,其中: 1 星期日 (Sunday)2 星期一 (Monday)3 星期二 (Tuesday)4 星期三 (Wednesday)5 星期四 (T…

從RNN到BERT

目錄 序列模型簡介RNN循環神經網絡LSTM長短期記憶網絡Transformer架構BERT模型詳解實踐項目 序列模型簡介 什么是序列數據? 序列數據是按照特定順序排列的數據,其中元素的順序包含重要信息。常見的序列數據包括: 文本:單詞或字…

橢圓曲線的數學基礎

一、引言 橢圓曲線密碼學(Elliptic Curve Cryptography, ECC)是現代公鑰密碼學的核心工具之一。 相比傳統的 RSA,ECC 可以用 更短的密鑰長度 提供 同等甚至更高的安全性,因此被廣泛應用于區塊鏈、TLS、移動設備加密等場景。 要理解…

從能耗黑洞到精準智控:ASCB2智慧空開重構高校宿舍用電能效模型

隨著智慧校園建設不斷推進,校園宿舍的用電管理面臨著安全性、智能化與可視化的多重挑戰。傳統用電監控手段在數據采集、實時控制和故障響應方面存在明顯不足。安科瑞ASCB2系列物聯網斷路器通過集成多種智能感知、保護控制與通信手段,為高校宿舍提供了一種…

前端學習——JavaScript基礎

前面我們已經學習了前端代碼的骨架——HTML和前端美化工具——CSS。但是作為界面與客戶進行交互我們還需要一個語言工具——JavaScript。 因此實際上HTML、CSS、JavaScript三者是這樣的關系: HTML: 網頁的結構(骨) CSS: 網頁的表現(皮) JavaScript: 網頁的行為(魂) …

Ubuntu下的壓縮及解壓縮

一、Linxu 下常用的壓縮格式 Linux 下常用的壓縮擴展名有:.tar 、.tar.bz2、 .tar.gz 。 二、Windows 下 7ZIP 軟件的安裝 因為 Linux 下很多文件是 .bz2 , .gz 結尾的壓縮文件,因此需要在 windows 下安裝 7ZIP 軟件。 7-Zip 三、Ubuntu…