> For the complete documentation index, see [llms.txt](https://docs.kangal.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kangal.dev/tr/gateway/traffic-management.md).

# Trafik yönetimi

Kangal trafiği service ayarları, upstream target seçimi ve sıralı route plugin'leriyle yönetir. Bu kontrolleri birlikte kullanın: service timeout'ları işlem süresini sınırlar, rate limit'ler kapasiteyi korur, circuit breaker ise hatalı bir backend'in tüm worker'ları tüketmesini önler.

Politikaları geniş kapsamda uygulamadan önce production dışı bir route üzerinde test edin.

## Trafik kontrollerinin çalışma yeri

Route plugin'leri, route seçildikten sonra data plane üzerinde çalışır. Bir plugin kaydında şu ortak alanlar bulunur:

| Alan               | Varsayılan         | Anlamı                                                                             |
| ------------------ | ------------------ | ---------------------------------------------------------------------------------- |
| `name`             | Zorunlu            | `rate_limiter` gibi kayıtlı plugin kimliği.                                        |
| `enabled`          | `true`             | Devre dışı kayıtlar configuration içinde kalır ancak çalışmaz.                     |
| `config`           | `{}`               | Plugin schema'sına göre doğrulanan ayarlar.                                        |
| `trigger`          | Plugin varsayılanı | `before_request`, `after_response`, `on_error` veya `both` gibi kısa stage tanımı. |
| `stage` / `stages` | Plugin varsayılanı | Tek veya birden fazla açık execution stage'i.                                      |
| `priority`         | Plugin varsayılanı | Aynı stage içinde yüksek değer önce çalışır.                                       |

Kangal bilinmeyen plugin adlarını, katı configuration schema'sı dışındaki alanları, geçersiz stage adlarını ve tanımlı aralık dışındaki değerleri reddeder. `plugins` içeren bir route update işlemi plugin dizisinin tamamını değiştirir; route üzerinde kalması gereken tüm plugin'leri isteğe ekleyin.

## Önce timeout ve retry ayarlarını yapma

Service'ler milisaniye cinsinden `connect_timeout_ms`, `read_timeout_ms` ve `write_timeout_ms` alanlarını sunar. Console `100` ile `300000` milisaniye arasındaki değerleri kabul eder. Connect timeout'u erişilemeyen target'ı hızlıca geçecek kadar kısa, read timeout'u ise backend'in geçerli response süresini karşılayacak şekilde ayarlayın.

`retries`, yeniden denenebilir hatalardan sonraki deneme sayısını belirler. Sıfır ile beş arasında bir değer kullanın; proxy runtime daha yüksek değerleri beşle sınırlar. Varsayılan olarak yalnızca `502`, `503` ve `504` response'ları yeniden denenir. Retry yalnızca replay açısından güvenli `GET`, `HEAD`, `OPTIONS`, `PUT` ve `DELETE` isteklerine uygulanır. Güvenilmeyen body taşıyabilen isteklerde retry'ı etkinleştirmeden önce herkese açık edge ve route üzerinde açık bir request-size politikası zorunlu kılın.

Retry işlemleri backend iş yükünü çoğaltır. Retry sayısını artırmadan önce açık bir service timeout'u belirleyin ve idempotent olmayan yazma işlemlerini retry'a dayandırmayın.

## Request rate limit ekleme

`rate_limiter` plugin'i tek pencere, adlandırılmış zaman pencereleri veya birden fazla özel pencere tanımlayabilir. Bu örnek her kaynak IP için dakikada 120 isteğe izin verir:

```json
{
  "name": "rate_limiter",
  "enabled": true,
  "trigger": "before_request",
  "priority": 100,
  "config": {
    "limit": 120,
    "window_seconds": 60,
    "limit_by": "ip",
    "fault_tolerant": false,
    "hide_client_headers": false,
    "error_code": 429,
    "error_message": "Request quota exceeded"
  }
}
```

En az bir limit biçimi zorunludur:

* `limit` ile birlikte `window_seconds`
* `second`, `minute`, `hour`, `day`, `month` veya `year` alanlarından en az biri
* öğeleri `limit` ile `window_seconds` veya `window_size` içeren, boş olmayan bir `limits` dizisi

Örneğin burst ve saatlik kotayı birlikte uygulayın:

```json
{
  "name": "rate_limiter",
  "config": {
    "limits": [
      {"name": "burst", "limit": 20, "window_seconds": 10},
      {"name": "hourly", "limit": 1000, "window_seconds": 3600}
    ],
    "limit_by": "consumer"
  }
}
```

### Rate-limit kimliği

`limit_by` şu değerleri kabul eder:

| Değer        | Bucket kimliği                                                                                                                                                     |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ip`         | `X-Forwarded-For` içindeki ilk adres; header yoksa bağlı client adresi. Bu değeri yalnızca kontrollü proxy ilgili header'ı yeniden yazıyorsa güvenilir kabul edin. |
| `consumer`   | Kimliği doğrulanmış consumer state'i veya `X-Consumer-ID`; kimliği doğrulanmamış istekler `anonymous` bucket'ını paylaşır.                                         |
| `credential` | Credential state'i veya credential/API key header'ları.                                                                                                            |
| `header`     | `header_name` değeri; header bulunmayan istekler `anonymous` bucket'ını paylaşır.                                                                                  |
| `path`       | Request path'i veya birleşik runtime'da yapılandırılmış `path`.                                                                                                    |
| `tenant`     | Geçerli tenant kimliği.                                                                                                                                            |
| `service`    | Seçilen service kimliği.                                                                                                                                           |
| `route`      | Seçilen route kimliği.                                                                                                                                             |
| `global`     | Yapılandırılan kapsam için tek bucket.                                                                                                                             |

`consumer` veya `credential` seçeneğini, ilgili kimliği authentication plugin'i request state'e ekledikten sonra kullanın. Aksi halde ilişkisiz caller'lar aynı bucket'ı paylaşabilir.

### Rate-limit response'ları

Kabul edilen isteklerde rate-limit metadata'sı upstream'e gönderilir ve client response sözleşmesinin parçası değildir. Reddedilen istekler `Retry-After` içerir. `error_code`, `400` ile `599` arasında olmalıdır; rate-limit reddi için `429` kullanın.

### Deployment'a göre sayaç kapsamı

Birleşik uygulamada `rate_limiter`, Redis ve fixed time bucket'ları kullanır. Aynı Redis instance'ını paylaşan replica'lar sayaçları da paylaşır.

Bağımsız deployment'ta çalışan data plane process-local bucket kullanır ve her process kendi kotasını uygular. Bu modelde her node limitini etkin process sayısını dikkate alarak boyutlandırın. Tam fleet-wide kota için paylaşılan edge katmanında merkezi enforcement kullanın.

Birleşik runtime Redis'e ulaşamadığında `fault_tolerant: true` isteklerin devam etmesine izin verir. Kota enforcement kaybı yerine trafiği reddetmenin daha güvenli olduğu senaryolarda `false` kullanın.

## Backend concurrency ve hatalarını koruma

`service_protection`, in-flight request sınırı ile rolling circuit breaker'ı birlikte sağlar:

```json
{
  "name": "service_protection",
  "enabled": true,
  "stages": ["before_request", "after_response", "on_error"],
  "priority": 90,
  "config": {
    "namespace": "checkout",
    "max_concurrent_requests": 80,
    "failure_window_seconds": 60,
    "failure_threshold": 5,
    "minimum_requests": 10,
    "failure_rate_threshold": 0.5,
    "cooldown_seconds": 30,
    "failure_status_codes": [500, 502, 503, 504],
    "open_circuit_status": 503,
    "open_circuit_body": "Checkout temporarily unavailable",
    "include_headers": true
  }
}
```

`before_request` stage'i concurrency slot ayırır ve circuit açıkken isteği reddeder. Response ve error stage'leri slot'u serbest bırakır ve sonucu kaydeder. In-flight hesabının doğru kalması için üç stage'i birlikte yapılandırın.

Circuit ancak `minimum_requests` ve `failure_threshold` değerlerinin ikisi de karşılandığında ve hata oranı `failure_rate_threshold` seviyesine ulaştığında açılır. Cooldown sırasında reddedilen response'lar `X-Service-Protection` ve `Retry-After` içerebilir. `include_headers: true` olduğunda response'larda state, hata ve request sayısı header'ları bulunabilir.

Concurrency ve circuit state'i worker ve data-plane node başına yönetilir. Backend genelinde kesin bir concurrency bütçesi uygulayacaksanız bütçeyi en yüksek etkin worker sayısına bölün veya backend katmanında merkezi limit kullanın.

## Request body boyutunu sınırlama

`request_size_limiter`, `POST`, `PUT` ve `PATCH` body'lerini korur:

```json
{
  "name": "request_size_limiter",
  "priority": 200,
  "config": {
    "max_bytes": 1048576
  }
}
```

`max_bytes` zorunludur ve byte cinsinden ölçülür. Plugin buffered `POST`, `PUT` ve `PATCH` body'lerine uygulanır. Streaming upload ve edge kapasitesini de korumak için ingress veya uygulama katmanında ek upload limiti belirleyin.

## Seçili istekleri sonlandırma

`request_termination`, yapılandırılan tüm header'lar tam olarak beklenen değerle eşleştiğinde tanımlı response'u döndürür:

```json
{
  "name": "request_termination",
  "priority": 300,
  "config": {
    "header_equals": {
      "X-Maintenance-Block": "true"
    },
    "status_code": 503,
    "message": "Temporarily unavailable"
  }
}
```

Kontrol header'larını eklemek veya kaldırmak için güvenilir bir edge kullanın. Bakım ya da policy kararının public client tarafından belirlenmesine izin vermeyin.

## Canary routing

`canary_shadow_traffic`, ana request için belirlenebilir yüzde ve header kararları üretir. Canary target tam bir HTTP veya HTTPS URL'si olmalıdır:

```json
{
  "name": "canary_shadow_traffic",
  "priority": 150,
  "config": {
    "canary_percentage": 10,
    "bucket_by": "header",
    "bucket_header_name": "X-Customer-ID",
    "bucket_salt": "checkout-v2",
    "canary_header_name": "X-Canary",
    "canary_header_value": "true",
    "canary_upstream_url": "https://checkout-v2.internal.example",
    "include_decision_headers": true
  }
}
```

Salt ve yüzde değişmediği sürece kararlı bucket key aynı kimliği aynı cohort'ta tutar. Canary kararı eşleştiğinde ana request `canary_upstream_url` veya `canary_forward_url` adresine yönlendirilir.

## Tamamlanan response'ları sayma

`response_rate_limiter`, request öncesinde kotayı kontrol eder ve sonrasında eşleşen response'ları kaydeder. Varsayılan olarak `2xx` response'ları sayar ve request ile response stage'lerinin ikisini de gerektirir:

```json
{
  "name": "response_rate_limiter",
  "trigger": "both",
  "config": {
    "limit": 100,
    "window_seconds": 60,
    "limit_by": "credential",
    "count_statuses": ["2xx", 429]
  }
}
```

Sayaçlar worker bazında tutulur. Bu plugin'i worker başına shaping ve response maliyeti akışlarında kullanın; finansal billing kaydı için merkezi metering sisteminizi esas alın.

## Eksiksiz route policy uygulama

Bu patch mevcut bir route'a paylaşılan request kotası ve service protection ekler. Önce environment değerlerini değiştirin:

```bash
export KANGAL_ADMIN_URL="https://control.example.com"
export KANGAL_TOKEN="replace-with-admin-token"
export KANGAL_GATEWAY_ID="gateway_123"
export KANGAL_ROUTE_ID="route_123"

curl -sS -X PATCH \
  "$KANGAL_ADMIN_URL/api/v1/admin/gateways/$KANGAL_GATEWAY_ID/routes/$KANGAL_ROUTE_ID" \
  -H "Authorization: Bearer $KANGAL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "plugins": [
      {
        "name": "rate_limiter",
        "enabled": true,
        "trigger": "before_request",
        "priority": 100,
        "config": {
          "minute": 120,
          "limit_by": "ip",
          "fault_tolerant": false
        }
      },
      {
        "name": "service_protection",
        "enabled": true,
        "stages": ["before_request", "after_response", "on_error"],
        "priority": 90,
        "config": {
          "max_concurrent_requests": 80,
          "failure_threshold": 5,
          "minimum_requests": 10,
          "failure_rate_threshold": 0.5,
          "cooldown_seconds": 30
        }
      }
    ]
  }'
```

Aynı işlemin CLI biçimi şöyledir:

```bash
kangalctl update routes "$KANGAL_ROUTE_ID" \
  --gateway-id "$KANGAL_GATEWAY_ID" \
  -f route-policy.json
```

Policy'yi uyguladıktan sonra load test çalıştırmadan önce istenen configuration version'ın serving data plane tarafından ACK edildiğini doğrulayın.

## Doğrulama listesi

1. Eşik altındaki istekleri gönderin ve quota header'larını inceleyin.
2. Eşiği aşın; response code ve `Retry-After` değerini doğrulayın.
3. Bağımsız kimliklerin ayrı bucket'lar aldığını test edin.
4. Kontrollü `5xx` response'ları üretin ve circuit geçişini gözlemleyin.
5. Başarılı response ve hatalardan sonra concurrency değerinin sıfıra döndüğünü doğrulayın.
6. Testleri her data-plane node üzerinde tekrarlayın ve node başına policy state'ini doğrulayın.

## Sorun giderme

### Tüm caller'lar aynı kotayı paylaşıyor

Seçilen kimlik bulunamıyor olabilir. Authentication sırasını ve kimlik header'larını kontrol edin veya geçici olarak `ip` kullanın. `header` seçeneğinde `header_name` alanının her request'te bulunduğunu doğrulayın.

### Dağıtık limit yapılandırılandan yüksek görünüyor

Her bağımsız runtime kendi process kotasını uygular. Fleet-wide üst sınırı hesaplarken yapılandırılan limiti etkin process sayısıyla değerlendirin veya paylaşılan Redis tabanlı runtime ya da merkezi edge enforcement kullanın.

### Redis erişilemiyor ancak istekler devam ediyor

Birleşik runtime'da `fault_tolerant` varsayılanı `true` değeridir. Kesin fail-closed kota enforcement gerekiyorsa `false` yapın ve Redis'i trafik bağımlılığı olarak izleyin.

### Circuit açılmıyor

Plugin'in request, response ve error stage'lerinde çalıştığını doğrulayın. Ardından failure code'ların, `minimum_requests`, `failure_threshold` ve `failure_rate_threshold` değerlerinin tanımlı pencere içinde karşılanabildiğini kontrol edin.

### İstekler bittikten sonra circuit meşgul kalıyor

Response veya error stage'inin yapılandırıldığını ve request'in eşleşen plugin yaşam döngüsünden geçtiğini kontrol edin. Üç `service_protection` stage'ini de uygulayıp tekrar test edin.

### Route update başka bir plugin'i kaldırdı

`plugins` bir replacement dizisidir. Route'u okuyun, korunacak kayıtları configuration dosyanızda birleştirin ve eksiksiz listeyle patch uygulayın.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kangal.dev/tr/gateway/traffic-management.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
