Skip to content

トラブルシューティング

Blog Service 開発・運用時によくある問題と解決策をまとめています。

データベース関連

問題: MySQL接続エラー

症状

Error 1045 (28000): Access denied for user 'root'@'localhost'

原因と解決策

原因1: パスワードが間違っている

bash
# 正しいパスワードを確認
cat docker-compose.yaml | grep MYSQL_ROOT_PASSWORD

# 接続テスト
mysql -u root -p -h localhost -P 3306

原因2: MySQLコンテナが起動していない

bash
# コンテナ状態確認
docker compose ps

# コンテナ再起動
docker compose restart mysql

原因3: ポートが衝突している

bash
# ポート使用状況確認
lsof -i :3306

# 衝突している場合は該当プロセスを停止
# または docker-compose.yaml でポート変更

問題: マイグレーション失敗

症状

atlas migrate apply: executing statement: table 'articles' already exists

解決策

手動でマイグレーション状態をリセット

bash
# 現在の状態確認
make atlas-status-dev

# マイグレーション履歴テーブルを確認
mysql -u root -p -h localhost -D dev -e "SELECT * FROM atlas_schema_revisions;"

# 問題のあるマイグレーションをスキップ
atlas migrate set --dir "file://migrate/migrations" --url "mysql://root:password@localhost:3306/dev" <version>

データベースを初期化してやり直し

bash
# データベースをドロップして再作成
docker compose down -v
docker compose up -d
make atlas-apply-dev

問題: マイグレーション競合

症状

複数の開発者が同時にマイグレーションを作成し、競合が発生

解決策

bash
# 最新のmainブランチから更新
git checkout main
git pull origin main

# 新しいマイグレーション作成
git checkout feature-branch
git rebase main
make atlas-diff name=fix_migration_conflict

# 競合したマイグレーションファイルを手動修正

開発環境

問題: Goモジュールエラー

症状

go: module github.com/example/package@v1.0.0: reading module: module not found

解決策

bash
# モジュールキャッシュをクリア
go clean -modcache

# 依存関係を再取得
go mod tidy
go mod download

# Goのプロキシを無効化(企業環境の場合)
export GOPROXY=direct
export GOSUMDB=off

問題: Wire生成エラー

症状

wire: /path/to/file.go:10:1: inject undefined

解決策

bash
# Wireタグの確認
//go:build wireinject
// +build wireinject

# Wireの再インストール
go install github.com/google/wire/cmd/wire@latest

# 生成ファイルを削除して再生成
rm di/wire_gen.go
make wire-gen

問題: ent生成エラー

症状

entc: schema description failed: template: <...>: undefined function

解決策

bash
# entのバージョン確認
go list -m entgo.io/ent

# スキーマファイルの構文確認
make ent-describe

# 生成ファイルを削除して再生成
rm -rf internal/infrastructure/ent/generated
make ent-generate

API関連

問題: 認証エラー

症状

json
{
  "apiVersion": "1.0.0",
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid token"
  }
}

解決策

JWTトークンの確認

bash
# トークンの形式確認(3つの部分に分かれているか)
echo "eyJ0eXAiOiJKV1..." | cut -d'.' -f1,2,3

# トークンの有効期限確認
# https://jwt.io/ でデコード

認証サービスとの接続確認

bash
# 認証サービスのヘルスチェック
curl -X GET https://auth-service/health

# ネットワーク接続確認
ping auth-service-host

問題: バリデーションエラー

症状

json
{
  "apiVersion": "1.0.0",
  "error": {
    "code": "VALIDATION_ERROR", 
    "message": "title is required"
  }
}

解決策

リクエストボディの確認

bash
# 正しいJSONフォーマットか確認
echo '{"title":"test","content":"test"}' | jq .

# 必須フィールドが含まれているか確認
curl -X POST http://localhost:8080/blog-service/v1/articles \
  -H "Content-Type: application/json" \
  -d '{"title":"記事タイトル","content":"記事本文","tagIds":[],"category":"tech"}'

問題: タイムアウトエラー

症状

context deadline exceeded

解決策

データベースクエリの最適化

bash
# 遅いクエリログを確認
mysql -u root -p -e "SHOW VARIABLES LIKE 'slow_query_log';"

# インデックスの確認
mysql -u root -p -D dev -e "SHOW INDEX FROM articles;"

接続プールの調整

go
// 設定例
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)

テスト関連

問題: テスト失敗

症状

FAIL: TestCreateArticle: expected status 201, got 500

解決策

詳細なログ出力

bash
# テストを詳細モードで実行
go test -v ./internal/usecase/article/

# 特定のテストのみ実行
go test -v -run TestCreateArticle ./internal/usecase/article/

テストデータベースの確認

bash
# テスト用DB接続確認
TEST_DB_URL="mysql://root:password@localhost:3307/test" \
  mysql -u root -p -h localhost -P 3307 -e "SELECT 1;"

モックの問題

bash
# モックを再生成
make mock-gen

# モックの設定確認
grep -r "EXPECT" internal/domain/*/repository/mock/

問題: カバレッジが低い

解決策

bash
# 詳細なカバレッジレポート
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# パッケージ別カバレッジ
go test -cover ./internal/usecase/...
go test -cover ./internal/domain/...

パフォーマンス問題

問題: メモリリーク

症状

runtime: out of memory: cannot allocate xxx bytes

解決策

メモリプロファイリング

bash
# pprof でメモリ使用量確認
go tool pprof http://localhost:8080/debug/pprof/heap

# トップメモリ消費箇所の確認
(pprof) top10
(pprof) list function_name

ゴルーチンリーク確認

bash
# ゴルーチン数確認
go tool pprof http://localhost:8080/debug/pprof/goroutine

問題: 応答時間が遅い

解決策

CPUプロファイリング

bash
# CPU使用量プロファイル
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30

データベースクエリ最適化

sql
-- 遅いクエリの特定
SHOW PROCESSLIST;

-- クエリ実行計画の確認
EXPLAIN SELECT * FROM articles WHERE category = 'tech';

-- インデックス追加
CREATE INDEX idx_articles_category ON articles(category);

ログ・監視

問題: ログが出力されない

解決策

bash
# ログレベル確認
export LOG_LEVEL=debug

# ログファイルの権限確認
ls -la /var/log/blog-service/

# 標準出力にログ出力
export LOG_OUTPUT=stdout

問題: 構造化ログの問題

解決策

go
// 正しい構造化ログの例
logger.Info("article created",
    zap.String("articleId", article.ID),
    zap.String("userId", userID),
    zap.Duration("duration", time.Since(start)),
)

本番環境

問題: サービス起動失敗

症状

panic: dial tcp: connection refused

解決策

環境変数の確認

bash
# 環境変数が正しく設定されているか
env | grep -E "(DB_|JWT_|LOG_)"

# 設定ファイルの存在確認
ls -la /etc/blog-service/config.yaml

ネットワーク接続確認

bash
# データベースサーバーへの接続確認
telnet db-server 3306

# DNS解決確認
nslookup db-server

問題: 高負荷時のエラー

解決策

接続数制限の調整

yaml
# nginx設定例
upstream blog-service {
    server blog-service-1:8080 max_fails=3 fail_timeout=30s;
    server blog-service-2:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

データベース接続プール調整

go
// アプリケーション設定
config := mysql.Config{
    MaxOpenConns:        100,
    MaxIdleConns:        10,
    ConnMaxLifetime:     time.Hour,
    ConnMaxIdleTime:     time.Minute * 10,
}

よくある質問

Q: 新しい機能を追加する手順は?

  1. 新しいマイグレーション作成
  2. ent スキーマ更新
  3. ドメインエンティティ作成
  4. UseCase 実装
  5. HTTP ハンドラー追加
  6. OpenAPI 定義更新
  7. テスト作成

Q: 本番データベースのバックアップは?

bash
# mysqldump による定期バックアップ
mysqldump -u $DB_USER -p$DB_PASSWORD \
  --single-transaction \
  --routines \
  --triggers \
  $DB_NAME > backup_$(date +%Y%m%d_%H%M%S).sql

Q: ログの保持期間は?

  • アプリケーションログ: 30日
  • アクセスログ: 90日
  • エラーログ: 1年

詳細な設定は運用チームに確認してください。

更なるサポート

問題が解決しない場合は以下にお問い合わせください:

  • 開発チーム: #blog-service-dev
  • 運用チーム: #blog-service-ops
  • 緊急時: oncall@company.com