MVC Framework retry filter ignores retries and sleeps 1s between attempts when no backoff is configured

オープン
#4,341 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
java, spring, spring-boot
領域
api, backend

調査の方向性

Start with FrameworkRetryFilterFunctions.java, especially the CompositeRetryPolicy default backoff around lines 133–134, and compare it with shouldRetry() and the explicit backoff path. Read the RetryFilterFunctionBackoffTests style and reproduce the reported case with retries set to 5. Done means six attempts succeed with no delay when backoff is disabled; the issue author says a fix and test are already ready and plans to open a PR.

索引モデルが issue の本文から書いたものです。

説明

waiting-for-triage

Describe the bug
Spring Cloud Gateway Server WebMVC 5.0.x (since 5.0.0, also on main), using the Spring Framework based retry filter (FrameworkRetryFilterFunctions, selected when Spring Retry is not on the classpath or use-framework-retry-filter=true).

When backoff is not configured, CompositeRetryPolicy falls back to RetryPolicy.withDefaults().getBackOff():

https://github.com/spring-cloud/spring-cloud-gateway/blob/b57ce6613e/spring-cloud-gateway-server-webmvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/FrameworkRetryFilterFunctions.java#L133-L134

In Spring Framework 7 that is new FixedBackOff(1000, 3): a 1 second delay and at most 3 retries. RetryTemplate stops as soon as the BackOff returns STOP, so:

  • a retries value above 3 is silently capped at 3 (retry(c -> c.setRetries(5)) gives up after the 4th attempt with RetryException: Retry policy ... exhausted);
  • every retry blocks the servlet thread for 1 second, although the documentation lists the default as backoff: disabled.

The behaviour predates the backoff support (de023f51): before that commit CompositeRetryPolicy simply inherited the same default from RetryPolicy.getBackOff(). The attempt limit is already enforced by shouldRetry() (attemptCount >= config.getRetries()), and the explicit-backoff path uses an ExponentialBackOff with unlimited attempts, so the default can be a zero-delay FixedBackOff with unlimited attempts, leaving the count to shouldRetry().

Sample
Reproduced with Spring Boot 4.0.9 / Spring Cloud 2025.1.4: a route with retry(c -> c.setRetries(5)) in front of a backend that fails 5 times and then returns 200. The gateway made 4 attempts, answered 500 and took 3.07 s (Backing off for 1000ms three times, then RetryException). Expected: 6 attempts, 200, no delay.

A handler-based test in RetryFilterFunctionBackoffTests style shows the same thing. I have a fix with this test ready and will open a PR.

主要言語
Java
スター
4.9k
フォーク
3.5k
平均マージ
2日 4時間
マージ済み PR(30日)
9

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

spring-cloud/spring-cloud-gateway のほかの issue

spring-cloud/spring-cloud-gateway の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。