Was ich bei Nebenprojekten gelernt habe…
Einführung: Aspektorientierte Programmierung (AOP) ist eine leistungsstarke Technik in Spring Boot, um übergreifende Anliegen von der Hauptanwendungslogik zu trennen. Ein häufiger Anwendungsfall von AOP ist die Implementierung einer Ratenbegrenzung in APIs, bei der Sie die Anzahl der Anfragen begrenzen, die ein Client innerhalb eines bestimmten Zeitraums stellen kann. In diesem Artikel untersuchen wir, wie Sie AOP nutzen können, um eine Ratenbegrenzung in Spring Boot-APIs zu implementieren und so eine optimale Leistung und Ressourcennutzung sicherzustellen.
Aspektorientierte Programmierung ist ein Programmierparadigma, das darauf abzielt, Querschnittsthemen in der Softwareentwicklung zu modularisieren. Querschnittsthemen sind Aspekte eines Programms, die mehrere Module betreffen und sich mit herkömmlichen Ansätzen nur schwer modularisieren lassen. Beispiele hierfür sind Protokollierung, Sicherheit und Transaktionsverwaltung.
AOP führt das Konzept der Aspekte ein, die übergreifende Anliegen zusammenfassen. Aspekte sind modulare Einheiten, die auf verschiedene Teile der Anwendung angewendet werden können, ohne die Kernlogik zu ändern. AOP-Frameworks wie Spring AOP bieten Mechanismen zum Definieren von Aspekten und deren Anwendung auf bestimmte Verbindungspunkte im Ausführungsfluss der Anwendung.
Ratenbegrenzung ist eine häufige Anforderung in Web-APIs, um Missbrauch zu verhindern und eine faire Nutzung von Ressourcen sicherzustellen. Mit AOP in Spring Boot können wir eine Ratenbegrenzung implementieren, indem wir Methodenaufrufe abfangen und Beschränkungen für die Anzahl der zulässigen Anfragen innerhalb eines bestimmten Zeitrahmens durchsetzen.
Um die Ratenbegrenzung mit AOP in Spring Boot zu implementieren, führen wir normalerweise die folgenden Schritte aus:
Die Implementierung einer Ratenbegrenzung in einer Spring Boot-API kann mithilfe verschiedener Techniken erreicht werden. Ein gängiger Ansatz besteht darin, Spring AOP (Aspect-Oriented Programming) zu verwenden, um eingehende Anfragen abzufangen und Ratenbeschränkungen durchzusetzen.
Schritt 1 – Ratenbegrenzungskonfiguration definieren: Erstellen Sie eine Konfigurationsklasse, in der Sie die Ratenbegrenzungsparameter wie die Anzahl der zulässigen Anfragen und den Zeitraum definieren.
@Configuration public class RateLimitConfig { @Value("${rate.limit.requests}") private int requests; @Value("${rate.limit.seconds}") private int seconds; // Getters and setters }
Schritt 2 – Erstellen Sie einen Aspekt zur Ratenbegrenzung: Implementieren Sie einen Aspekt mithilfe von Spring AOP, um Methodenaufrufe abzufangen und Ratenbegrenzungen durchzusetzen.
@Aspect @Component public class RateLimitAspect { @Autowired private RateLimitConfig rateLimitConfig; @Autowired private RateLimiter rateLimiter; @Around("@annotation(RateLimited)") public Object enforceRateLimit(ProceedingJoinPoint joinPoint) throws Throwable { String key = getKey(joinPoint); if (!rateLimiter.tryAcquire(key, rateLimitConfig.getRequests(), rateLimitConfig.getSeconds())) { throw new RateLimitExceededException("Rate limit exceeded"); } return joinPoint.proceed(); } private String getKey(ProceedingJoinPoint joinPoint) { // Generate a unique key for the method being called // Example: method signature, user ID, IP address, etc. // You can customize this based on your requirements } }
Schritt 3 – RateLimited-Anmerkung definieren: Erstellen Sie eine benutzerdefinierte Anmerkung, um die Methoden zu markieren, die ratenbegrenzt werden sollen.
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RateLimited { }
Schritt 4 – Ratenbegrenzer implementieren: Erstellen Sie eine Ratenbegrenzerkomponente, um Ratenbegrenzungen mithilfe eines Token-Bucket-Algorithmus oder eines anderen geeigneten Algorithmus zu verwalten.
@Component public class RateLimiter { private final Map<String,RateLimitedSemaphore> semaphores = new ConcurrentHashMap<>(); public boolean tryAcquire(String key, int requests, int seconds) { // Get the current timestamp long currentTime = System.currentTimeMillis(); // Calculate the start time of the time window (in milliseconds) long startTime = currentTime - seconds * 1000; // Remove expired entries from the semaphore map cleanupExpiredEntries(startTime); // Get or create the semaphore for the given key RateLimitedSemaphore semaphore = semaphores.computeIfAbsent(key, k -> { RateLimitedSemaphore newSemaphore = new RateLimitedSemaphore(requests); newSemaphore.setLastAcquireTime(currentTime); // Set last acquire time return newSemaphore; }); // Check if the semaphore allows acquiring a permit boolean acquired = semaphore.tryAcquire(); if (acquired) { semaphore.setLastAcquireTime(currentTime); // Update last acquire time } return acquired; } private void cleanupExpiredEntries(long startTime) { Iterator<Map.Entry<String, RateLimitedSemaphore>> iterator = semaphores.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, RateLimitedSemaphore> entry = iterator.next(); String key = entry.getKey(); RateLimitedSemaphore semaphore = entry.getValue(); if (semaphore.getLastAcquireTime() < startTime) { iterator.remove(); } } } private class RateLimitedSemaphore extends Semaphore { private volatile long lastAcquireTime; public RateLimitedSemaphore(int permits) { super(permits); } public long getLastAcquireTime() { return lastAcquireTime; } public void setLastAcquireTime(long lastAcquireTime) { this.lastAcquireTime = lastAcquireTime; } } }
Schritt 5 – Controller-Methoden kommentieren: Annotieren Sie die Controller-Methoden, die ratenbegrenzt werden sollen, mit @RateLimited.
@RestController public class MyController { @RateLimited @GetMapping("/api/resource") public ResponseEntity<String> getResource() { // Implementation } }
Schritt 6 – Ratenbegrenzungseigenschaften konfigurieren: Konfigurieren Sie die Ratenbegrenzungseigenschaften in Ihrer application.properties oder application.yml.
rate.limit.requests=10 rate.limit.seconds=60
Außerdem…
Um Anfragen nach IP-Adresse zu begrenzen, können Sie die IP-Adresse aus der eingehenden Anfrage extrahieren und sie als Schlüssel für die Ratenbegrenzung verwenden. So können Sie die Methode „getKey“ ändern, um einen eindeutigen Schlüssel basierend auf der IP-Adresse zu generieren:
private String getKey(HttpServletRequest request) { // Get the IP address of the client making the request String ipAddress = request.getRemoteAddr(); return ipAddress; // Use IP address as the key }
Sie müssen außerdem die Methode „enforceRateLimit“ in der Klasse „RateLimitAspect“ ändern, um das Objekt „HttpServletRequest“ an die Methode „getKey“ zu übergeben:
@Around("@annotation(RateLimited)") public Object enforceRateLimit(ProceedingJoinPoint joinPoint) throws Throwable { // Get the current request from the JoinPoint ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); String key = getKey(request); if (!rateLimiter.tryAcquire(key, rateLimitConfig.getRequests(), rateLimitConfig.getSeconds())) { throw new RateLimitExceededException("Rate limit exceeded"); } return joinPoint.proceed(); }
In diesem Beispiel definieren wir eine benutzerdefinierte Annotation @RateLimited , um Methoden zu markieren, die ratenbegrenzt werden sollen. Anschließend erstellen wir einen Aspekt „RateLimitAspect“, der mit „@RateLimited“ annotierte Methodenaufrufe abfängt. Innerhalb des Aspekts erzwingen wir Ratenbegrenzungen mithilfe einer RateLimiter-Komponente.
In diesem Artikel haben wir untersucht, wie man Ratenbegrenzung in Spring Boot-APIs mithilfe von Aspect-Oriented Programming (AOP) implementiert. Indem wir übergreifende Anliegen wie die Ratenbegrenzung von der Kernanwendungslogik trennen, können wir eine bessere Modularität, Wartbarkeit und Skalierbarkeit unserer Anwendungen sicherstellen. AOP bietet einen leistungsstarken Mechanismus zur Lösung solcher Bedenken und ermöglicht es Entwicklern, sich auf die Entwicklung robuster und effizienter APIs zu konzentrieren.
Durch Befolgen der in diesem Artikel beschriebenen Schritte und Nutzung der AOP-Funktionen in Spring Boot können Entwickler problemlos Ratenbegrenzung und andere übergreifende Probleme in ihren Anwendungen implementieren, was zu widerstandsfähigeren und leistungsfähigeren APIs führt.
Das obige ist der detaillierte Inhalt vonSo implementieren Sie eine Ratenbegrenzung in Spring Boot-APIs mithilfe aspektorientierter Programmierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!