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
}
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é.
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).
@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)