>Java >java지도 시간 >Java의 제한 사항 살펴보기

Java의 제한 사항 살펴보기

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌앞으로
2024-01-02 10:28:411434검색

소프트웨어 개발 세계에서 리소스 소비를 효과적으로 관리하고 서비스의 공정한 사용을 보장하는 것은 확장 가능하고 강력한 애플리케이션을 구축하는 데 중요한 고려 사항입니다. 조절은 특정 작업이 수행되는 속도를 제어하는 ​​방식이며 이러한 목표를 달성하기 위한 핵심 메커니즘입니다. 이 기사에서는 Java에서 조절을 구현하는 다양한 방법에 대해 자세히 알아보고 실제 사례를 통해 다양한 전략을 소개합니다.

Java의 제한 사항 살펴보기

Java의 제한 사항 탐색: 간단한 구현 예 - 1부

자원 소비를 효율적으로 관리하고 서비스의 공정한 사용을 보장하는 것은 확장 가능하고 강력한 애플리케이션을 구축하는 데 중요한 고려 사항입니다.

소프트웨어 개발 세계에서 리소스 소비를 효과적으로 관리하고 서비스의 공정한 사용을 보장하는 것은 확장 가능하고 강력한 애플리케이션을 구축하는 데 있어 중요한 고려 사항입니다. 조절은 특정 작업이 수행되는 속도를 제어하는 ​​방식이며 이러한 목표를 달성하기 위한 핵심 메커니즘입니다. 이 기사에서는 Java에서 조절을 구현하는 다양한 방법에 대해 자세히 알아보고 실제 사례를 통해 다양한 전략을 소개합니다.

면책 조항: 이 기사에서는 기본 솔루션을 해결하는 간단한 단일 스레드 그림에 중점을 둘 것입니다.

제한 이해

제한에는 특정 작업이 허용되는 빈도를 규제하는 것이 포함됩니다. 이는 시스템을 남용으로부터 보호해야 하거나 리소스 관리가 필요하거나 공유 서비스에 대한 공정한 액세스가 필요한 상황에서 특히 중요합니다. 조절의 일반적인 사용 사례에는 API 요청 속도 제한, 데이터 업데이트 관리, 중요한 리소스에 대한 액세스 제어가 포함됩니다.

간단한 차단 속도 제한기 - 프로덕션용이 아닙니다! thread.sleep()

제한을 구현하는 간단한 방법은 이 메서드를 사용하여 연속 작업 사이에 지연을 도입하는 것입니다. 이 방법은 간단하지만 차단 특성으로 인해 고성능 시나리오에는 적합하지 않을 수 있습니다. 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);
    }
}

이 예제에서 이 클래스를 사용하면 초당 지정된 수의 작업을 수행할 수 있습니다. 작업 간 경과 시간이 구성된 간격보다 짧은 경우 원하는 속도를 달성하기 위해 절전 기간이 도입됩니다. SimpleRateLimiter

대기의 ​​기본 제한

메서드 실행을 제한하는 데 사용하는 간단한 예제부터 시작하겠습니다. 목표는 특정 쿨다운 시간이 경과한 후에만 메서드가 호출되도록 허용하는 것입니다. 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);
        }
    }
}

이 예에서 메서드는 이 메서드를 사용하여 스레드가 휴지 기간이 경과할 때까지 기다리도록 합니다. throttledOperationwait

대기 및 알림이 포함된 동적 제한

이전 예제를 개선하여 쿨다운을 동적으로 조정할 수 있는 동적 조절을 도입해 보겠습니다. 생산 과정에서는 즉석에서 변경할 수 있는 기회가 있어야 합니다.

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();
            }
        }
    }
}

이번 예시에서는 쿨타임을 동적으로 조정하는 방법을 소개합니다. 이 방법은 대기 중인 스레드를 깨우고 새로운 쿨다운 시간을 확인할 수 있도록 하는 데 사용됩니다. setCooldownnotify

Java의 세마포어 사용

Java 클래스는 조절을 위한 강력한 도구로 사용될 수 있습니다. 세마포어는 라이센스 세트를 유지 관리합니다. 여기서 각 획득 작업은 하나의 라이센스를 사용하고 각 릴리스 작업은 하나의 라이센스를 증가시킵니다. 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();
        }
    }
}

이 예에서 클래스는 지정된 수의 라이선스를 사용합니다. 이 방법은 라이센스 획득을 시도하고 성공하면 작업을 허용합니다. SemaphoreRateLimiterSemaphorethrottle

상자에 포함된 여러 예제

Spring 또는 Redis와 같은 프레임워크는 다양하고 간단한 솔루션을 제공합니다.

메서드 제한을 위한 Spring AOP

Spring의 AOP(관점 지향 프로그래밍) 기능을 사용하여 메서드 수준 제한 메커니즘을 만들 수 있습니다. 이 접근 방식을 사용하면 메서드 호출을 가로채고 제한 논리를 적용할 수 있습니다.

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

이 예에서는 마지막 호출 이후 경과된 시간을 확인하고 그에 따라 메서드를 허용하거나 차단하기 위해 . @ThrottleThrottleAspect@ThrottleThrottleAspect

Guava RateLimiter 사용

Google의 Guava 라이브러리는 제한 구현을 단순화하는 클래스를 제공합니다. 이를 통해 작업이 허용되는 속도를 정의할 수 있습니다. RateLimiter

메서드 제한에 어떻게 사용될 수 있는지 살펴보겠습니다: 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.");
        }
    }
}

이 예에서는 Guava를 사용하여 메소드의 실행 속도를 제어합니다. 이 메소드는 정의된 비율에 따라 해당 작업이 허용되는지 확인하는 데 사용됩니다. RateLimiterthrottledOperationtryAcquire

Redis를 제한 메커니즘으로

Redis와 같은 외부 데이터 저장소를 사용하여 분산 조절 메커니즘을 구현할 수 있습니다. 이 접근 방식은 여러 인스턴스가 제약 조건을 조정해야 하는 마이크로서비스 환경에서 특히 유용합니다.

@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);
    }
}

이 예에서는 Redis를 사용하여 사용자별 작업 횟수를 저장하고 관리합니다. 이 메서드는 개수를 증가시키고 허용된 제한에 도달했는지 확인합니다. PerformThrottledOperation

결론

제한은 애플리케이션의 안정성과 확장성을 유지하는 데 중요한 역할을 합니다. 이 기사에서는 기본 솔루션을 사용하고 적용하는 간단한 기술을 포함하여 Java에서 조절을 구현하는 다양한 방법을 살펴봅니다. Thread.sleep()Semaphore

제한 전략의 선택은 애플리케이션의 특성, 성능 요구 사항 및 필요한 제어 수준과 같은 요소에 따라 달라집니다. 제한사항을 구현할 때 남용 방지와 반응적이고 공정한 사용자 경험 보장 사이에서 균형을 유지해야 합니다.

제한 메커니즘을 애플리케이션에 통합할 때 실제 사용 패턴을 기반으로 매개변수를 모니터링하고 조정하는 것을 고려하세요. 제약 조건 구현을 결정할 때 작업이 할당된 기한을 초과하는 상황을 처리하는 방법과 같은 몇 가지 질문이 발생할 수 있습니다. 다음 기사에서는 다양한 시나리오를 포괄적으로 다루는 강력한 Java 구현을 살펴볼 계획입니다.

위 내용은 Java의 제한 사항 살펴보기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 dzone.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제