Heim  >  Artikel  >  Java  >  Entdecken Sie die Einschränkungen in Java

Entdecken Sie die Einschränkungen in Java

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌nach vorne
2024-01-02 10:28:411431Durchsuche

In der Welt der Softwareentwicklung sind die effektive Verwaltung des Ressourcenverbrauchs und die Gewährleistung einer fairen Nutzung von Diensten wichtige Überlegungen beim Aufbau skalierbarer und robuster Anwendungen. Unter Drosselung versteht man die Steuerung der Geschwindigkeit, mit der bestimmte Vorgänge ausgeführt werden, und ist ein Schlüsselmechanismus zum Erreichen dieser Ziele. In diesem Artikel werden wir uns eingehend mit den verschiedenen Möglichkeiten zur Implementierung der Drosselung in Java befassen und verschiedene Strategien anhand praktischer Beispiele vorstellen.

Entdecken Sie die Einschränkungen in Java

Untersuchung von Einschränkungen in Java: Einfaches Implementierungsbeispiel – Teil 1

Effiziente Verwaltung des Ressourcenverbrauchs und Gewährleistung einer fairen Nutzung von Diensten sind wichtige Überlegungen beim Aufbau skalierbarer und robuster Anwendungen.

In der Welt der Softwareentwicklung sind die effektive Verwaltung des Ressourcenverbrauchs und die Gewährleistung einer fairen Nutzung von Diensten wichtige Überlegungen beim Aufbau skalierbarer und robuster Anwendungen. Unter Drosselung versteht man die Steuerung der Geschwindigkeit, mit der bestimmte Vorgänge ausgeführt werden, und ist ein Schlüsselmechanismus zum Erreichen dieser Ziele. In diesem Artikel befassen wir uns eingehend mit den verschiedenen Möglichkeiten zur Implementierung der Drosselung in Java und stellen verschiedene Strategien anhand praktischer Beispiele vor.

Haftungsausschluss: In diesem Artikel werde ich mich auf einfache Single-Threaded-Illustrationen konzentrieren, die grundlegende Lösungen lösen.

Grenzwerte verstehen

Bei Grenzwerten geht es darum, zu regeln, wie oft bestimmte Aktionen stattfinden dürfen. Dies ist besonders wichtig in Situationen, in denen das System vor Missbrauch geschützt werden muss, eine Ressourcenverwaltung erforderlich ist oder ein fairer Zugriff auf gemeinsam genutzte Dienste erforderlich ist. Zu den häufigsten Anwendungsfällen für die Drosselung gehören die Begrenzung der Rate von API-Anfragen, die Verwaltung von Datenaktualisierungen und die Kontrolle des Zugriffs auf kritische Ressourcen.

Einfacher Blockierungsratenbegrenzer – nicht für den Produktionseinsatz! thread.sleep()

Eine einfache Möglichkeit, Grenzwerte zu implementieren, besteht darin, mit dieser Methode eine Verzögerung zwischen aufeinanderfolgenden Vorgängen einzuführen. Obwohl diese Methode einfach ist, ist sie aufgrund ihrer blockierenden Natur möglicherweise nicht für Hochleistungsszenarien geeignet. Thread.sleep()

public class SimpleRateLimiter {

    private long lastExecutionTime = 0;
    private long intervalInMillis;

    public SimpleRateLimiter(long requestsPerSecond) {
        this.intervalInMillis = 1000 / requestsPerSecond;
    }

    public void throttle() throws InterruptedException {
        long currentTime = System.currentTimeMillis();
        long elapsedTime = currentTime - lastExecutionTime;

        if (elapsedTime < intervalInMillis) {
            Thread.sleep(intervalInMillis - elapsedTime);
        }

        lastExecutionTime = System.currentTimeMillis();
        // Perform the throttled operation
        System.out.println("Throttled operation executed at: " + lastExecutionTime);
    }
}

In diesem Beispiel ermöglicht diese Klasse die Ausführung einer bestimmten Anzahl von Operationen pro Sekunde. Wenn die zwischen den Vorgängen verstrichene Zeit kürzer als das konfigurierte Intervall ist, wird eine Schlafdauer eingeführt, um die gewünschte Rate zu erreichen. SimpleRateLimiter

Grundlegende Einschränkung von Wartezeiten

Beginnen wir mit einem einfachen Beispiel, das wir verwenden, um die Ausführung einer Methode einzuschränken. Ziel ist es, den Aufruf der Methode erst nach Ablauf einer bestimmten Abklingzeit zu ermöglichen. wait

public class BasicThrottling {

    private final Object lock = new Object();
    private long lastExecutionTime = 0;
    private final long cooldownMillis = 5000; // 5 seconds cooldown

    public void throttledOperation() throws InterruptedException {
        synchronized (lock) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastExecutionTime;

            if (elapsedTime < cooldownMillis) {
                lock.wait(cooldownMillis - elapsedTime);
            }

            lastExecutionTime = System.currentTimeMillis();
            // Perform the throttled operation
            System.out.println("Throttled operation executed at: " + lastExecutionTime);
        }
    }
}

In diesem Beispiel verwendet die Methode diese Methode, um den Thread warten zu lassen, bis die Abklingzeit abgelaufen ist. drosselte Operationwait

Dynamische Grenzen mit Wartezeiten und Benachrichtigungen

Erweitern wir das vorherige Beispiel, um dynamische Drosselung einzuführen, bei der die Abklingzeit dynamisch angepasst werden kann. Die Produktion muss die Möglichkeit haben, Änderungen im laufenden Betrieb vorzunehmen.

public class DynamicThrottling {

    private final Object lock = new Object();
    private long lastExecutionTime = 0;
    private long cooldownMillis = 5000; // Initial cooldown: 5 seconds

    public void throttledOperation() throws InterruptedException {
        synchronized (lock) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastExecutionTime;

            if (elapsedTime < cooldownMillis) {
                lock.wait(cooldownMillis - elapsedTime);
            }

            lastExecutionTime = System.currentTimeMillis();
            // Perform the throttled operation
            System.out.println("Throttled operation executed at: " + lastExecutionTime);
        }
    }

    public void setCooldown(long cooldownMillis) {
        synchronized (lock) {
            this.cooldownMillis = cooldownMillis;
            lock.notify(); // Notify waiting threads that cooldown has changed
        }
    }

    public static void main(String[] args) {
        DynamicThrottling throttling = new DynamicThrottling();

        for (int i = 0; i < 10; i++) {
            try {
                throttling.throttledOperation();
                // Adjust cooldown dynamically
                throttling.setCooldown((i + 1) * 1000); // Cooldown increases each iteration
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

In diesem Beispiel stellen wir die Methode zur dynamischen Anpassung der Abklingzeit vor. Mit dieser Methode werden alle wartenden Threads aufgeweckt, sodass sie die neue Abklingzeit prüfen können. setCooldownnotify

Verwendung von Java-Semaphoren

Java-Klassen können als leistungsstarke Tools zur Drosselung verwendet werden. Das Semaphor verwaltet eine Reihe von Lizenzen, wobei jeder Erwerbsvorgang eine Lizenz verbraucht und jeder Freigabevorgang eine Lizenz erhöht. Semaphore

public class SemaphoreRateLimiter {

    private final Semaphore semaphore;

    public SemaphoreRateLimiter(int permits) {
        this.semaphore = new Semaphore(permits);
    }

    public boolean throttle() {
        if (semaphore.tryAcquire()) {
            // Perform the throttled operation
            System.out.println("Throttled operation executed. Permits left: " + semaphore.availablePermits());
            return true;
        } else {
            System.out.println("Request throttled. Try again later.");
            return false;
        }
    }

    public static void main(String[] args) {
        SemaphoreRateLimiter rateLimiter = new SemaphoreRateLimiter(5); // Allow 5 operations concurrently

        for (int i = 0; i < 10; i++) {
            rateLimiter.throttle();
        }
    }
}

In diesem Beispiel verwendet die Klasse a mit der angegebenen Anzahl von Lizenzen. Diese Methode versucht, eine Lizenz zu erhalten und lässt den Vorgang bei Erfolg zu. SemaphoreRateLimiterSemaphorethrottle

Mehrere Beispiele in der Box

Frameworks wie Spring oder Redis bieten eine Vielzahl einfacher Lösungen.

Spring AOP für Methodeneinschränkungen

Mit den Funktionen der aspektorientierten Programmierung (AOP) von Spring können wir einen Einschränkungsmechanismus auf Methodenebene erstellen. Dieser Ansatz ermöglicht es uns, Methodenaufrufe abzufangen und Drosselungslogik anzuwenden.

@Aspect
@Component
public class ThrottleAspect {

    private Map<String, Long> lastInvocationMap = new HashMap<>();

    @Pointcut("@annotation(throttle)")
    public void throttledOperation(Throttle throttle) {}

    @Around("throttledOperation(throttle)")
    public Object throttleOperation(ProceedingJoinPoint joinPoint, Throttle throttle) throws Throwable {
        String key = joinPoint.getSignature().toLongString();

        if (!lastInvocationMap.containsKey(key) || System.currentTimeMillis() - lastInvocationMap.get(key) > throttle.value()) {
            lastInvocationMap.put(key, System.currentTimeMillis());
            return joinPoint.proceed();
        } else {
            throw new ThrottleException("Request throttled. Try again later.");
        }
    }
}

In diesem Beispiel haben wir eine benutzerdefinierte Annotation und einen AOP-Aspekt() definiert, um die Methode abzufangen, um die seit dem letzten Aufruf verstrichene Zeit zu überprüfen und die Methode entsprechend zuzulassen oder zu blockieren. @ThrottleThrottleAspect@ThrottleThrottleAspect

Guava RateLimiter verwenden

Die Guava-Bibliothek von Google bietet eine Klasse, die die Implementierung von Grenzwerten vereinfacht. Es ermöglicht die Festlegung der Geschwindigkeit, mit der Vorgänge zulässig sind. RateLimiter

Sehen wir uns an, wie es zur Methodenbegrenzung verwendet werden kann: RateLimiter

import com.google.common.util.concurrent.RateLimiter;

@Component
public class ThrottledService {

    private final RateLimiter rateLimiter = RateLimiter.create(5.0); // Allow 5 operations per second

    @Throttle
    public void throttledOperation() {
        if (rateLimiter.tryAcquire()) {
            // Perform the throttled operation
            System.out.println("Throttled operation executed.");
        } else {
            throw new ThrottleException("Request throttled. Try again later.");
        }
    }
}

In diesem Beispiel verwenden wir Guava, um die Ausführungsrate einer Methode zu steuern. Mit dieser Methode wird geprüft, ob der Vorgang basierend auf einem definierten Tarif zulässig ist. RateLimiterthrottledOperationtryAcquire

Redis als Begrenzungsmechanismus

Mit einem externen Datenspeicher wie Redis können wir einen verteilten Drosselungsmechanismus implementieren. Dieser Ansatz ist besonders nützlich in Microservice-Umgebungen, in denen mehrere Instanzen Einschränkungen koordinieren müssen.

@Component
public class RedisThrottleService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${throttle.key.prefix}")
    private String keyPrefix;

    @Value("${throttle.max.operations}")
    private int maxOperations;

    @Value("${throttle.duration.seconds}")
    private int durationSeconds;

    public void performThrottledOperation(String userId) {
        String key = keyPrefix + userId;
        Long currentCount = redisTemplate.opsForValue().increment(key);

        if (currentCount != null && currentCount > maxOperations) {
            throw new ThrottleException("Request throttled. Try again later.");
        }

        if (currentCount == 1) {
            // Set expiration for the key
            redisTemplate.expire(key, durationSeconds, TimeUnit.SECONDS);
        }

        // Perform the throttled operation
        System.out.println("Throttled operation executed for user: " + userId);
    }
}

In diesem Beispiel verwenden wir Redis, um die Anzahl der Vorgänge pro Benutzer zu speichern und zu verwalten. Diese Methode erhöht die Anzahl und prüft, ob der zulässige Grenzwert erreicht wurde. performThrottledOperation

Fazit

Die Drosselung spielt eine Schlüsselrolle bei der Aufrechterhaltung der Stabilität und Skalierbarkeit Ihrer Anwendung. In diesem Artikel untersuchen wir verschiedene Möglichkeiten zur Implementierung der Drosselung in Java, einschließlich einfacher Techniken zur Verwendung und Anwendung vorgefertigter Lösungen. Thread.sleep()Semaphore

Die Wahl der Drosselungsstrategie hängt von Faktoren wie der Art der Anwendung, den Leistungsanforderungen und dem erforderlichen Kontrollniveau ab. Bei der Umsetzung von Einschränkungen müssen Sie ein Gleichgewicht zwischen der Verhinderung von Missbrauch und der Gewährleistung einer reaktionsschnellen und fairen Benutzererfahrung finden.

Wenn Sie Drosselungsmechanismen in Ihre Anwendung integrieren, sollten Sie die Überwachung und Anpassung von Parametern basierend auf tatsächlichen Nutzungsmustern in Betracht ziehen. Bei der Entscheidung über die Implementierung von Einschränkungen können einige Fragen auftauchen, z. B. wie mit Situationen umgegangen werden soll, in denen eine Aufgabe ihre zugewiesene Frist überschreitet. In meinem nächsten Artikel möchte ich robuste Java-Implementierungen untersuchen, die verschiedene Szenarien umfassend abdecken.

Das obige ist der detaillierte Inhalt vonEntdecken Sie die Einschränkungen in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:dzone.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen