Redisson实现 如果一个外卖配送单子要发布,现在有200个骑手都想要接这一单,如何保证只有一个骑手接到单子?

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。Redisson实现 如果一个外卖配送单子要发布,现在有200个骑手都想要接这一单,如何保证只有一个骑手接到单子?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

Redisson实现

要实现只有一个骑手接到外卖配送单子,可以使用分布式锁来确保只有一个骑手能够成功接单。下面是一种基于Java和Spring Boot的实现方式:

  1. 引入依赖:在项目的pom.xml文件中添加以下依赖,用于使用分布式锁的功能。这是一个示例,你可以根据具体需求选择适合的分布式锁库。
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.16.2</version>
</dependency>
  1. 配置Redisson:在Spring Boot的配置文件中添加Redisson的配置,用于连接Redis服务。
spring:
  redis:
    host: your-redis-host
    port: your-redis-port
  1. 创建接单服务:创建一个接单服务类,使用分布式锁来保证只有一个骑手能够成功接单。
package com.tan.springboot2.p1;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class OrderService {

    private static final String LOCK_KEY = "order-lock:";

    @Autowired
    private RedissonClient redissonClient;

    public boolean takeOrder(Integer orderId) {
        RLock lock = redissonClient.getLock(LOCK_KEY + orderId);
        try {
            // 尝试获取分布式锁,设置锁的过期时间,避免锁长时间占用
            boolean locked = lock.tryLock(10, 300, TimeUnit.SECONDS);
            if (locked) {
                log.info("cg");
                // 在这里实现接单逻辑
                Thread.sleep(280 * 1000L);
                // ...
                return true; // 接单成功
            } else {
                log.info("sb");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock(); // 释放锁
            }
        }
        return false; // 接单失败
    }
}


package com.tan.springboot2.p1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//(160条消息) 如果一个外卖配送单子要发布,现在有200个骑手都想要接这一单,如何保证只有一个骑手接到单子?_powerTan01的博客-CSDN博客
//https://blog.csdn.net/tanwu1/article/details/130721622

@RestController
@RequestMapping("/p1")
public class P {

    @Autowired
    OrderService orderService;

    @GetMapping("/m/{orderId}")
    public boolean m(@PathVariable Integer orderId) {
        return orderService.takeOrder(orderId);
    }

}


在上述代码中,通过RedissonClient获取一个分布式锁实例,并使用tryLock方法尝试获取锁。如果成功获取到锁,则执行接单逻辑,完成后释放锁。如果无法获取到锁,表示已经有其他骑手接单,返回接单失败。

这样,当有多个骑手同时调用takeOrder方法时,只有一个骑手能够成功获取到分布式锁并接单,其他骑手将无法获取到锁,从而实现了只有一个骑手能够接到单子的效果。

请注意,在使用分布式锁时,需要确保Redis服务正常运行,并且配置的锁过期时间合理,以避免锁长时间占用。此外,还需处理可能的异常情况,例如锁获取超时或中断等。

以上是一个基于Java和Spring Boot的实现示例,具体实现方式可能会根据实际需求和项目架构有所不同。

boolean locked = lock.tryLock(10, 300, TimeUnit.SECONDS); 锁续期规则是怎么样

在Redisson中,使用tryLock方法获取分布式锁时,可以指定一个锁续期的时间。当成功获取到锁时,会为该锁设置一个过期时间,并在到期前不断自动进行续期。

锁续期规则如下:

  • 初始获取锁时,设置的过期时间即为锁的初始过期时间。
  • 在获取锁成功后,Redisson会在锁的过期时间的2/3处开始自动进行续期。
  • 续期的时间间隔是通过心跳机制来控制的,每隔一定的时间,Redisson会向Redis发送续期指令,更新锁的过期时间。

具体的续期机制可以保证在获取锁成功后,只要锁的持有者仍在运行,并且没有发生异常情况,锁会一直持有,直到锁的持有者释放锁或发生锁超时。

tryLock方法中,你可以传入等待时间参数,用于等待获取锁的最大时间。如果在等待时间内无法获取到锁,tryLock方法会返回false,表示获取锁失败。

需要注意的是,锁的续期是在Redisson客户端自动进行的,而不是在Redis服务器端。因此,如果Redisson客户端发生意外终止或网络故障,可能导致锁无法进行续期,最终导致锁的过期。

综上所述,通过合理设置锁的过期时间和等待时间,可以在分布式环境中实现可靠的锁续期机制。但仍需注意处理可能的异常情况和故障恢复策略,以确保锁的正常使用。

代码

https://github.com/tanwu001/springboot2.1
p1包中

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/161151.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!