web-dev-qa-db-fra.com

Comment définir un délai d'expiration sur un Spring Boot REST API?

J'ai quelques REST APIs qui peuvent prendre un certain temps à exécuter, et je veux limiter leur durée d'exécution. De préférence, si 30 secondes se sont écoulées et que la demande n'est pas revenue, je voudrais revenir un code/données HTTP spécifique et terminer complètement cette demande.

Le code actuel:

@RestController
@CrossOrigin(origins = {"*"}, maxAge = 4800, allowCredentials = "false")
public class APIController {

@RequestMapping(value = "/api/myapifunc", method = RequestMethod.POST, produces = "application/json")
public ResponseEntity<?> optimize(@RequestParam(value="param1", defaultValue="")) {
    // Code here
}
10
Tom Shir

Il semble que vous décriviez le modèle de disjoncteur . Si vous contrôlez à la fois le code client et le code serveur et que vous souhaitez explorer les bibliothèques Spring Cloud et Netflix Hysterix, vous pouvez consulter le guide Mise en route: Disjoncteur .

Si vous utilisez Apache Tomcat comme conteneur de servlet, vous pouvez configurer Stuck Thread Detection Valve :

Cette valve permet de détecter les demandes qui prennent beaucoup de temps à traiter, ce qui pourrait indiquer que le thread qui la traite est bloqué. De plus, il peut éventuellement interrompre ces threads pour essayer de les débloquer.

Lorsqu'une telle demande est détectée, la trace de pile actuelle de son thread est écrite dans le journal Tomcat avec un niveau WARN.

Les ID et les noms des threads bloqués sont disponibles via JMX dans les attributs stuckThreadIds et stuckThreadNames. Les ID peuvent être utilisés avec le MBean JVM Threading standard (Java.lang: type = Threading) pour récupérer d'autres informations sur chaque thread bloqué.

3
Karol Dowbecki

Vous pouvez définir cette configuration de propriété

 server.connection-timeout=30000 

dans votre application.properties. Basé sur documentation officielle dit:

server.connection-timeout = # Temps pendant lequel les connecteurs attendent une autre requête HTTP avant de fermer la connexion. Lorsqu'il n'est pas défini, la valeur par défaut spécifique au conteneur du connecteur est utilisée. Utilisez une valeur de -1 pour indiquer aucun délai (c'est-à-dire un délai infini).

1
Jonathan JOhx
@RequestMapping(value = "/api/myapifunc", method = RequestMethod.POST, produces = 
"application/json")
public ResponseEntity<?> optimize(@RequestParam(value="param1", defaultValue="")) {
 return new Callable<String>() {
    @Override
    public String call() throws Exception {
        Thread.sleep(3000); //this will cause a timeout
        return "foobar";
    }
  };
}

Futur, vous pouvez utiliser ou annotation @Timed @Transactional(timeout = 3000)

0
Syam Dorjee