Apa yang saya pelajari semasa membuat projek sampingan…
Pengenalan: Pengaturcaraan Berorientasikan Aspek (AOP) ialah teknik yang berkuasa dalam Spring Boot untuk memisahkan kebimbangan silang daripada logik aplikasi utama. Satu kes penggunaan biasa AOP ialah melaksanakan pengehadan kadar dalam API, di mana anda mengehadkan bilangan permintaan yang boleh dibuat oleh pelanggan dalam tempoh tertentu. Dalam artikel ini, kami akan meneroka cara memanfaatkan AOP untuk melaksanakan pengehadan kadar dalam Spring Boot API, memastikan prestasi optimum dan penggunaan sumber.
Pengaturcaraan Berorientasikan Aspek ialah paradigma pengaturcaraan yang bertujuan untuk memodulasi kebimbangan silang dalam pembangunan perisian. Kebimbangan silang adalah aspek program yang mempengaruhi berbilang modul dan sukar untuk dimodulasi menggunakan pendekatan tradisional. Contohnya termasuk pengelogan, keselamatan dan pengurusan transaksi.
AOP memperkenalkan konsep aspek, yang merangkumi kebimbangan silang. Aspek ialah unit modular yang boleh digunakan merentasi bahagian aplikasi yang berbeza tanpa mengubah logik teras. Rangka kerja AOP, seperti Spring AOP, menyediakan mekanisme untuk mentakrifkan aspek dan menerapkannya pada titik gabungan tertentu dalam aliran pelaksanaan aplikasi.
Penghadan kadar ialah keperluan biasa dalam API web untuk mencegah penyalahgunaan dan memastikan penggunaan sumber yang adil. Dengan AOP dalam Spring Boot, kami boleh melaksanakan pengehadan kadar dengan memintas seruan kaedah dan menguatkuasakan sekatan ke atas bilangan permintaan yang dibenarkan dalam tempoh masa tertentu.
Untuk melaksanakan pengehadan kadar dengan AOP dalam Spring Boot, kami biasanya mengikuti langkah berikut:
Melaksanakan pengehadan kadar dalam Spring Boot API boleh dicapai menggunakan pelbagai teknik. Satu pendekatan biasa ialah menggunakan Spring AOP (Aspect-Oriented Programming) untuk memintas permintaan masuk dan menguatkuasakan had kadar.
Langkah 1 - Tentukan Konfigurasi Had Kadar: Buat kelas konfigurasi di mana anda menentukan parameter had kadar seperti bilangan permintaan yang dibenarkan dan tempoh masa.
@Configuration public class RateLimitConfig { @Value("${rate.limit.requests}") private int requests; @Value("${rate.limit.seconds}") private int seconds; // Getters and setters }
Langkah 2 — Buat Aspek Mengehadkan Kadar: Laksanakan aspek menggunakan Spring AOP untuk memintas panggilan kaedah dan menguatkuasakan had kadar.
@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 } }
Langkah 3 — Tentukan Anotasi RateLimited: Buat anotasi tersuai untuk menandakan kaedah yang sepatutnya dihadkan kadar.
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RateLimited { }
Langkah 4 — Laksanakan Pengehad Kadar: Buat komponen pengehad kadar untuk mengurus had kadar menggunakan algoritma baldi token atau mana-mana algoritma lain yang sesuai.
@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; } } }
Langkah 5 — Anotasi Kaedah Pengawal: Anotasi kaedah pengawal yang sepatutnya dihadkan kadar dengan @RateLimited.
@RestController public class MyController { @RateLimited @GetMapping("/api/resource") public ResponseEntity<String> getResource() { // Implementation } }
Langkah 6 — Konfigurasikan Sifat Had Kadar: Konfigurasikan sifat had kadar dalam application.properties atau application.yml anda.
rate.limit.requests=10 rate.limit.seconds=60
Tambahan pula…
Untuk mengehadkan permintaan mengikut alamat IP, anda boleh mengekstrak alamat IP daripada permintaan masuk dan menggunakannya sebagai kunci untuk mengehadkan kadar. Begini cara anda boleh mengubah suai kaedah getKey untuk menghasilkan kunci unik berdasarkan alamat IP:
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 }
Anda juga perlu mengubah suai kaedah enforceRateLimit dalam kelas RateLimitAspect untuk menghantar objek HttpServletRequest ke kaedah getKey:
@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(); }
Dalam contoh ini, kami mentakrifkan anotasi tersuai @RateLimited untuk menandakan kaedah yang sepatutnya dihadkan kadar. Kami kemudian membuat aspek RateLimitAspect yang memintas panggilan kaedah yang dianotasi dengan @RateLimited. Di dalam aspek tersebut, kami menguatkuasakan had kadar menggunakan komponen RateLimiter.
Dalam artikel ini, kami telah meneroka cara melaksanakan pengehadan kadar dalam Spring Boot API menggunakan Pengaturcaraan Berorientasikan Aspek (AOP). Dengan memisahkan kebimbangan silang seperti pengehadan kadar daripada logik aplikasi teras, kami boleh memastikan modulariti, kebolehselenggaraan dan kebolehskalaan yang lebih baik bagi aplikasi kami. AOP menyediakan mekanisme yang berkuasa untuk menangani kebimbangan sedemikian, membolehkan pembangun menumpukan pada membina API yang teguh dan cekap.
Dengan mengikut langkah-langkah yang digariskan dalam artikel ini dan memanfaatkan keupayaan AOP dalam Spring Boot, pembangun boleh melaksanakan pengehadan kadar dengan mudah dan kebimbangan lain dalam aplikasi mereka, yang membawa kepada API yang lebih berdaya tahan dan berprestasi tinggi.
Atas ialah kandungan terperinci Cara Melaksanakan Pengehadan Kadar dalam API Boot Spring Menggunakan Pengaturcaraan Berorientasikan Aspek. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!