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

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

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

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

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

圖片

2024年國慶節(jié)假期某天下午的實時在線數(shù)對比

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

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

1. Go在DevOps中的優(yōu)勢

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

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

$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場景提供了所需的豐富的網絡、加密和系統(tǒng)操作功能庫,大幅降低對外部的依賴,即便不使用第三方包生態(tài)系統(tǒng),也可以滿足大部分的DevOps功能需求。

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

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作為腳本語言的潛力

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

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

下面是一個簡單的文件處理腳本,用于向大家展示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代碼行數(shù)要多,但由于Go的簡單和直觀,多數(shù)人都很容易看懂這段代碼。

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

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

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

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

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

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

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

$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!

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

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

// 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使用退出狀態(tài)1來表示其運行程序的異常退出狀態(tài),但這個值和真實的exit的狀態(tài)值不相等。

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

4. Go腳本化的實現(xiàn)方式

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

#!/usr/bin/env python3

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

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,然后執(zhí)行該Go“腳本”:

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

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

常規(guī)的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命令。當文件被執(zhí)行時,shell會解釋這一行,/usr/bin/env用于尋找go命令的路徑,go run @ 告訴go命令運行當前腳本文件(以及所有傳遞給腳本的參數(shù)@),當go run編譯這個腳本時,又會將第一行當做注釋行而忽略,這就是關鍵所在。最后的exit確保shell在Go程序執(zhí)行完畢后退出。如果沒有exit,shell會執(zhí)行后續(xù)Go代碼,那顯然會導致報錯!

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

4.2 在Linux系統(tǒng)中注冊Go為可執(zhí)行格式

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

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

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

簡單解釋一下上述命令:

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

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

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

#!/bin/bash

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

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

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

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

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

接下來,我們就可以直接執(zhí)行不帶有"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)
}

直接執(zhí)行上述源文件:

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

4.3 第三方工具支持

Go社區(qū)也有一些將支持將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語言因其高性能、并發(fā)處理能力及跨平臺編譯特性,成為DevOps領域的重要工具,助力于自動化任務和微服務部署。其次,隨著Go語言的普及,其作為腳本語言的潛力逐漸被開發(fā)運維人員認識,Go展現(xiàn)出了優(yōu)于傳統(tǒng)腳本語言的高效性和可靠性。

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

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

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語言數(shù)組

2023-12-20 14:44:33

軟件開發(fā)DevOpsNoOps

2021-09-01 22:58:22

Canvas標簽

2022-06-22 09:24:30

云原生Go 語言

2017-12-27 14:52:21

JSGo編程語言

2023-01-31 08:48:49

Go語言文件

2022-11-01 12:16:47

Nginx微服務編譯

2024-08-28 10:36:19

2019-12-24 08:29:25

DevOpsDevSecOps工具

2018-10-10 14:02:30

Linux系統(tǒng)硬件內核

2024-02-21 23:16:08

C語言開發(fā)

2017-03-13 09:19:38

CAP編程語言

2021-02-22 09:30:09

go開發(fā)環(huán)境桌面系統(tǒng)

2020-05-08 11:42:24

JavaScript編程語言技術

2018-05-31 15:27:59

DevOpsDataOps數(shù)據(jù)中心

2024-05-17 08:47:33

數(shù)組切片元素
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品免费观看 | 精品小视频 | 青青草社区| 91麻豆精品国产91久久久更新资源速度超快 | 日韩在线电影 | 国产aa| 日韩欧美在线一区 | 亚洲高清在线观看 | 亚洲视频免费观看 | 天天干天天干 | 性生生活大片免费看视频 | 中文字幕精品一区 | 精品国产一区二区三区久久久蜜月 | 欧美日韩不卡合集视频 | 秋霞在线一区二区 | com.色.www在线观看 | 久久综合一区 | 操亚洲 | 国产免费一区二区三区 | 我想看国产一级毛片 | 日韩欧美综合 | 一区精品国产欧美在线 | 亚洲精品一区二三区不卡 | 精品久久久久久久久久久久久久久久久 | a毛片 | 午夜影视大全 | 性色网站 | 美女毛片 | 日韩欧美在线观看 | 亚洲综合在线播放 | 一级毛片在线视频 | 日韩中文字幕免费在线观看 | 男女网站在线观看 | 国产日韩视频 | 天天爽夜夜爽精品视频婷婷 | 国产精品美女久久久久久不卡 | h片在线观看免费 | 国产成人精品久久二区二区 | 亚洲狠狠爱 | 亚洲成人精品 | 国产区久久 |