
サービスが少なければ、設定に直接アドレスを書けます。インスタンスが増えると、アドレスの変更や一時的な障害に対応するため、「現在、このサービスにはどのインスタンスがあるか」を記録する場所が必要になります。Consul は登録、発見、ヘルスチェックを提供します。
1. 登録と発見とは
- 登録:インスタンス ID、サービス名、アドレス、ポートを Consul に伝えます。
- 発見:サービス名で条件に合うインスタンスを探し、呼び出す先を選びます。
- ヘルスチェック:状態を記録し、異常なインスタンスを除外できるようにします。
登録済みと業務の利用可能性は別です。状態を確認し、呼び出しにはタイムアウトとエラー処理を設けます。チェック成功は次の要求の成功を保証しません。関連する API は Health API。
2. 導入と起動
Docker でローカル開発用のインスタンスを起動します。1.21.3 は以前の学習環境に合わせた固定値で、本番でその版を使い続ける推奨ではありません。
docker run -d \
--name dev-consul \
-p 127.0.0.1:8500:8500 \
hashicorp/consul:1.21.3 agent -dev -client=0.0.0.0
ブラウザで http://127.0.0.1:8500。-dev は開発モードで、終了後の本番状態の保持には使えません。ポートの対応付けのためコンテナ内では全アドレスを待ち受けますが、ホスト側はローカルに制限します。


3. Go から登録と発見を行う
新しい例のディレクトリでモジュールを初期化します。
go mod init example.com/consul-demo
次のコードを main.go に保存し、後の手順で依存を導入します。
package main
import (
"fmt"
"net/http"
"os"
"time"
"github.com/hashicorp/consul/api"
)
func run() error {
cfg := api.DefaultConfig()
cfg.Address = "127.0.0.1:8500"
cfg.HttpClient = &http.Client{Timeout: 3 * time.Second}
client, err := api.NewClient(cfg)
if err != nil {
return err
}
registration := &api.AgentServiceRegistration{
ID: "demo-api-1", Name: "demo-api",
Address: "127.0.0.1", Port: 18080,
Check: &api.AgentServiceCheck{TTL: "15s"},
}
if err := client.Agent().ServiceRegister(registration); err != nil {
return err
}
defer func() {
if err := client.Agent().ServiceDeregister(registration.ID); err != nil {
fmt.Println("注销失败:", err)
}
}()
if err := client.Agent().UpdateTTL("service:demo-api-1", "demo heartbeat", "passing"); err != nil {
return err
}
services, _, err := client.Health().Service("demo-api", "", true, nil)
if err != nil {
return err
}
for _, entry := range services {
fmt.Printf("%s %s:%d\n", entry.Service.ID, entry.Service.Address, entry.Service.Port)
}
return nil
}
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, "Consul 示例失败:", err)
os.Exit(1)
}
}
保存後、例で使う SDK の版を導入して実行します。
go get github.com/hashicorp/consul/api@v1.30.0
go mod tidy
go run .
API の再現用に版を固定しています。変更時には再確認し、go.mod と go.sum を保持します。登録、TTL の更新、正常なインスタンスの検索、終了時の解除を示す例です。18080 番に業務サーバーを起動するものではなく、表示されたアドレスだけで利用可能とは判断できません。Go SDK の API と サービス登録 API を併せて確認できます。
実際のアプリでは、業務サーバーを起動してから到達可能なアドレスを登録します。TTL は定期的に更新し、状態に応じて passing か critical を報告します。HTTP チェックを使う場合は、Consul agent からエンドポイントへ接続できることを確認します。
4. 注意点
サービス名とインスタンス ID は別です。複数のインスタンスが demo-api という名前でも、ID は別にしないと登録を上書きします。
アドレスは利用者が接続するものです。ここでの 127.0.0.1 は同じホスト上の呼び出しに限ります。機械やコンテナをまたぐ場合は、実際に到達できるアドレスを登録します。
登録解除だけでは障害に対応できないため、正常終了では解除し、強制終了にはヘルスチェックで対応します。正常な候補を検索しても、タイムアウトや接続失敗は処理します。
KV ストアを何でも保存するデータベースと考えないようにします。設定などには使えますが、権限、更新通知、読み取り失敗時の動作を検討します。