发送验证按,存redis

1、pom引入:

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>3.2.8</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>1.1.0</version>
</dependency>

2、controller:

/**
 * 发送验证码
 * @param phone
 * @return
 */
@RequestMapping(value = "sendSmsCode",method = RequestMethod.POST)
public ResponseEntity<?> sendSmsCode(String phone) {
    boolean flag = authService.sendSmsCode(phone);
    return ResponseEntity.ok(flag);
}

3、service:(SmsUtil工具类查看本人另一篇博客)

@Resource
RedisTemplate<String, Object> redisTemplate;

/**
* 发送验证码
*
* @param phone
* @return
*/
public Boolean sendSmsCode(String phone) {
    // 生成随机数(6位)
    Random random = new Random();
    int code = random.nextInt(999999);

    if ("success".equals(SmsUtil.sendSms(phone, String.valueOf(code)))) {
        redisTemplate.opsForValue().set(phone, String.valueOf(code), 300, TimeUnit.SECONDS);
        return true;
    } else {
        return false;
    }
}

### Java Redis Lua 扣减库 实现方案 示例代码 #### 方案概述 为了实现高效的库扣减操作并解决高并发场景下的竞争问题,可以利用 Redis 的原子性和 Lua 脚本来完成这一功能。Lua 脚本可以在服务器端执行,从而避免多次网络往返带来的延迟,并确保操作的原子性。 以下是基于 JavaRedis 结合 Lua 脚本实现库扣减的具体方法: --- #### 1. **引入依赖** 在项目中引入 Redis 客户端库 `Jedis` 或者 `Lettuce` 来连接 Redis 并执行命令。这里以 Jedis 为例: ```xml <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.0.0</version> </dependency> ``` --- #### 2. **Lua 脚本设计** 编写一个简单的 Lua 脚本用于库扣减逻辑。该脚本会在 Redis 中运行,判断当前库是否充足,并进行相应的扣减操作。 ```lua -- Lua script for stock decrement with lock local key = KEYS[1] -- Key name, e.g., "stock" local value = tonumber(ARGV[1]) -- Decrement amount if redis.call('GET', key) and tonumber(redis.call('GET', key)) >= value then local current_stock = redis.call('DECRBY', key, value) return current_stock else return -1 -- Insufficient stock or no stock available end ``` 此脚本的功能如下: - 判断指定键是否在以及其值是否大于等于要扣减的数量。 - 如果满足条件,则调用 `DECRBY` 减少库。 - 否则返回 `-1` 表示库不足[^3]。 --- #### 3. **Java 实现代码** 下面是一个完整的 Java 方法,展示如何加载 Lua 脚本并通过 Redis 进行库扣减。 ```java import redis.clients.jedis.Jedis; import redis.clients.jedis.Scripting; public class StockService { private static final String STOCK_KEY = "stock"; private static final int INITIAL_STOCK = 10; // Initial stock quantity public static void main(String[] args) { try (Jedis jedis = new Jedis("localhost", 6379)) { // Initialize the stock in Redis jedis.set(STOCK_KEY, String.valueOf(INITIAL_STOCK)); // Define the Lua script as a string String luaScript = "local key = KEYS[1]\n" + "local value = tonumber(ARGV[1])\n" + "\n" + "if redis.call('GET', key) and tonumber(redis.call('GET', key)) >= value then\n" + " local current_stock = redis.call('DECRBY', key, value)\n" + " return current_stock\n" + "else\n" + " return -1\n" + "end"; // Simulate multiple threads to perform concurrent decrements simulateConcurrentDecrement(jedis, luaScript); } } private static void simulateConcurrentDecrement(Jedis jedis, String luaScript) { long successCount = 0; int threadCount = 6; CountDownLatch latch = new CountDownLatch(threadCount); Runnable task = () -> { boolean isSuccessful = false; while (!isSuccessful && jedis.exists(STOCK_KEY)) { Long result = (Long) jedis.eval(luaScript, 1, STOCK_KEY, "1"); if (result != null && result != -1) { isSuccessful = true; successCount++; } } latch.countDown(); }; List<Thread> threads = new ArrayList<>(); for (int i = 0; i < threadCount; i++) { Thread t = new Thread(task); threads.add(t); t.start(); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("成功扣减库的操作数: " + successCount); System.out.println("最终剩余库数量: " + jedis.get(STOCK_KEY)); } } ``` --- #### 4. **解释与注意事项** - 上述代码模拟了多个线程同时尝试扣减库的情况,验证了 Lua 脚本的原子性。 - 使用 `jedis.eval()` 将 Lua 脚本发送Redis 服务端执行,确保整个过程不会被其他客户端中断[^4]。 - 当前库不足以支持扣减时,脚本会返回 `-1`,表示失败。 --- #### 5. **扩展优化建议** 如果需要进一步增强系统的可靠性和性能,可考虑以下改进措施: - **设置过期时间**:为库键设置合理的 TTL(Time To Live),防止数据永久驻留。 - **分布式锁机制**:虽然 Lua 脚本本身具有原子性,但在更复杂的业务场景下仍需配合分布式锁工具(如 Redlock 算法)[^1]。 - **监控与报警**:实时监测 Redis 数据状态,及时发现异常情况。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值