¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package org.springblade.core.redis.ratelimiter; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springblade.core.tool.utils.CharPool; |
| | | import org.springframework.core.env.Environment; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.data.redis.core.script.RedisScript; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * redis éæµæå¡ |
| | | * |
| | | * @author dream.lu |
| | | */ |
| | | @RequiredArgsConstructor |
| | | public class RedisRateLimiterClient implements RateLimiterClient { |
| | | /** |
| | | * redis éæµ key åç¼ |
| | | */ |
| | | private static final String REDIS_KEY_PREFIX = "limiter:"; |
| | | /** |
| | | * 失败çé»è®¤è¿åå¼ |
| | | */ |
| | | private static final long FAIL_CODE = 0; |
| | | /** |
| | | * redisTemplate |
| | | */ |
| | | private final StringRedisTemplate redisTemplate; |
| | | /** |
| | | * redisScript |
| | | */ |
| | | private final RedisScript<List<Long>> script; |
| | | /** |
| | | * env |
| | | */ |
| | | private final Environment environment; |
| | | |
| | | @Override |
| | | public boolean isAllowed(String key, long max, long ttl, TimeUnit timeUnit) { |
| | | // redis key |
| | | String redisKeyBuilder = REDIS_KEY_PREFIX + |
| | | getApplicationName(environment) + CharPool.COLON + key; |
| | | List<String> keys = Collections.singletonList(redisKeyBuilder); |
| | | // 毫ç§ï¼èè主ä»çç¥åèæ¬åæ¾æºå¶ï¼è¿ä¸ªtimeç±å®¢æ·ç«¯è·åä¼ å
¥ |
| | | long now = System.currentTimeMillis(); |
| | | // 转为毫ç§ï¼pexpire |
| | | long ttlMillis = timeUnit.toMillis(ttl); |
| | | // æ§è¡å½ä»¤ |
| | | List<Long> results = this.redisTemplate.execute(this.script, keys, max + "", ttlMillis + "", now + ""); |
| | | // ç»æä¸ºç©ºè¿å失败 |
| | | if (results == null || results.isEmpty()) { |
| | | return false; |
| | | } |
| | | // 夿è¿åæå |
| | | Long result = results.get(0); |
| | | return result != FAIL_CODE; |
| | | } |
| | | |
| | | private static String getApplicationName(Environment environment) { |
| | | return environment.getProperty("spring.application.name", ""); |
| | | } |
| | | |
| | | } |