Dalam dunia pembangunan perisian, mengurus penggunaan sumber secara berkesan dan memastikan penggunaan perkhidmatan yang adil adalah pertimbangan penting dalam membina aplikasi berskala dan mantap. Pendikitan ialah amalan mengawal kadar operasi tertentu dilakukan dan merupakan mekanisme utama untuk mencapai matlamat ini. Dalam artikel ini, kami akan mendalami pelbagai cara untuk melaksanakan pendikitan di Jawa dan memperkenalkan pelbagai strategi dengan contoh praktikal. .
Dalam dunia pembangunan perisian, mengurus penggunaan sumber secara berkesan dan memastikan penggunaan perkhidmatan yang adil adalah pertimbangan penting dalam membina aplikasi berskala dan mantap. Pendikitan ialah amalan mengawal kadar operasi tertentu dilakukan dan merupakan mekanisme utama untuk mencapai matlamat ini. Dalam artikel ini, kami akan mendalami pelbagai cara untuk melaksanakan pendikitan di Jawa dan memperkenalkan pelbagai strategi dengan contoh praktikal.
Penafian: Dalam artikel ini, saya akan menumpukan pada ilustrasi berbenang tunggal yang mudah menyelesaikan penyelesaian asas.
Had melibatkan mengawal selia kekerapan tindakan tertentu dibenarkan berlaku. Ini amat penting dalam situasi di mana sistem perlu dilindungi daripada penyalahgunaan, memerlukan pengurusan sumber atau memerlukan akses adil kepada perkhidmatan yang dikongsi. Kes penggunaan biasa untuk pendikit termasuk mengehadkan kadar permintaan API, mengurus kemas kini data dan mengawal akses kepada sumber kritikal.
Cara mudah untuk melaksanakan had adalah dengan menggunakan kaedah ini untuk memperkenalkan kelewatan antara operasi berturut-turut. Walaupun kaedah ini mudah, ia mungkin tidak sesuai untuk senario berprestasi tinggi kerana sifat menyekatnya. 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); } }
Dalam contoh ini, kelas ini membenarkan bilangan operasi tertentu untuk dilakukan sesaat. Jika masa berlalu antara operasi kurang daripada selang yang dikonfigurasikan, tempoh tidur diperkenalkan untuk mencapai kadar yang dikehendaki. SimpleRateLimiter
Mari kita mulakan dengan contoh mudah yang kita gunakan untuk mengehadkan pelaksanaan sesuatu kaedah. Matlamatnya adalah untuk membenarkan kaedah dipanggil hanya selepas masa bertenang tertentu telah berlalu. tunggu
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); } } }
Dalam contoh ini, kaedah menggunakan kaedah ini untuk membuat benang menunggu tempoh bertenang untuk tamat. throttledOperationwait
Mari tingkatkan contoh sebelumnya untuk memperkenalkan pendikitan dinamik, di mana tempoh bertenang boleh dilaraskan secara dinamik. Pengeluaran mesti mempunyai peluang untuk membuat perubahan dengan cepat.
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(); } } } }
Dalam contoh ini, kami memperkenalkan kaedah melaraskan masa bertenang secara dinamik. Kaedah ini digunakan untuk membangunkan sebarang urutan menunggu, membolehkan mereka menyemak masa bertenang baharu. setCooldownnotify
Kelas Java boleh digunakan sebagai alat berkuasa untuk pendikit. Semaphore mengekalkan satu set lesen, di mana setiap operasi perolehan menggunakan satu lesen dan setiap operasi pelepasan menambah satu lesen. 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(); } } }
Dalam contoh ini, kelas menggunakan a dengan bilangan lesen yang ditentukan. Kaedah ini cuba mendapatkan lesen dan membenarkan operasi jika berjaya. SemaphoreRateLimiterSemaphorethrottle
Frameworks seperti Spring atau Redis menyediakan pelbagai penyelesaian mudah.
Menggunakan keupayaan pengaturcaraan berorientasikan aspek (AOP) Spring, kami boleh mencipta mekanisme sekatan peringkat kaedah. Pendekatan ini membolehkan kami memintas panggilan kaedah dan menggunakan logik pendikit.
@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."); } } }
Dalam contoh ini, kami telah menentukan anotasi tersuai dan aspek AOP() untuk memintas kaedah menggunakan . @ThrottleThrottleAspect@ThrottleThrottleAspect
Pustaka Guava Google menyediakan kelas yang memudahkan pelaksanaan had. Ia membolehkan menentukan kadar operasi dibenarkan. RateLimiter
Mari kita lihat cara ia boleh digunakan untuk mengehadkan kaedah: 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."); } } }
Dalam contoh ini, kami menggunakan Guava untuk mengawal kadar pelaksanaan sesuatu kaedah. Kaedah ini digunakan untuk menyemak sama ada operasi dibenarkan berdasarkan kadar yang ditetapkan. RateLimiterthrottledOperationtryAcquire
Menggunakan stor data luaran seperti Redis, kami boleh melaksanakan mekanisme pendikitan teragih. Pendekatan ini amat berguna dalam persekitaran perkhidmatan mikro di mana beberapa keadaan perlu menyelaraskan kekangan.
@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); } }
Dalam contoh ini, kami menggunakan Redis untuk menyimpan dan mengurus kiraan operasi bagi setiap pengguna. Kaedah ini menambah kiraan dan menyemak sama ada had yang dibenarkan telah dicapai. performThrottledOperation
Pendikit memainkan peranan penting dalam mengekalkan kestabilan dan kebolehskalaan aplikasi anda. Dalam artikel ini, kami meneroka pelbagai cara untuk melaksanakan pendikitan dalam Java, termasuk teknik mudah untuk menggunakan dan menggunakan penyelesaian luar kotak. Thread.sleep()Semaphore
Pilihan strategi pendikit bergantung pada faktor seperti sifat aplikasi, keperluan prestasi dan tahap kawalan yang diperlukan. Apabila melaksanakan sekatan, anda mesti menyeimbangkan antara mencegah penyalahgunaan dan memastikan pengalaman pengguna yang responsif dan adil.
Apabila menyepadukan mekanisme pendikit ke dalam aplikasi anda, pertimbangkan untuk memantau dan melaraskan parameter berdasarkan corak penggunaan sebenar. Apabila membuat keputusan tentang pelaksanaan kekangan, beberapa pertanyaan mungkin timbul, seperti cara mengendalikan situasi di mana tugas melebihi tarikh akhir yang ditetapkan. Dalam artikel saya yang seterusnya, saya merancang untuk meneroka pelaksanaan Java yang mantap yang menangani pelbagai senario secara komprehensif.
Atas ialah kandungan terperinci Terokai batasan dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!