{
  "title": "ران تایم",
  "slug": "team/devops/runbook",
  "url": "/docs/team/devops/runbook",
  "frontmatter": {
    "layout": "doc",
    "title": "ران‌بوک عملیات",
    "description": "دفترچه راهنمای عملیات پلتفرم — کشیک، سطوح شدت، مسیر تشدید و بازیابی",
    "version": "1.0.0",
    "status": "PRIVATE",
    "author": "xoxxel",
    "owner": "xoxxel",
    "created_at": "2026-06-03",
    "updated_at": "2026-06-15",
    "tags": "",
    "reviewers": ""
  },
  "sections": [
    {
      "level": 1,
      "heading": "ران تایم",
      "content": "**نسخه:** v1.0  \n**دامنه:** تمام سرویس‌های تولیدی  \n**مخاطب:** مهندسان کشیک، SRE، عملیات پلتفرم  \n**آخرین به‌روزرسانی:** ۱۴۰۵-۰۳-۱۳ (2026-06-03)"
    },
    {
      "level": 2,
      "heading": "فهرست مطالب",
      "content": "- [مبانی کشیک](#مبانی-کشیک)\n- [سطوح شدت](#سطوح-شدت)\n- [مسیر تشدید](#مسیر-تشدید)\n- [ابزارهای تشخیص عمومی](#ابزارهای-تشخیص-عمومی)\n- [حوادث IAM](#حوادث-iam)\n- [حوادث کش](#حوادث-کش)\n- [حوادث Event Bus](#حوادث-event-bus)\n- [حوادث پایگاه داده](#حوادث-پایگاه-داده)\n- [حوادث Marketplace](#حوادث-marketplace)\n- [حوادث Wallet](#حوادث-wallet)\n- [پس از حادثه](#پس-از-حادثه)\n- [تماس‌ها و منابع](#تماسها-و-منابع)"
    },
    {
      "level": 2,
      "heading": "۱. مبانی کشیک",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۶۰ ثانیه اول هر حادثه",
      "content": "1. داشبورد مانیتورینگ را چک کنید → سرویس(های) تحت تأثیر را شناسایی کنید\n2. NATS DLQ را برای backlog رویدادها بررسی کنید\n3. وضعیت Redis را چک کنید\n4. تأخیر replication PostgreSQL را بررسی کنید\n5. شدت حادثه را تعیین کنید → بر اساس آن صفحه کنید\n6. کانال حادثه را باز کنید: `#incident-YYYY-MM-DD`\n7. وضعیت اولیه را پست کنید"
    },
    {
      "level": 3,
      "heading": "سیگنال‌های طلایی که اول باید چک کنید",
      "content": "| سیگنال                  | ابزار          | آستانه نگرانی                  |\n|-------------------------|----------------|--------------------------------|\n| نرخ خطا                | Grafana        | > ۱٪ درخواست‌ها               |\n| تأخیر (p99)            | Grafana        | > ۵۰۰ میلی‌ثانیه              |\n| اشباع (CPU/Mem)        | Grafana        | > ۸۰٪ پایدار                   |\n| تأخیر مصرف‌کننده NATS | داشبورد NATS  | > ۱۰۰۰ پیام                    |\n| حافظه Redis            | Redis Insight  | > ۸۵٪                          |\n| اتصالات Postgres       | Grafana        | > ۸۰٪ از حداکثر               |\n| تعداد پیام DLQ         | داشبورد NATS  | > ۱۰ پیام                      |"
    },
    {
      "level": 2,
      "heading": "۲. سطوح شدت",
      "content": "| سطح     | نام          | تعریف                                      | زمان پاسخگویی       | مثال‌ها |\n|---------|-------------|-------------------------------------------|---------------------|--------|\n| SEV-1  | بحرانی     | قطعی کل پلتفرم یا خطر از دست رفتن داده   | فوری — بیدار کردن همه | کاربران نمی‌توانند لاگین کنند، پرداخت‌ها شکست می‌خورند، خرابی DB |\n| SEV-2  | بالا        | ویژگی اصلی برای بخش قابل توجهی از کاربران خراب است | کمتر از ۱۵ دقیقه     | داده‌های IAM اشتباه، برداشت‌ها برای همه کاربران مسدود |\n| SEV-3  | متوسط      | تجربه کاربری کاهش یافته، راه‌حل جایگزین وجود دارد | کمتر از ۱ ساعت       | کندی موتور سیاست، تأخیر اعلان‌ها، خطای یک سرویس |\n| SEV-4  | پایین       | مشکل جزئی بدون تأثیر بر کاربر           | روز کاری بعدی       | نویز لاگ، پیام‌های تک DLQ، انحراف متریک غیربحرانی |"
    },
    {
      "level": 2,
      "heading": "۳. مسیر تشدید",
      "content": "```\nAlert → \nOn-call Engineer (L1) → \n(اگر حل نشد) Senior Engineer (L2) → \n(اگر حل نشد) Engineering Lead (L3) → \n(در صورت از دست رفتن داده یا قطعی طولانی) CTO + Legal\n```"
    },
    {
      "level": 3,
      "heading": "قوانین صفحه کردن",
      "content": "- **SEV-1:** همزمان L1 و L2 را صفحه کنید.\n- **SEV-2:** فقط L1 را صفحه کنید. L2 در حالت آماده‌باش.\n- **SEV-3:** L1 به صورت async مدیریت کند. خارج از ساعات اداری صفحه نشود.\n- **SEV-4:** تیکت ایجاد شود. صفحه نشود."
    },
    {
      "level": 2,
      "heading": "۴. ابزارهای تشخیص عمومی",
      "content": ""
    },
    {
      "level": 3,
      "heading": "چک کردن سلامت سرویس‌ها",
      "content": "```bash"
    },
    {
      "level": 1,
      "heading": "از طریق Gateway",
      "content": "curl -s http://localhost/v1/auth/health\ncurl -s http://localhost/v1/auth/ready"
    },
    {
      "level": 1,
      "heading": "مستقیم (فقط در شبکه داخلی کلاستر)",
      "content": "curl -s http://auth-service:3001/health\n```"
    },
    {
      "level": 3,
      "heading": "Kubernetes / K3d (تنها مسیر رسمی)",
      "content": "```bash"
    },
    {
      "level": 1,
      "heading": "بررسی وضعیت کلاستر",
      "content": "k3d cluster list\nkubectl cluster-info"
    },
    {
      "level": 1,
      "heading": "بررسی پادها",
      "content": "kubectl get pods -n nons-platform\nkubectl get pods -n nons-system\nkubectl describe pod <pod-name> -n nons-platform"
    },
    {
      "level": 1,
      "heading": "لاگ‌ها",
      "content": "kubectl logs <pod-name> -n nons-platform --tail=100\nkubectl logs -f -l app=auth-service -n nons-platform"
    },
    {
      "level": 1,
      "heading": "بررسی وضعیت Helm",
      "content": "helm list -n nons-platform\nhelm history nons-auth-service -n nons-platform\nhelm status nons-auth-service -n nons-platform"
    },
    {
      "level": 1,
      "heading": "بررسی IngressRoutes",
      "content": "kubectl get ingressroute -n nons-system\n```"
    },
    {
      "level": 3,
      "heading": "پایگاه داده PostgreSQL",
      "content": "```sql\n-- تعداد اتصالات\nSELECT count(*) FROM pg_stat_activity;\n\n-- کوئری‌های کند\nSELECT pid, now() - query_start AS duration, query\nFROM pg_stat_activity\nWHERE state = 'active' AND now() - query_start > interval '5 seconds'\nORDER BY duration DESC;\n```"
    },
    {
      "level": 3,
      "heading": "Redis",
      "content": "```bash"
    },
    {
      "level": 1,
      "heading": "از داخل کلاستر",
      "content": "kubectl run tmp-redis-cli --rm -i --tty --image=redis:alpine -n nons-platform -- redis-cli -h redis ping\nredis-cli -h $REDIS_HOST INFO\nredis-cli -h $REDIS_HOST INFO memory\nredis-cli -h $REDIS_HOST SLOWLOG GET 10\n```"
    },
    {
      "level": 3,
      "heading": "NATS",
      "content": "```bash"
    },
    {
      "level": 1,
      "heading": "از داخل کلاستر",
      "content": "kubectl exec -n nons-platform -it deployment/nons-nats -- nats stream list\ncurl http://$NATS_HOST:8222/healthz\nnats stream info IAM\nnats consumer info IAM marketplace-service-consumer\n```"
    },
    {
      "level": 3,
      "heading": "Helm (مدیریت استقرار)",
      "content": "```bash"
    },
    {
      "level": 1,
      "heading": "بررسی تاریخچه استقرار",
      "content": "helm history nons-auth-service -n nons-platform"
    },
    {
      "level": 1,
      "heading": "بازگشت به نسخه قبل",
      "content": "helm rollback nons-auth-service <revision> -n nons-platform"
    },
    {
      "level": 1,
      "heading": "مشاهده مقادیر جاری",
      "content": "helm get values nons-auth-service -n nons-platform\n```"
    },
    {
      "level": 3,
      "heading": "K3d (مدیریت کلاستر محلی)",
      "content": "```bash"
    },
    {
      "level": 1,
      "heading": "ایست/شروع کلاستر",
      "content": "k3d cluster stop nons\nk3d cluster start nons"
    },
    {
      "level": 1,
      "heading": "ایمپورت ایمیج جدید",
      "content": "k3d image import nons-auth-service:latest -c nons"
    },
    {
      "level": 1,
      "heading": "حذف و بازسازی کلاستر",
      "content": "k3d cluster delete nons\n```"
    },
    {
      "level": 2,
      "heading": "۵. حوادث IAM",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۵.۱ بازگشت داده قدیمی (Stale) در IAM Context",
      "content": "**علائم:**\n- کاربر بن شده ولی هنوز دسترسی دارد\n- محدودیت اعمال شده ولی توسط سرویس‌های پایین‌دستی اجرا نمی‌شود\n\n**تشخیص:**\n```sql\n-- چک کردن دیتابیس IAM (جدول users در IAM نگهداری می‌شود، نه Auth)\nSELECT status, updated_at FROM users WHERE kratos_id = '<userId>';\n```\n```bash\nredis-cli -h $REDIS_HOST GET \"iam:context:<userId>\"\n```\n\n**رفع:**\n```bash\nredis-cli -h $REDIS_HOST DEL \"iam:context:<userId>\"\n```"
    },
    {
      "level": 3,
      "heading": "۵.۲ فعال نشدن Policy Engine",
      "content": "**رفع:**\n- استفاده از Admin API برای ارزیابی دستی سیاست\n- فعال کردن مجدد مصرف‌کننده NATS\n- فعال کردن سیاست در دیتابیس"
    },
    {
      "level": 3,
      "heading": "۵.۳ عدم پاسخگویی سرویس IAM (SEV-1)",
      "content": "**رفع:**\n1. ری‌استارت سرویس\n2. Redeploy کامل\n3. Rollback به ایمیج قبلی"
    },
    {
      "level": 2,
      "heading": "۶. حوادث کش (Cache)",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۶.۱ خرابی یا ناهماهنگی Redis Cache",
      "content": "**رفع:**\n```bash"
    },
    {
      "level": 1,
      "heading": "فلاش فقط کلیدهای IAM (ایمن)",
      "content": "redis-cli -h $REDIS_HOST --scan --pattern \"iam:context:*\" | xargs redis-cli -h $REDIS_HOST DEL\n```"
    },
    {
      "level": 3,
      "heading": "۶.۲ تمام شدن حافظه Redis",
      "content": "**رفع فوری:**\n- افزایش موقت `maxmemory`\n- فلاش کلیدهای غیرضروری\n- بررسی fragmentation"
    },
    {
      "level": 3,
      "heading": "۶.۳ عدم دسترسی به Redis (SEV-1/2)",
      "content": ""
    },
    {
      "level": 2,
      "heading": "۷. حوادث Event Bus (NATS)",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۷.۱ تأخیر مصرف‌کننده NATS",
      "content": "**رفع:**\n- ری‌استارت سرویس مصرف‌کننده\n- Scale up replicas\n- Skip پیام مشکل‌دار"
    },
    {
      "level": 3,
      "heading": "۷.۲ عدم دسترسی JetStream (SEV-1)",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۷.۳ پر شدن Dead Letter Queue",
      "content": ""
    },
    {
      "level": 2,
      "heading": "۸. حوادث پایگاه داده",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۸.۱ تعداد بالای اتصالات PostgreSQL",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۸.۲ کوئری‌های کند",
      "content": ""
    },
    {
      "level": 2,
      "heading": "۹. حوادث Marketplace",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۹.۱ پردازش نشدن سفارشات",
      "content": ""
    },
    {
      "level": 2,
      "heading": "۱۰. حوادث Wallet",
      "content": ""
    },
    {
      "level": 3,
      "heading": "۱۰.۱ مسدود شدن غیرمنتظره برداشت‌ها",
      "content": ""
    },
    {
      "level": 2,
      "heading": "۱۱. پس از حادثه (Post-Incident)",
      "content": "**الزامی برای SEV-1 و SEV-2 در کمتر از ۲۴ ساعت**"
    },
    {
      "level": 3,
      "heading": "قالب گزارش حادثه",
      "content": "```markdown"
    },
    {
      "level": 2,
      "heading": "گزارش حادثه — <تاریخ> — <عنوان>",
      "content": "**شدت:** SEV-X  \n**مدت:** X ساعت X دقیقه  \n**سرویس‌های تحت تأثیر:**"
    },
    {
      "level": 3,
      "heading": "timeline",
      "content": ""
    },
    {
      "level": 3,
      "heading": "Root Cause",
      "content": ""
    },
    {
      "level": 3,
      "heading": "چه چیزی خوب پیش رفت",
      "content": ""
    },
    {
      "level": 3,
      "heading": "چه چیزی بد پیش رفت",
      "content": ""
    },
    {
      "level": 3,
      "heading": "اقدامات اصلاحی",
      "content": "```"
    },
    {
      "level": 2,
      "heading": "۱۲. تماس‌ها و منابع",
      "content": ""
    },
    {
      "level": 3,
      "heading": "داشبوردها",
      "content": "- **Grafana:** http://grafana.internal\n- **NATS Dashboard:** http://nats.internal:8222\n- **Redis Insight:** http://redis.internal\n- **Jaeger:** http://jaeger.internal\n- **Traefik Dashboard:** `http://localhost:8085` (محلی)"
    },
    {
      "level": 3,
      "heading": "متغیرهای محیطی مهم",
      "content": "- `IAM_DATABASE_URL`\n- `REDIS_HOST`\n- `NATS_URL`\n- `KRATOS_ADMIN_URL`\n- `HYDRA_ADMIN_URL`"
    },
    {
      "level": 3,
      "heading": "مستندات مرتبط",
      "content": "- **Helm Architecture:** ./helm-architecture.md\n- **راهنمای استقرار:** ./setup-guide.md\n\n---\n\n**کانال‌های ارتباطی:**\n- اصلی: `#incident-<تاریخ>`\n- تشدید: `#engineering-leads`\n- Status Page: https://status.platform.internal"
    }
  ]
}