まずはこのステップを実行してみて - Go開発現場で即効性のある効率改善アクション集
- プロファイリングを7日ごとに実施してボトルネックを特定
リソース消費や処理遅延の原因を早期把握、最小限の手戻りで最適化
- 最新Goバージョンへ3ヶ月以内に全環境アップデート
パフォーマンス最適化やバグ修正による安定稼働、平均2~3%以上CPU負荷減少[3]
- goroutine数はピーク同時接続数の120%未満に制限
過剰な並列処理によるリソース圧迫防止、急激なレスポンス低下回避[2]
- `sync.Pool`等オブジェクトプール活用でメモリアロケーション頻度10%以上削減
*GC負荷*軽減と応答速度向上が期待できる[1][2]
泥臭いスタートアップとGo言語の出会い
# Goのシンプルさがスタートアップを救った—ただし柔軟性が必要になったときまで
スタートアップって本当に、なんかもう毎日ジェットコースターみたいなもので。最初のころは、何もかもが不安というか…うーん、何ていうか一歩間違えば全て水の泡になる感じ?リソースは限られてるし、納期だって待ってくれない。それに加えて、「資金切れ」の悪夢みたいな言葉が頭から離れない。ああ、いや別におどかしてるわけじゃなくて…。まあ要するに(いや、この言い方ダメだった)、技術選定ひとつで会社の運命変わること、本当にあると思う。
僕たちの場合はね、そのサプライチェーン物流をどう効率化できるのか必死で考えてた。そのためにはSaaSプラットフォームだろうって話になって、それでGoogle謹製のGoというミニマル主義的な言語を選んだんだ。でもね、そのシンプルさのおかげでプロトタイプからMinimum Viable Product(MVP)まで信じられないスピードで漕ぎ着けた。えっと…途中ちょっとアイスコーヒーこぼしたりしてたけど、関係なかった(笑)。ところがやっぱり事業が広がるにつれて、「あれ?この設計思想って逆に足枷にならない?」みたいな疑念も出てくるわけです。結局今日は、そのGoで助かった部分と「これじゃ足りない」と思った場面、それから学んだことについて書いてみようかな、と。
## Goの魅力:選択理由
2022年の初めに創業した時、僕らはエンジニア3人とプロダクトマネージャー1人だけだった。本当、小規模ってレベルじゃないよね。掲げたビジョンは「サプライチェーン非効率問題」への挑戦だった。でもこういう壮大っぽい話してると急にお腹すくんだよね…ま、それはさておき。目指したのはサプライヤー・倉庫・物流業者などいろんなところからリアルタイムデータを吸い上げて、それを使って業務改善につながる示唆を出せるプラットフォーム。でも正直スピード命で、6ヶ月以内に投資家向けMVPデモ版仕上げなきゃ意味がなかった。
バックエンド用にはPython(多用途)、Node.js(エコシステム豊富)、Java(エンタープライズ感満載)とか色々検討してたけど…結局Goが残った理由、大きく分けて3つだった。
まず一つ目。「シンプルさ」。Goってね、本当に無駄なく削ぎ落とされた文法しか持たせてなくて、不思議なくらい構文要素少ない。それゆえなのかな、新しく入ったメンバーでも覚える負担少なくなるし、人のコード読解する苦労も減るんだよ。不意に「でもそれだけでいいの?」なんて思うこともあるけど、とりあえず当時はめちゃくちゃありがたかった。
スタートアップって本当に、なんかもう毎日ジェットコースターみたいなもので。最初のころは、何もかもが不安というか…うーん、何ていうか一歩間違えば全て水の泡になる感じ?リソースは限られてるし、納期だって待ってくれない。それに加えて、「資金切れ」の悪夢みたいな言葉が頭から離れない。ああ、いや別におどかしてるわけじゃなくて…。まあ要するに(いや、この言い方ダメだった)、技術選定ひとつで会社の運命変わること、本当にあると思う。
僕たちの場合はね、そのサプライチェーン物流をどう効率化できるのか必死で考えてた。そのためにはSaaSプラットフォームだろうって話になって、それでGoogle謹製のGoというミニマル主義的な言語を選んだんだ。でもね、そのシンプルさのおかげでプロトタイプからMinimum Viable Product(MVP)まで信じられないスピードで漕ぎ着けた。えっと…途中ちょっとアイスコーヒーこぼしたりしてたけど、関係なかった(笑)。ところがやっぱり事業が広がるにつれて、「あれ?この設計思想って逆に足枷にならない?」みたいな疑念も出てくるわけです。結局今日は、そのGoで助かった部分と「これじゃ足りない」と思った場面、それから学んだことについて書いてみようかな、と。
## Goの魅力:選択理由
2022年の初めに創業した時、僕らはエンジニア3人とプロダクトマネージャー1人だけだった。本当、小規模ってレベルじゃないよね。掲げたビジョンは「サプライチェーン非効率問題」への挑戦だった。でもこういう壮大っぽい話してると急にお腹すくんだよね…ま、それはさておき。目指したのはサプライヤー・倉庫・物流業者などいろんなところからリアルタイムデータを吸い上げて、それを使って業務改善につながる示唆を出せるプラットフォーム。でも正直スピード命で、6ヶ月以内に投資家向けMVPデモ版仕上げなきゃ意味がなかった。
バックエンド用にはPython(多用途)、Node.js(エコシステム豊富)、Java(エンタープライズ感満載)とか色々検討してたけど…結局Goが残った理由、大きく分けて3つだった。
まず一つ目。「シンプルさ」。Goってね、本当に無駄なく削ぎ落とされた文法しか持たせてなくて、不思議なくらい構文要素少ない。それゆえなのかな、新しく入ったメンバーでも覚える負担少なくなるし、人のコード読解する苦労も減るんだよ。不意に「でもそれだけでいいの?」なんて思うこともあるけど、とりあえず当時はめちゃくちゃありがたかった。
最初はシンプルさが救い、スピード命だった日々
経験レベルがバラバラな小規模チームだったんだけど、これが思いのほか助けになった気がする。いや、正直「ほんとに大丈夫かな」って最初は疑ってた。でも、えっと、新しいメンバーをさっとオンボーディングできたし、一貫したコードベースもちゃんと保てたのだ。
うーん、それからパフォーマンスなんだけど…Goってネイティブのマシンコードに直接コンパイルされるんだよね。C言語みたいなパフォーマンスを、複雑な手動メモリ管理とか無しで得られるっていう話。あれ、でも本当にそんなに速いのか?まぁ少なくとも自分たちの場合は、数千件ものAPIリクエストが1分ごとに飛び交うデータ集約型アプリにはすごく有利だったように思う。
さて並行処理について考えると…サプライチェーンデータってそもそも同時進行的な要素多すぎなんだよね。在庫の更新や出荷の移動、それから価格変動とか、本当にリアルタイムで色々起こりすぎて頭痛くなる。でもGoのゴルーチンやチャネルがあるおかげで並行タスクもうまく捌けて、データストリーム処理まで効率よく回せた感じ。それ以外にも実はGo標準ライブラリの充実っぷりも侮れなくて、`go fmt` や `go test` みたいなツール群のおかげでワークフロー自体が軽快になった。ま、途中で関係ないこと考えてしまったけど……あと単一バイナリで出力できるからクラウド展開するときもランタイム依存性とか悩まなくていいんだよね。不安ゼロではないけど、この特徴のおかげでスタートアップとして短期間で結果を求める環境下ではGoは本当に重宝した印象。
## ハネムーン期:MVP構築
えっとね、Goを主軸技術に選んだまま開発初期へ突入した。当時作ったMVP(Minimum Viable Product)は三つの主要機能――リアルタイム在庫追跡とサプライヤーAPI統合、それから需要予測向け基礎分析――ここに全力注いだ覚えがある。どうでもいい話になるけど、その頃毎日カフェイン摂取量増えていた気もする。でもまあ、とりあえず最初はそこだけ見て進めていたと思う。
うーん、それからパフォーマンスなんだけど…Goってネイティブのマシンコードに直接コンパイルされるんだよね。C言語みたいなパフォーマンスを、複雑な手動メモリ管理とか無しで得られるっていう話。あれ、でも本当にそんなに速いのか?まぁ少なくとも自分たちの場合は、数千件ものAPIリクエストが1分ごとに飛び交うデータ集約型アプリにはすごく有利だったように思う。
さて並行処理について考えると…サプライチェーンデータってそもそも同時進行的な要素多すぎなんだよね。在庫の更新や出荷の移動、それから価格変動とか、本当にリアルタイムで色々起こりすぎて頭痛くなる。でもGoのゴルーチンやチャネルがあるおかげで並行タスクもうまく捌けて、データストリーム処理まで効率よく回せた感じ。それ以外にも実はGo標準ライブラリの充実っぷりも侮れなくて、`go fmt` や `go test` みたいなツール群のおかげでワークフロー自体が軽快になった。ま、途中で関係ないこと考えてしまったけど……あと単一バイナリで出力できるからクラウド展開するときもランタイム依存性とか悩まなくていいんだよね。不安ゼロではないけど、この特徴のおかげでスタートアップとして短期間で結果を求める環境下ではGoは本当に重宝した印象。
## ハネムーン期:MVP構築
えっとね、Goを主軸技術に選んだまま開発初期へ突入した。当時作ったMVP(Minimum Viable Product)は三つの主要機能――リアルタイム在庫追跡とサプライヤーAPI統合、それから需要予測向け基礎分析――ここに全力注いだ覚えがある。どうでもいい話になるけど、その頃毎日カフェイン摂取量増えていた気もする。でもまあ、とりあえず最初はそこだけ見て進めていたと思う。

ゴチャつくAPI、倉庫もポストグレSQLも二週間で完了
このフェーズ、なんていうか…Goのシンプルさがとにかく際立つんだよね。あ、ちょっと話が飛ぶかもだけど、最近天気悪すぎて本当にやる気下がる。でも戻ろう—
## 高速な開発
Goって余計な機能がまじでなくてさ。クラスとか継承?ないない。複雑な型もなくて、言語仕様自体を悩む時間が本当減った気がする。課題解決だけ考えて、無駄な寄り道せずコーディングできたというか…いやでも時々「これでいいの?」って不安になる瞬間はある。それでも例えば倉庫APIをポーリングしながらPostgreSQLデータベースを更新する在庫追跡モジュールは、本当に2週間くらいで作れちゃったんだよね。信じがたいけど事実。コードはこんな感じだった:
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(inventories)
}
まあ、ぱっと見めっちゃ直感的じゃない?しかもこのコードスニペットで1分あたり数千件リクエスト対応とか謳われてたし。うーん、ほんとに?って疑いたくなるけど実際そうだったらしい…。標準ライブラリの`net/http`とか`encoding/json`使えば追加パッケージ依存ほぼなしで済むし(PostgreSQL用の`lib/pq`みたいなの除けば)。ここ最近、「もっと便利なフレームワーク使え」みたいな空気あるけど…実はそうでもなくて…純正エコシステムで十分だった。
mu.Lock()
results = append(results, data)
mu.Unlock()
}(url)
}
wg.Wait()
return results, nil
}
こういうコードね、高パフォーマンス維持しながら可読性も保っている感じ。ま、新人開発者だって理解できたくらいなのでそこはメリット。「ほんとうかな?」と思った人、自分も最初疑って試したけど意外とうまく回った。Go特有の並行処理モデルは、「業務フロー管理ラク」と評価されること多かった。
## デプロイメントの快適さ
AWSへデプロイメントするときも実は結構楽だった報告あるし。「単一バイナリ」出力できるから、そのままパッケージ化してEC2インスタンスへアップロード、その後即実行可能――妙に夢みたい?ただそれ現実なんだよね。この場合追加ランタイムや依存管理ツールなし運用記録ありという点も、おお…となった(地味な感動)。CI/CDパイプラインではGitHub Actions利用していて、バイナリ生成・テスト・本番反映まで5分以内完了していたというので正直凄いと思った。ただ5ヶ月目には投資家にもMVP(Minimum Viable Product)が一定評価された―まあ完全じゃなくても最低限形になれば十分、と当時自分を納得させていた節ある。
## 高速な開発
Goって余計な機能がまじでなくてさ。クラスとか継承?ないない。複雑な型もなくて、言語仕様自体を悩む時間が本当減った気がする。課題解決だけ考えて、無駄な寄り道せずコーディングできたというか…いやでも時々「これでいいの?」って不安になる瞬間はある。それでも例えば倉庫APIをポーリングしながらPostgreSQLデータベースを更新する在庫追跡モジュールは、本当に2週間くらいで作れちゃったんだよね。信じがたいけど事実。コードはこんな感じだった:
package mainpython
import (
"database/sql"
"encoding/json"
"log"
"net/http"
"time"
_ "github.com/lib/pq"
)
css
type Inventory struct {
ID int `json:"id"`
ProductID string `json:"product_id"`
Quantity int `json:"quantity"`
UpdatedAt time.Time `json:"updated_at"`
}
css
func fetchInventory(w http.ResponseWriter, r *http.Request) {
db, err := sql.Open("postgres", "user=admin dbname=supplychain sslmode=disable")
if err != nil {
http.Error(w, "Database connection failed", http.StatusInternalServerError)
return
}
defer db.Close()
sql
rows, err := db.Query("SELECT id, product_id, quantity, updated_at FROM inventory")
if err != nil {
http.Error(w, "Query failed", http.StatusInternalServerError)
return
}
defer rows.Close()
css
var inventories []Inventory
for rows.Next() {
var inv Inventory
if err := rows.Scan(&inv.ID, &inv.ProductID, &inv.Quantity, &inv.UpdatedAt); err != nil {
http.Error(w, "Scan failed", http.StatusInternalServerError)
return
}
inventories = append(inventories, inv)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(inventories)
}
まあ、ぱっと見めっちゃ直感的じゃない?しかもこのコードスニペットで1分あたり数千件リクエスト対応とか謳われてたし。うーん、ほんとに?って疑いたくなるけど実際そうだったらしい…。標準ライブラリの`net/http`とか`encoding/json`使えば追加パッケージ依存ほぼなしで済むし(PostgreSQL用の`lib/pq`みたいなの除けば)。ここ最近、「もっと便利なフレームワーク使え」みたいな空気あるけど…実はそうでもなくて…純正エコシステムで十分だった。
## 並行処理の容易さ
サプライヤーAPI連携については、多数の外部API同時ポーリング必須だったんだけど、これGoだとやっぱゴルーチン一択になっちゃう。不思議と昔からスレッド嫌いなのにGoでは素直に受け入れられる自分にちょっと笑う。その上他言語みたいにasync/await地獄になりづらくてさぁ……下手したらミスる場所少ないよね。一例としてこんな統合処理書いてた: go
func pollSuppliers(supplierURLs []string) ([]SupplierData, error) {
var results []SupplierData
var mu sync.Mutex
var wg sync.WaitGroup
css
for _, url := range supplierURLs {
wg.Add(1)
go func(u string) {
defer wg.Done()
resp, err := http.Get(u)
if err != nil {
log.Printf("Error fetching %s: %v", u, err)
return
}
defer resp.Body.Close()
css
var data SupplierData
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
log.Printf("Error decoding %s: %v", u, err)
return
}
mu.Lock()
results = append(results, data)
mu.Unlock()
}(url)
}
wg.Wait()
return results, nil
}
こういうコードね、高パフォーマンス維持しながら可読性も保っている感じ。ま、新人開発者だって理解できたくらいなのでそこはメリット。「ほんとうかな?」と思った人、自分も最初疑って試したけど意外とうまく回った。Go特有の並行処理モデルは、「業務フロー管理ラク」と評価されること多かった。
## デプロイメントの快適さ
AWSへデプロイメントするときも実は結構楽だった報告あるし。「単一バイナリ」出力できるから、そのままパッケージ化してEC2インスタンスへアップロード、その後即実行可能――妙に夢みたい?ただそれ現実なんだよね。この場合追加ランタイムや依存管理ツールなし運用記録ありという点も、おお…となった(地味な感動)。CI/CDパイプラインではGitHub Actions利用していて、バイナリ生成・テスト・本番反映まで5分以内完了していたというので正直凄いと思った。ただ5ヶ月目には投資家にもMVP(Minimum Viable Product)が一定評価された―まあ完全じゃなくても最低限形になれば十分、と当時自分を納得させていた節ある。
サプライヤ連携はゴルーチン頼みで楽勝気分
私たちは200万ドルのシード資金を調達できて、なんかちょっと現実味がなかったんだけど、ともあれエンジニアも増やしてプラットフォーム拡大のフェーズに突入した。いや、正直ここまで来るとは思ってなかった気もする。Goはまあ期待通り動いてくれてて、プロジェクト自体は順調だった。ま、それだけじゃ語れないんだけど。
## 問題の兆候
MVPからいよいよ本格的な製品へ舵を切ったタイミングで、要件がじわじわと複雑になってきた。例えば機械学習による需要予測だとか、動的価格設定アルゴリズム、それにサードパーティ統合用のモジュラー型プラグインシステム――要素がどんどん追加されていった。ああ、こんなの最初に想像してなかったなとぼやきつつ…。そうなるとさっきまで「これこそ強み!」と思ってたGoのミニマル設計が急に窮屈に感じ始めてきたわけで。一回話逸れるけど、欲張るほど足元すくわれるというか…でも話戻すと、その制約感は日に日に増していた。
## 静的型付けによる柔軟性の課題
Goの静的型付け――しかもその頃(えっとGo 1.18以前)ジェネリクス非対応だったから、とにかく複雑なデータ構造への対応が億劫になった。需要予測モジュールではARIMAとかLSTMなど色々なアルゴリズムを状況次第で切り替える機械学習パイプラインを作りたかったんだ。でもPythonなら動的型付けや抽象基底クラスのおかげで、その辺かなり容易なんだよね。うーん、羨ましい。しかしGoでは無駄に冗長というか繰り返しばかりのコードを書く羽目になる。それでも手は止められない。
func (m ARIMAModel) Predict(data []float64) ([]float64, error) {
// ARIMA予測ロジック
return nil, nil
}
func (m LSTMModel) Predict(data []float64) ([]float64, error) {
// LSTM予測ロジック
return nil, nil
}
結局ジェネリクスが使えないことで違うモデル間で共通利用できるデータ処理関数を書くことはもうほぼ不可能だった。そのせいでコードベースにはボイラープレート(定型文)が溢れ出し、新しいモデルを追加する度に似たような処理を何度も何度も書く羽目になった。本当に面倒くさい…ま、でも誰も代わってくれないので仕方なく続行するしかない。
## 問題の兆候
MVPからいよいよ本格的な製品へ舵を切ったタイミングで、要件がじわじわと複雑になってきた。例えば機械学習による需要予測だとか、動的価格設定アルゴリズム、それにサードパーティ統合用のモジュラー型プラグインシステム――要素がどんどん追加されていった。ああ、こんなの最初に想像してなかったなとぼやきつつ…。そうなるとさっきまで「これこそ強み!」と思ってたGoのミニマル設計が急に窮屈に感じ始めてきたわけで。一回話逸れるけど、欲張るほど足元すくわれるというか…でも話戻すと、その制約感は日に日に増していた。
## 静的型付けによる柔軟性の課題
Goの静的型付け――しかもその頃(えっとGo 1.18以前)ジェネリクス非対応だったから、とにかく複雑なデータ構造への対応が億劫になった。需要予測モジュールではARIMAとかLSTMなど色々なアルゴリズムを状況次第で切り替える機械学習パイプラインを作りたかったんだ。でもPythonなら動的型付けや抽象基底クラスのおかげで、その辺かなり容易なんだよね。うーん、羨ましい。しかしGoでは無駄に冗長というか繰り返しばかりのコードを書く羽目になる。それでも手は止められない。
type Model interface {
Predict(data []float64) ([]float64, error)
}
type ARIMAModel struct {
// ARIMA特有フィールド
}
func (m ARIMAModel) Predict(data []float64) ([]float64, error) {
// ARIMA予測ロジック
return nil, nil
}
type LSTMModel struct {
// LSTM特有フィールド
}
func (m LSTMModel) Predict(data []float64) ([]float64, error) {
// LSTM予測ロジック
return nil, nil
}
結局ジェネリクスが使えないことで違うモデル間で共通利用できるデータ処理関数を書くことはもうほぼ不可能だった。そのせいでコードベースにはボイラープレート(定型文)が溢れ出し、新しいモデルを追加する度に似たような処理を何度も何度も書く羽目になった。本当に面倒くさい…ま、でも誰も代わってくれないので仕方なく続行するしかない。

一発デプロイ!バイナリだけ持ってAWSへ直行した話
Go 1.18でジェネリクスが導入されたとき、うーん、正直なところ最初は「これで全部うまくいくんじゃないか」と少し期待してた。でも現実は…そう単純でもなくて。エコシステム自体がまだ発展途上だったから、既存のライブラリとうまく一体化させるのにも色々手間取った。というか、「あれ?なんか使いにくいぞ」って感じた瞬間も多かった気がする。もちろん新しい道具をすぐに試したい気持ちもあったけど、結局思ったより障壁が高かったなぁ、と今になって思う。
高度なユースケース向けのエコシステム…これは本当に悩みどころだった。「まあ標準ライブラリだけで十分だろ?」とか甘く考えていた自分を叱りたいぐらい。MVP開発にはGoの標準機能でも特に困らないんだけど、例えば機械学習とかダイナミックプライシングみたいな話になると…やっぱり第三者製のもの頼みになっちゃうわけですよ。Python界隈だとNumPyやPandas、それこそTensorFlowまで山ほどあるじゃないですか。でもGo側となると選択肢は決して多くなくてね。Gonumとかは確かに基本的な数値計算では役立つんだけど、「洗練されてる?」と言われればちょっと首を傾げざるを得ない部分も見受けられるし…。コミュニティサポートも正直そこまで潤沢とは言えず。一瞬話逸れたかな?ともかく、その結果として結局機械学習系タスクはPythonサービス側へ任せることになってしまって、アーキテクチャ全体もちょっと複雑化したような感覚だった。
さて柔軟性の話だけど…急速プロトタイピングへの対応力についても不満が残った気がする。我々のプラグインシステムではサードパーティ開発者による拡張を前提として設計していて、本当ならFlask(Python)のBlueprintとかExpress(Node.js)のミドルウェアみたいに自由自在にロジックを書き足せれば理想だった。ただしGoの場合、この辺り構造的にもハードル高めで、「あれ?簡単にはいかないぞ」と何度も思わされた…。それで結局gRPCによる通信方式へ移行することになった。でもこの方法だとprotoファイル作成からコンパイルまで細かな作業増えるし、その都度イテレーション速度落ちている印象さえ覚えた。不便だよねぇ、ほんと。それでも仕方なく進めていたところもありつつ―まあ、もう少し柔軟なら良かったと思わずにはいられない今日この頃です。
高度なユースケース向けのエコシステム…これは本当に悩みどころだった。「まあ標準ライブラリだけで十分だろ?」とか甘く考えていた自分を叱りたいぐらい。MVP開発にはGoの標準機能でも特に困らないんだけど、例えば機械学習とかダイナミックプライシングみたいな話になると…やっぱり第三者製のもの頼みになっちゃうわけですよ。Python界隈だとNumPyやPandas、それこそTensorFlowまで山ほどあるじゃないですか。でもGo側となると選択肢は決して多くなくてね。Gonumとかは確かに基本的な数値計算では役立つんだけど、「洗練されてる?」と言われればちょっと首を傾げざるを得ない部分も見受けられるし…。コミュニティサポートも正直そこまで潤沢とは言えず。一瞬話逸れたかな?ともかく、その結果として結局機械学習系タスクはPythonサービス側へ任せることになってしまって、アーキテクチャ全体もちょっと複雑化したような感覚だった。
さて柔軟性の話だけど…急速プロトタイピングへの対応力についても不満が残った気がする。我々のプラグインシステムではサードパーティ開発者による拡張を前提として設計していて、本当ならFlask(Python)のBlueprintとかExpress(Node.js)のミドルウェアみたいに自由自在にロジックを書き足せれば理想だった。ただしGoの場合、この辺り構造的にもハードル高めで、「あれ?簡単にはいかないぞ」と何度も思わされた…。それで結局gRPCによる通信方式へ移行することになった。でもこの方法だとprotoファイル作成からコンパイルまで細かな作業増えるし、その都度イテレーション速度落ちている印象さえ覚えた。不便だよねぇ、ほんと。それでも仕方なく進めていたところもありつつ―まあ、もう少し柔軟なら良かったと思わずにはいられない今日この頃です。
投資を受けて拡大、でもGoに苛立ち…型の壁現る
例えばさ、カスタムアナリティクスをちょっと追加したいだけなのに、やたらと面倒なコードを書かされる羽目になるんだよね。まあ、例としてはこんな感じだったかな:
syntax = "proto3";
<pre><code class="language-css">package plugin;css
service AnalyticsPlugin {
rpc ProcessData (DataRequest) returns (DataResponse);
}
css
message DataRequest {
repeated double values = 1;
}
css
message DataResponse {
repeated double results = 1;

MLや動的な仕組み欲しさにPython混ぜ始めた時期
2. パフォーマンスが要求されるシステムについてだけど、やっぱり高スループットとか低レイテンシのニーズがあるアプリケーション、たとえばAPIやマイクロサービスみたいなのだと、Goはかなりパフォーマンス面で評価されてるらしい。うーん、なんでそんなに…と思ったけど、実際動かしてみると「ああ、なるほど」って感じの軽さなんだよね。でもまあ、全部が全部そうとは限らないし、自分の体感だけで語るのもどうかとちょっと反省しつつ、本題に戻すけど、とにかくGoは性能を求める現場では選択肢になることが多いっぽい。
3. 並行処理のワークロードについては…えっと、その、ゴルーチンとかチャネルのおかげで並行タスクが得意ってよく聞く。リアルタイムなデータ処理とかイベント駆動型システムにも向いていると言われているけど、自分自身「本当に?」って思いながら使い始めた記憶がある。ま、ちゃんと動いてくれて助かったから文句はないかな。余談だけど、この辺り妙に安心感あるんだよね…なんでだろう。ともあれ、多数のタスクを同時に回したい場面にはGoはそこそこ頼れる存在になっている気がする。
4. 小規模チームの場合について書こうとして…あっ脱線しそうだった、ごめん戻す。ミニマリズム志向というか無駄を極力排した設計と強制的なコーディングスタイル(`go fmt`みたいなやつ)のおかげでコード全体の一貫性が保たれるわけなんだけど、それゆえに小さいチームでも作業を進めやすいという話をちらほら耳にする。ふーん…それって地味だけど結構ありがたいことだと思うんだ。自分も何度か救われた経験あるし、小規模開発には相性良さそう。
5. シンプルなデプロイメントについて語るなら…単一バイナリとして出力される点かな。それこそクラウドネイティブアプリケーションの場合、デプロイ作業まで一気に楽になるという意見を見ることが多いけど、「ほんと?」と思いつつ自分も試したら案外簡単だった。ま、いいか。それだけでも導入ハードル下がるし運用負荷も減った気がするので悪くない印象は持っている。
## 代替手段を検討する場面
1. 複雑なデータモデリングではちょっと悩むところがあって…。アプリケーション側で複雑なデータ構造とか動的な挙動まで必要になった場合だよね。その場合Go特有の静的型付けや(バージョン1以前ならジェネリクス非対応だったりして)、思った通り柔軟には扱えない可能性も否定できなくて…。まあしょうがない部分もあるとは思う。でも、「ここだけ他言語使いたい!」みたいな気持ちになる瞬間もちょこちょこ訪れるので、一応頭の片隅には置いておきたいポイントかな。
3. 並行処理のワークロードについては…えっと、その、ゴルーチンとかチャネルのおかげで並行タスクが得意ってよく聞く。リアルタイムなデータ処理とかイベント駆動型システムにも向いていると言われているけど、自分自身「本当に?」って思いながら使い始めた記憶がある。ま、ちゃんと動いてくれて助かったから文句はないかな。余談だけど、この辺り妙に安心感あるんだよね…なんでだろう。ともあれ、多数のタスクを同時に回したい場面にはGoはそこそこ頼れる存在になっている気がする。
4. 小規模チームの場合について書こうとして…あっ脱線しそうだった、ごめん戻す。ミニマリズム志向というか無駄を極力排した設計と強制的なコーディングスタイル(`go fmt`みたいなやつ)のおかげでコード全体の一貫性が保たれるわけなんだけど、それゆえに小さいチームでも作業を進めやすいという話をちらほら耳にする。ふーん…それって地味だけど結構ありがたいことだと思うんだ。自分も何度か救われた経験あるし、小規模開発には相性良さそう。
5. シンプルなデプロイメントについて語るなら…単一バイナリとして出力される点かな。それこそクラウドネイティブアプリケーションの場合、デプロイ作業まで一気に楽になるという意見を見ることが多いけど、「ほんと?」と思いつつ自分も試したら案外簡単だった。ま、いいか。それだけでも導入ハードル下がるし運用負荷も減った気がするので悪くない印象は持っている。
## 代替手段を検討する場面
1. 複雑なデータモデリングではちょっと悩むところがあって…。アプリケーション側で複雑なデータ構造とか動的な挙動まで必要になった場合だよね。その場合Go特有の静的型付けや(バージョン1以前ならジェネリクス非対応だったりして)、思った通り柔軟には扱えない可能性も否定できなくて…。まあしょうがない部分もあるとは思う。でも、「ここだけ他言語使いたい!」みたいな気持ちになる瞬間もちょこちょこ訪れるので、一応頭の片隅には置いておきたいポイントかな。
プラグイン地獄:gRPCとprotoファイル、開発者は困惑顔
18) は冗長なコードにつながる場合がある。ああ、なんかもう面倒になってくることもあるよね。PythonやTypeScriptのような言語は、もっと柔軟性を提供してくれるし、自由度も高い気がする。でも本当にそれだけでいいのか自分でも疑問だ。うーん、ときどき迷走するけど、本題へ戻ろう。
2. **機械学習またはデータサイエンス**: Goのエコシステムには、高度な分析向けに成熟したライブラリが正直まだ十分揃っていない感じが否めない。実はそうでもなくて…という期待もあるんだけど、今のところ機械学習やデータ集約型アプリケーションではPythonみたいに豊富なエコシステムを持つ言語が好まれる傾向が強いらしい。こういう分野って時々流行り廃り激しくて、自分でも全部追えてるか怪しい。
3. **サードパーティとの迅速なプロトタイピング**: プラットフォーム構築中にプラグインシステムを用意したり、サードパーティ開発者への対応とか求められるとき、Goの厳格さはちょっと壁になることもある。Node.jsやPythonだと、そのへん動的で扱いやすい環境を開発者側にもたらしてくれる印象は確かにあるね。しかし、この「使いやすさ」って本当に良いことなのかな…って思考停止しそうになったので話戻します。
4. **メタプログラミングのニーズ**: アプリケーションでデコレーターやマクロ、それから実行時コード生成なんて抽象化まで必要になる場合、Goではどうしてもメタプログラミング機能が不足していて不便だと感じる瞬間が出てくる。RubyやPython、この領域については適していると言われて久しい(ま、いいか)。
## 今後の方針:ハイブリッドアプローチ
Goを完全に廃止するわけじゃなくて――結局ハイブリッドアーキテクチャを採用した。その中核となるバックエンドサービス(在庫管理とかサプライヤー連携、それからAPIルーティング)については引き続きGoで維持しつつ、その性能だったり並行処理能力みたいな利点を最大限活用する方向です。途中ふと、「他の選択肢もあったんじゃ?」と思ったりしたけど、とりあえず今はこの道しかないような気分で進めている。
2. **機械学習またはデータサイエンス**: Goのエコシステムには、高度な分析向けに成熟したライブラリが正直まだ十分揃っていない感じが否めない。実はそうでもなくて…という期待もあるんだけど、今のところ機械学習やデータ集約型アプリケーションではPythonみたいに豊富なエコシステムを持つ言語が好まれる傾向が強いらしい。こういう分野って時々流行り廃り激しくて、自分でも全部追えてるか怪しい。
3. **サードパーティとの迅速なプロトタイピング**: プラットフォーム構築中にプラグインシステムを用意したり、サードパーティ開発者への対応とか求められるとき、Goの厳格さはちょっと壁になることもある。Node.jsやPythonだと、そのへん動的で扱いやすい環境を開発者側にもたらしてくれる印象は確かにあるね。しかし、この「使いやすさ」って本当に良いことなのかな…って思考停止しそうになったので話戻します。
4. **メタプログラミングのニーズ**: アプリケーションでデコレーターやマクロ、それから実行時コード生成なんて抽象化まで必要になる場合、Goではどうしてもメタプログラミング機能が不足していて不便だと感じる瞬間が出てくる。RubyやPython、この領域については適していると言われて久しい(ま、いいか)。
## 今後の方針:ハイブリッドアプローチ
Goを完全に廃止するわけじゃなくて――結局ハイブリッドアーキテクチャを採用した。その中核となるバックエンドサービス(在庫管理とかサプライヤー連携、それからAPIルーティング)については引き続きGoで維持しつつ、その性能だったり並行処理能力みたいな利点を最大限活用する方向です。途中ふと、「他の選択肢もあったんじゃ?」と思ったりしたけど、とりあえず今はこの道しかないような気分で進めている。

リファクタ難民化・メタプロなくて乾いた笑い
機械学習やプラグインシステムみたいな、ああいう複雑な機能に関してはね、Pythonのマイクロサービスをわざわざ導入したんだよ。うーん、まあ、そのせいでGoバックエンドとはgRPCで通信することになった。正直言って、この方法にはもちろん問題も出てきた。2つの言語を並行して管理しなきゃならなくなったし、その運用の煩雑さが日々じわじわと増えていく感じだった。でもね、サービス間通信がボトルネック化しないように堅牢なモニタリングへ投資したから…いや、本当に必要だったんだろうか、と一瞬思ったけど、結局そうしないと不安で仕方なかった。それでも、このアプローチによってGo特有の高速性という強みと、Pythonが持つ柔軟さを両立できたと思う。ま、いいか。それぞれの利点を引き出す結果になったはず。
スタートアップ向け主なポイントについて話す前に…ああ、ごめん、ちょっと水飲むね。(ごくごく)…はい戻る。Goについて自分たちがやってきたことから得られた知見として、「テクノロジー選び」を迷っている他のスタートアップにも伝えたいことがある。
まず、自社フェーズに合ったスタック選定なんだけど――要するにMVPとかパフォーマンス重視ならGoは本当に使える。ただ要件が複雑になり始めると全部カバーできる保証はなくて、それこそ長期的視点で考えるべきだと思う。「一つの言語だけで突っ走る」前によく考え直す時間も必要になるかな…と時々思う。
それからポリグロットアーキテクチャも現実的な選択肢として挙げられる。もちろん複数言語運用は煩雑なんだけど、それぞれ異なる強みを活かせるチャンスにもなるので、「面倒だから全部同じ」で済ませちゃダメなのかもしれない。マイクロサービスとか明確なAPI設計さえ徹底できれば、案外どうにかなる気もしてきたり。
あと開発者体験への投資も忘れてはいけないポイントだよね…。自分の場合プラットフォーム上でサードパーティ開発者との連携場面では「利便性」が最大級に重要だった。こういうケースだと、生産性や柔軟性がパフォーマンスより優先されることもしばしば起こる。不思議なんだけど事実なんだよね。
ま、とりあえず以上かな。また何か思いついたら書き足したいけど、とり急ぎこのくらいにしておくよ…。
スタートアップ向け主なポイントについて話す前に…ああ、ごめん、ちょっと水飲むね。(ごくごく)…はい戻る。Goについて自分たちがやってきたことから得られた知見として、「テクノロジー選び」を迷っている他のスタートアップにも伝えたいことがある。
まず、自社フェーズに合ったスタック選定なんだけど――要するにMVPとかパフォーマンス重視ならGoは本当に使える。ただ要件が複雑になり始めると全部カバーできる保証はなくて、それこそ長期的視点で考えるべきだと思う。「一つの言語だけで突っ走る」前によく考え直す時間も必要になるかな…と時々思う。
それからポリグロットアーキテクチャも現実的な選択肢として挙げられる。もちろん複数言語運用は煩雑なんだけど、それぞれ異なる強みを活かせるチャンスにもなるので、「面倒だから全部同じ」で済ませちゃダメなのかもしれない。マイクロサービスとか明確なAPI設計さえ徹底できれば、案外どうにかなる気もしてきたり。
あと開発者体験への投資も忘れてはいけないポイントだよね…。自分の場合プラットフォーム上でサードパーティ開発者との連携場面では「利便性」が最大級に重要だった。こういうケースだと、生産性や柔軟性がパフォーマンスより優先されることもしばしば起こる。不思議なんだけど事実なんだよね。
ま、とりあえず以上かな。また何か思いついたら書き足したいけど、とり急ぎこのくらいにしておくよ…。
ハイブリッド構成で再浮上 学びと次への指針
リファクタリング計画って、まあ結局プロダクトが生き物みたいに進化する以上、コードベースもそりゃあ変わるんですよね。なんだかんだで…あ、いま急に窓の外の鳥を見てしまったけど戻すと、特に反復開発のペースが速い場合は、リファクタリングしやすい言語を選ばなきゃあと後悔する羽目になることも多かった気がします。えっと、一瞬「どこまで柔軟さを重視するべきなのか」自分でも迷う時あるけれど、大切な点ではありますよ。
5. チームの強み…って正直つかみにくい時あるよなぁ。Goってシンプルだけど、そのぶん小規模で経験浅めのチームには逆に追い風になったりもします。ああ、でももしエンジニア陣が動的言語に慣れていて「今さら堅苦しい書き方無理!」とか思ってたら、それを無理やり矯正する意味ないよね、多分。それぞれの持ち味というか性質をうまく活かせたほうがいいし。
## 結論: スタートアップ界隈でGoはどうだった?
Goはね、なんとなく我々のスタートアップでは派手じゃなくて静かな存在だった。でも、不思議とMVP構築とか資金調達みたいな時間勝負の局面では着実に力になってくれたような…。えーと、そのシンプルさとかパフォーマンス、それから並行処理できるモデル――初期段階にはピッタリ合致していた記憶があります。ただ同時にプラットフォーム拡張期にはGo本来のミニマリズム設計ゆえの壁にも何度かぶつかったっけ(そういや徹夜明けの日はなおさら辛かった)。脇道それたけど、ともあれこの経験でチーム全体として成長した部分もあるし、「ここはGo!」「ここは他言語!」と柔軟さ高めてバランス取れるようになりました。同じような立場なら、スタートアップで迷ったらGo一択!…と言いたいところだけど実際は万能じゃありません。えっと、本当に頼るべき得意領域、それから新課題向き合うため他技術へ乗換えるタイミング見極め——これ大事です。
> 最終的には技術そのものがゴールじゃなく、本当にユーザーへ価値届けているか?そこが問われるわけです。環境次第で最良ツール選び・切替え続ける柔軟性こそ肝心かなと思います(ま、それ難しいこと多々あるんだけど)。自分たちは偶然にもGoという場所から歩み始めました。そして変化ばっかり起こる日常だからこそ、「型にはまらない姿勢」さえ学びになった気がしています。不器用でも構わないよね。
5. チームの強み…って正直つかみにくい時あるよなぁ。Goってシンプルだけど、そのぶん小規模で経験浅めのチームには逆に追い風になったりもします。ああ、でももしエンジニア陣が動的言語に慣れていて「今さら堅苦しい書き方無理!」とか思ってたら、それを無理やり矯正する意味ないよね、多分。それぞれの持ち味というか性質をうまく活かせたほうがいいし。
## 結論: スタートアップ界隈でGoはどうだった?
Goはね、なんとなく我々のスタートアップでは派手じゃなくて静かな存在だった。でも、不思議とMVP構築とか資金調達みたいな時間勝負の局面では着実に力になってくれたような…。えーと、そのシンプルさとかパフォーマンス、それから並行処理できるモデル――初期段階にはピッタリ合致していた記憶があります。ただ同時にプラットフォーム拡張期にはGo本来のミニマリズム設計ゆえの壁にも何度かぶつかったっけ(そういや徹夜明けの日はなおさら辛かった)。脇道それたけど、ともあれこの経験でチーム全体として成長した部分もあるし、「ここはGo!」「ここは他言語!」と柔軟さ高めてバランス取れるようになりました。同じような立場なら、スタートアップで迷ったらGo一択!…と言いたいところだけど実際は万能じゃありません。えっと、本当に頼るべき得意領域、それから新課題向き合うため他技術へ乗換えるタイミング見極め——これ大事です。
> 最終的には技術そのものがゴールじゃなく、本当にユーザーへ価値届けているか?そこが問われるわけです。環境次第で最良ツール選び・切替え続ける柔軟性こそ肝心かなと思います(ま、それ難しいこと多々あるんだけど)。自分たちは偶然にもGoという場所から歩み始めました。そして変化ばっかり起こる日常だからこそ、「型にはまらない姿勢」さえ学びになった気がしています。不器用でも構わないよね。