成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

從DevOps到日常腳本:聊聊Go語言的多面性

開發 前端
在本文中,我們探討了Go語言在DevOps和日常腳本編寫中的多面性。首先,Go語言因其高性能、并發處理能力及跨平臺編譯特性,成為DevOps領域的重要工具,助力于自動化任務和微服務部署。

2024年初,TIOBE編程語言排行榜上,Go再次進入了前十,并在之后又成功沖高至第七名。

Go語言的排名上升,至少在Reddit Go論壇[1]上帖子數量和在線人數上得到了體現,盡管目前與Rust[2]熱度仍有差距,但可見Go的關注度在提升:

圖片

2024年國慶節假期某天下午的實時在線數對比

隨著Go語言人氣的上升,論壇中的問題也變得愈發多樣化。許多Gopher常常問及為何Go是DevOps語言[3]和Go適合用作腳本語言嗎[4]等問題,這些都反映了Go語言的多面性。

從最初的系統編程語言,到如今在DevOps領域的廣泛應用,再到一些場合被探索用作腳本語言,Go展現出了令人驚嘆的靈活性和適應性。在本篇文章中,我們將聚焦于Go語言在DevOps領域的應用以及它作為腳本替代語言的潛力,聊聊其強大多面性如何滿足這些特定場景的需求。

1. Go在DevOps中的優勢

隨著DevOps的發展,平臺工程(Platform Engineering)[5]這一新興概念逐漸興起。在自動化任務、微服務部署和系統管理中,編程語言的作用變得愈發重要。Go語言憑借其高性能、并發處理能力以及能夠編譯成單一二進制文件的特點,越來越受到DevOps領域開發人員的青睞,成為開發DevOps工具鏈的重要組成部分。

首先,Go的跨平臺編譯能力使得DevOps團隊可以在一個平臺上編譯,然后在多個不同的操作系統和架構上運行,結合編譯出的單一可執行文件的能力,大大簡化了部署流程,這也是很多Go開發者認為Go適合DevOps的第一優勢:

$GOOS=linux GOARCH=amd64 go build -o myapp-linux-amd64 main.go
$GOOS=linux GOARCH=arm64 go build -o myapp-linux-arm64 main.go
$GOOS=darwin GOARCH=amd64 go build -o myapp-darwin-amd64 main.go
$GOOS=windows GOARCH=amd64 go build -o myapp-windows-amd64.exe main.go

其次,Go的標準庫仿佛“瑞士軍刀”,開箱即用,為DevOps場景提供了所需的豐富的網絡、加密和系統操作功能庫,大幅降低對外部的依賴,即便不使用第三方包生態系統,也可以滿足大部分的DevOps功能需求。

此外,Go的goroutines和channels為處理高并發任務提供了極大便利,這在DevOps中也尤為重要。例如,以下代碼展示了如何使用goroutines并發檢查多個服務的健康狀態:

func checkServices(services []string) {
    var wg sync.WaitGroup
    for _, service := range services {
        wg.Add(1)
        go func(s string) {
            defer wg.Done()
            if err := checkHealth(s); err != nil {
                log.Printf("Service %s is unhealthy: %v", s, err)
            } else {
                log.Printf("Service %s is healthy", s)
            }
        }(service)
    }
    wg.Wait()
}

并且,許多知名的DevOps基礎設施、中間件和工具都是用Go編寫的,如Docker、Kubernetes、Prometheus等,集成起來非常絲滑。這些工具的成功進一步證明了Go在DevOps領域的適用性。

2. Go作為腳本語言的潛力

在傳統的DevOps任務中,Python和Shell腳本長期以來都是主力軍,它們(尤其是Python)以其簡潔的語法和豐富的生態系統贏得了DevOps社區的廣泛青睞。然而,傳統主力Python和Shell腳本雖然靈活易用,但在處理大規模數據或需要高性能的場景時往往力不從心。此外,它們的動態類型系統可能導致運行時錯誤,增加了調試難度。

隨著Go的普及,它的“超高性價比”逐漸被開發運維人員所接受:既有著接近于腳本語言的較低的學習曲線與較高的生產力(也得益于Go超快的編譯速度),又有著靜態語言的高性能,還有單一文件在部署方面的便利性。

下面是一個簡單的文件處理腳本,用于向大家展示Go的簡單易學:

package main

import (
 "bufio"
 "fmt"
 "os"
 "strings"
)

func main() {
 file, err := os.Open("input.txt")
 if err != nil {
  fmt.Println("Error opening file:", err)
  return
 }
 defer file.Close()

 scanner := bufio.NewScanner(file)
 for scanner.Scan() {
  line := scanner.Text()
  if strings.Contains(line, "ERROR") {
   fmt.Println(line)
  }
 }
}

這個示例雖然要比同等功能的Python或shell代碼行數要多,但由于Go的簡單和直觀,多數人都很容易看懂這段代碼。

此外,Go的靜態強類型系統可以在編譯時捕獲更多錯誤,避免在運行時的調試,提高了腳本在運行時的可靠性。

開發運維人員眼中的腳本語言,如Shell腳本和Python腳本,通常是直接基于源代碼進行解釋和運行的。實際上,Go語言同樣可以實現這一點,而其關鍵工具就是go run命令。這個命令允許開發者快速執行Go代碼,從而使Go源碼看起來更像是“腳本”,下面我們就來看看go run。

3. go run:橋接編譯型語言與腳本語言的利器

我們知道go run命令實際上是編譯和運行的組合,它首先編譯源代碼,然后立即執行生成的二進制文件。這個過程對用戶來說是透明的,使得Go程序可以像腳本一樣方便地運行。這一命令也大大簡化了Go程序的開發流程,使Go更接近傳統的腳本語言工作流。可以說,通過go run,Go語言向腳本語言的使用體驗更靠近了一步。

此外,go run與go build在編譯階段的行為并不完全相同:

  • go run在運行結束后,不保留編譯后的二進制文件;而go build生成可執行文件并保留。
  • go run編譯時默認不包含調試信息,以減少構建時間;而go build則保留完整的調試信息。
  • go run可以使用-exec標志指定運行環境,比如:
$go run -exec="ls" main.go
/var/folders/cz/sbj5kg2d3m3c6j650z0qfm800000gn/T/go-build1742641170/b001/exe/main

我們看到,如果設置了-exec標志,那么go run -exec="prog" main.go args編譯后的命令執行就變為了"prog a.out args"。go run還支持跨平臺模擬執行,當GOOS或GOARCH與系統默認值不同時,如果在PATH路徑下存在名為"go_GOOS_$GOARCH_exec"的程序,那么go run就會執行:

$go_$GOOS_$GOARCH_exec a.out args

比如:go_js_wasm_exec a.out args
  • go run通常用于運行main包,在go module開啟的情況下,go run使用的是main module的上下文。go build可以編譯多個包,對于非main包時只檢查構建而不生成輸出
  • go run還支持運行一個指定版本號的包

當指定了版本后綴(如@v1.0.0或@latest)時,go run會進入module-aware mode(模塊感知模式),并忽略當前目錄或上級目錄中的go.mod文件。這意味著,即使你當前的項目中存在依賴管理文件go.mod,go run也不會影響或修改當前項目的依賴關系,下面這個示例展示了這一點:

$go run golang.org/x/example/hello@latest

go: downloading golang.org/x/example v0.0.0-20240925201653-1a5e218e5455
go: downloading golang.org/x/example/hello v0.0.0-20240925201653-1a5e218e5455
Hello, world!

這個功能特別適合在不影響主模塊依賴的情況下,臨時運行某個工具或程序。例如,如果你只是想測試某個工具的特定版本,或者快速運行一個遠程程序包,而不希望它干擾你正在開發的項目中的依賴項,這種方式就很實用。

不過有一點要注意的是:go run的退出狀態并不等于編譯后二進制文件的退出狀態,看下面這個示例:

// main.go成功退出
$go run main.go
Hello from myapp!
$echo $?        
0

// main.go中調用os.Exit(2)退出
$go run main.go               
Hello from myapp!
exit status 2
$echo $?        
1

go run使用退出狀態1來表示其運行程序的異常退出狀態,但這個值和真實的exit的狀態值不相等。

到這里我們看到,go run xxx.go可以像bash xxx.sh或python xxx.py那樣,以“解釋”方式運行一個Go源碼文件。這使得Go語言在某種程度上具備了腳本語言的特性。然而,在腳本語言中,例如Bash或Python等,用戶可以通過將源碼文件設置為可執行,并在文件的首行添加適當的解釋器指令,從而直接運行腳本,而無需顯式調用解釋器。這種靈活性使得腳本的執行變得更加簡便。那么Go是否也可以做到這一點呢?我們繼續往下看。

4. Go腳本化的實現方式

下面是通過一些技巧或第三方工具實現Go腳本化的方法。對于喜歡使用腳本的人來說,最熟悉的莫過于shebang(即解釋器指令)。在許多腳本語言中,通過在文件的第一行添加指定的解釋器路徑,可以直接運行腳本,而無需顯式調用解釋器。例如,在Bash或Python腳本中,通常會看到這樣的行:

#!/usr/bin/env python3

那么Go語言支持shebang嗎? 是否可以實現實現類似的效果呢?我們下面來看看。

4.1 使用“shebang(#!)”運行Go腳本

很遺憾,Go不能直接支持shebang,我們看一下這個示例main.go:

#!/usr/bin/env go run 

package main

import (
 "fmt"
 "os"
)

func main() {
 s := "world"
 if len(os.Args) > 1 {
  s = os.Args[1]
 }
 fmt.Printf("Hello, %v!\n", s)
}

這一示例的第一行就是一個shebang解釋器指令,我們chmod u+x main.go,然后執行該Go“腳本”:

$./main.go
main.go:1:1: illegal character U+0023 '#'

這個執行過程中,Shell可以正常識別shebang,然后調用go run去運行main.go,問題就在于go編譯器視shebang這一行為非法語法!

常規的shebang寫法行不通,我們就使用一些trick,下面是改進后的示例:

//usr/bin/env go run $0 $@; exit

package main

import (
 "fmt"
 "os"
)

func main() {
 s := "world"
 if len(os.Args) > 1 {
  s = os.Args[1]
 }
 fmt.Printf("Hello, %v!\n", s)
}

這段代碼則可以chmod +x 后直接運行:

$./main.go     
Hello, world!
$./main.go gopher
Hello, gopher!

這是因為它巧妙地結合了shell腳本和Go代碼的特性。我們來看一下第一行:

//usr/bin/env go run $0 $@; exit

這一行看起來像是Go的注釋,但實際上是一個shell命令。當文件被執行時,shell會解釋這一行,/usr/bin/env用于尋找go命令的路徑,go run @ 告訴go命令運行當前腳本文件(以及所有傳遞給腳本的參數@),當go run編譯這個腳本時,又會將第一行當做注釋行而忽略,這就是關鍵所在。最后的exit確保shell在Go程序執行完畢后退出。如果沒有exit,shell會執行后續Go代碼,那顯然會導致報錯!

除了上述trick外,我們還可以將Go源碼文件注冊為可執行格式(僅在linux上進行了測試),下面就是具體操作步驟。

4.2 在Linux系統中注冊Go為可執行格式

就像在Windows上雙擊某個文件后,系統打開特定程序處理對應的文件一樣,我們也可以將Go源文件(xxx.go)注冊為可執行格式,并指定用于處理該文件的程序。實現這一功能,我們需要借助binfmt_misc。binfmt_misc是Linux內核的一個功能,允許用戶注冊新的可執行文件格式。這使得Linux系統能夠識別并執行不同類型的可執行文件,比如腳本、二進制文件等。

我們用下面命令將Go源文件注冊到binfmt_misc中:

echo ':golang:E::go::/usr/local/bin/gorun:OC' | sudo tee /proc/sys/fs/binfmt_misc/register

簡單解釋一下上述命令:

  • :golang::這是注冊的格式的名稱,可以自定義。
  • E:::表示執行文件的魔數(magic number),在這里為空,表示任何文件類型。
  • go:::指定用于執行的解釋器,這里是go命令。
  • /usr/local/bin/gorun:指定用于執行的程序路徑,這里是一個自定義的gorun腳本
  • :OC:表示這個格式是可執行的(O)并且支持在運行時創建(C)。

當你執行一個Go源文件時,Linux內核會檢查文件的類型。如果文件的格式與注冊的格式匹配,內核會調用指定的解釋器(在這個例子中是gorun)來執行該文件。

gorun腳本是我們自己編寫的,源碼如下:

#!/bin/bash

# 檢查是否提供了源文件
if [ -z "$1" ]; then
  echo "用法: gorun <go源文件> [參數...]"
  exit 1
fi

# 檢查文件是否存在
if [ ! -f "$1" ]; then
  echo "錯誤: 文件 $1 不存在"
  exit 1
fi

# 將第一個參數作為源文件,剩余的參數作為執行參數
GO_FILE="$1"
shift  # 移除第一個參數,剩余的參數將會被傳遞

# 使用go run命令執行Go源文件,傳遞其余參數
go run "$GO_FILE" "$@"

將gorun腳本放置帶/usr/local/bin下,并chmod +x使其具有可執行權限。

接下來,我們就可以直接執行不帶有"shebang"的正常go源碼了:

// main.go
package main

import (
    "fmt"
    "os"
)
  
func main() {
      s := "world"
      if len(os.Args) > 1 {
          s = os.Args[1]
      }
      fmt.Printf("Hello, %v!\n", s)
}

直接執行上述源文件:

$ ./main.go
Hello, world!
$ ./main.go gopher
Hello, gopher!

4.3 第三方工具支持

Go社區也有一些將支持將Go源文件視為腳本的解釋器工具,比如:traefik/yaegi[6]等。

$go install github.com/traefik/yaegi/cmd/yaegi@latest
go: downloading github.com/traefik/yaegi v0.16.1
$yaegi main.go
Hello, main.go!

yaegi還可以像python那樣,提供Read-Eval-Print-Loop功能,我們可以與yaegi配合進行交互式“Go腳本”編碼:

$ yaegi
> 1+2
: 3
> import "fmt"
: 0xc0003900d0
> fmt.Println("hello, golang")
hello, golang
: 14
>

類似的提供REPL功能的第三方Go解釋器還包括:cosmos72/gomacro[7]、x-motemen/gore[8]等,這里就不深入介紹了,感興趣的童鞋可以自行研究。

5. 小結

在本文中,我們探討了Go語言在DevOps和日常腳本編寫中的多面性。首先,Go語言因其高性能、并發處理能力及跨平臺編譯特性,成為DevOps領域的重要工具,助力于自動化任務和微服務部署。其次,隨著Go語言的普及,其作為腳本語言的潛力逐漸被開發運維人員認識,Go展現出了優于傳統腳本語言的高效性和可靠性。

我們還介紹了Go腳本的實現方式,包括使用go run命令,它使得Go程序的執行更像傳統腳本語言,同時也探討了一些技巧和工具,幫助開發者將Go源碼文件作為可執行腳本直接運行。通過這些探索,我們可以看到Go語言在現代開發中的靈活應用及其日益增長的吸引力。

隨著AI能力的飛速發展,使用Go編寫一個日常腳本就是分分鐘的事情,但Go的特性讓這樣的腳本具備了傳統腳本語言所不具備的并發性、可靠性和性能優勢。我們有理由相信,Go在DevOps和腳本編程領域的應用將會越來越廣泛,為開發者帶來更多的可能性和便利。

6. 參考資料

  • Using Go as a scripting language in Linux[9] - https://blog.cloudflare.com/using-go-as-a-scripting-language-in-linux/
  • Go as a Scripting Language[10] - https://www.infoq.com/news/2020/04/go-scripting-language/
  • Go compared to Python for small scale system administration scripts and tools[11] - https://utcc.utoronto.ca/~cks/space/blog/sysadmin/SysadminGoVsPython

參考資料

[1] Reddit Go論壇: https://www.reddit.com/r/golang/

[2] Rust: https://tonybai.com/tag/rust

[3] 為何Go是DevOps語言: https://www.reddit.com/r/golang/comments/1fqwbv0/why_is_golang_the_language_of_devops/

[4] Go適合用作腳本語言嗎: https://www.reddit.com/r/golang/comments/1ftpk2m/do_you_use_go_for_scripts/

[5] 平臺工程(Platform Engineering): https://en.wikipedia.org/wiki/Platform_engineering

[6] traefik/yaegi: https://github.com/traefik/yaegi

[7] cosmos72/gomacro: https://github.com/cosmos72/gomacro

[8] x-motemen/gore: https://github.com/x-motemen/gore

[9] Using Go as a scripting language in Linux: https://blog.cloudflare.com/using-go-as-a-scripting-language-in-linux/

[10] Go as a Scripting Language: https://www.infoq.com/news/2020/04/go-scripting-language/

[11] Go compared to Python for small scale system administration scripts and tools: https://utcc.utoronto.ca/~cks/space/blog/sysadmin/SysadminGoVsPython

責任編輯:武曉燕 來源: TonyBai
相關推薦

2023-12-27 06:48:49

KubernetesDevOpsHTTP

2021-03-28 20:58:25

Go語言線程

2021-04-29 09:02:44

語言Go 處理

2023-03-21 07:57:37

Go語言設計模式

2021-07-13 06:44:04

Go語言數組

2021-09-01 22:58:22

Canvas標簽

2023-12-20 14:44:33

軟件開發DevOpsNoOps

2022-11-01 12:16:47

Nginx微服務編譯

2022-06-22 09:24:30

云原生Go 語言

2023-01-31 08:48:49

Go語言文件

2017-12-27 14:52:21

JSGo編程語言

2024-08-28 10:36:19

2019-12-24 08:29:25

DevOpsDevSecOps工具

2018-10-10 14:02:30

Linux系統硬件內核

2024-02-21 23:16:08

C語言開發

2017-03-13 09:19:38

CAP編程語言

2020-05-08 11:42:24

JavaScript編程語言技術

2021-02-22 09:30:09

go開發環境桌面系統

2018-05-31 15:27:59

DevOpsDataOps數據中心

2024-04-26 08:17:09

GoGoogle項目
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91久久精品一区二区二区 | 欧美精品一区二区三区蜜桃视频 | 免费看大片bbbb欧美 | 伊人无码高清 | 桃色五月| 久久久av一区 | 亚洲成人观看 | a在线观看免费 | 精品美女在线观看 | 国产午夜精品视频 | 亚洲午夜精品久久久久久app | 中文字幕av中文字幕 | 一区二区三区四区国产 | 噜久寡妇噜噜久久寡妇 | 韩国精品在线观看 | 久久久精品一区 | 成人在线精品视频 | 国产日韩欧美激情 | 亚洲精品久久久久久国产精华液 | 久草视频在线播放 | 一级欧美一级日韩片免费观看 | 亚洲成人久久久 | 蜜桃视频在线观看免费视频网站www | 中文字幕在线一区 | 亚洲 欧美 日韩 精品 | 亚洲国产一区二区三区在线观看 | 精品亚洲91 | 国产熟熟 | 色天堂影院 | 欧美美女二区 | 亚洲欧美日韩国产综合 | 一级美国黄色片 | 欧美一区成人 | 中文字幕一区二区三区不卡在线 | 久久久av一区| 国产日屁| 久国产精品 | 亚洲一区二区三区在线观看免费 | 久久亚洲国产 | 国产精品永久免费观看 | 视频一区 亚洲 |