Go言語
Google開発のシンプルで高速なコンパイル言語
Go言語とは
Goは2009年にGoogleが開発した静的型付けコンパイル言語です。 シンプルな構文、高速なコンパイル、組み込みの並行処理機能が特徴。 Kubernetes、Docker、Terraform等、インフラツールの標準言語となっています。
Goの実行アーキテクチャ
ポイント: Goは静的リンクでシングルバイナリを生成。 実行環境にGoランタイムやライブラリのインストールが不要。 Dockerイメージも軽量化できる(scratch/distrolessベース)。
Goランタイムの構造
Goroutineスケジューラ
軽量スレッド(goroutine)をOSスレッドにマッピング。M:Nスケジューリング。
ガベージコレクタ
並行マーク&スイープ。低レイテンシ重視。STW時間を最小化。
ネットワークポーラー
epoll/kqueueを抽象化。非同期I/Oを同期的に記述。
Goroutineと並行処理
Goroutineは軽量な並行処理の単位。 OSスレッド(数MB)と比べ、goroutineは約2KBで起動可能。 数十万のgoroutineを同時に実行できる。
1 // Goroutineの基本 2 func main() { 3 // goキーワードで並行実行 4 go func() { 5 fmt.Println("Hello from goroutine") 6 }() 7 8 // Channelで通信 9 ch := make(chan string) 10 go func() { 11 ch <- "message" // 送信 12 }() 13 msg := <-ch // 受信 14 fmt.Println(msg) 15 } 16 17 // Worker Pool パターン 18 func worker(id int, jobs <-chan int, results chan<- int) { 19 for j := range jobs { 20 results <- j * 2 21 } 22 } 23 24 func main() { 25 jobs := make(chan int, 100) 26 results := make(chan int, 100) 27 28 // 3つのworkerを起動 29 for w := 1; w <= 3; w++ { 30 go worker(w, jobs, results) 31 } 32 33 // ジョブを投入 34 for j := 1; j <= 5; j++ { 35 jobs <- j 36 } 37 close(jobs) 38 39 // 結果を収集 40 for a := 1; a <= 5; a++ { 41 <-results 42 } 43 }
Goの主要な特徴
シンプルな構文
キーワードは25個のみ。継承なし、ジェネリクスは1.18から限定的にサポート。 「一つのことを一つの方法で」という設計思想。
高速なコンパイル
依存関係の解析が効率的で、大規模プロジェクトでも数秒でコンパイル完了。 開発サイクルが速い。
クロスコンパイル
GOOS/GOARCHを指定するだけで異なるOS/アーキテクチャ向けにビルド可能。
1 # Linux向けにビルド(Mac上で) 2 GOOS=linux GOARCH=amd64 go build -o myapp-linux 3 4 # Windows向け 5 GOOS=windows GOARCH=amd64 go build -o myapp.exe 6 7 # ARM (Raspberry Pi等) 8 GOOS=linux GOARCH=arm64 go build -o myapp-arm
標準ライブラリ
HTTP、JSON、暗号化、テスト等、実用的な機能が標準で充実。 外部依存を最小限に抑えられる。
エラーハンドリング
Goは例外(exception)を使わず、エラーを戻り値として返す設計。 明示的なエラーチェックが必要だが、エラーの流れが明確。
1 // エラーは戻り値の最後 2 func readFile(path string) ([]byte, error) { 3 data, err := os.ReadFile(path) 4 if err != nil { 5 return nil, fmt.Errorf("failed to read %s: %w", path, err) 6 } 7 return data, nil 8 } 9 10 // 呼び出し側で必ずチェック 11 func main() { 12 data, err := readFile("config.json") 13 if err != nil { 14 log.Fatal(err) 15 } 16 // dataを使用 17 } 18 19 // Go 1.13以降: errors.Is, errors.As でエラー判定 20 if errors.Is(err, os.ErrNotExist) { 21 // ファイルが存在しない 22 }
SRE/インフラでの活用
CLIツール
kubectl, terraform, docker - シングルバイナリで配布が容易
Kubernetes関連
Operator開発、CRD、client-go - K8sエコシステムの標準
監視ツール
Prometheus, Grafana Agent - 高性能なメトリクス収集
API/マイクロサービス
低レイテンシ、高スループット、省メモリ
標準的なプロジェクト構成
1 myproject/ 2 ├── cmd/ 3 │ └── myapp/ 4 │ └── main.go # エントリーポイント 5 ├── internal/ # 内部パッケージ(外部からimport不可) 6 │ ├── handler/ 7 │ └── service/ 8 ├── pkg/ # 公開パッケージ 9 │ └── client/ 10 ├── api/ # API定義(OpenAPI, Protocol Buffers) 11 ├── configs/ # 設定ファイル 12 ├── scripts/ # ビルド・デプロイスクリプト 13 ├── go.mod # モジュール定義 14 ├── go.sum # 依存関係のチェックサム 15 ├── Makefile 16 └── Dockerfile