当前位置: 首页 > wzjs >正文

优质的做网站网络营销成功案例有哪些

优质的做网站,网络营销成功案例有哪些,做的网站必须放在idc机房吗,bt最佳磁力搜索引擎吧分布式锁是分布式系统中解决资源竞争问题的重要机制。Redis凭借其高性能和原子性操作,成为实现分布式锁的热门选择。本文将详细介绍如何使用Java和Redis实现分布式锁,并重点讲解如何通过Lua脚本保证锁操作的原子性。 一、分布式锁的基本要求 一个可靠的…

分布式锁是分布式系统中解决资源竞争问题的重要机制。Redis凭借其高性能和原子性操作,成为实现分布式锁的热门选择。本文将详细介绍如何使用Java和Redis实现分布式锁,并重点讲解如何通过Lua脚本保证锁操作的原子性。

一、分布式锁的基本要求

一个可靠的分布式锁应满足以下条件:

  1. 互斥性:同一时刻只有一个客户端能持有锁

  2. 避免死锁:即使客户端崩溃,锁也能自动释放

  3. 容错性:只要大部分Redis节点正常运行,客户端就能获取和释放锁

  4. 释放锁的正确性:只能由锁的持有者释放锁

二、不使用Lua脚本的基础实现

1. 基础分布式锁实现(Java + StringRedisTemplate)

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.UUID;
import java.util.concurrent.TimeUnit;@Component
public class BasicRedisLock {private final StringRedisTemplate stringRedisTemplate;public BasicRedisLock(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}/*** 获取锁* @param lockKey 锁的key* @param expireTime 过期时间(秒)* @return 锁的value(用于释放锁时验证)*/public String lock(String lockKey, long expireTime) {String value = UUID.randomUUID().toString();Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS);return Boolean.TRUE.equals(success) ? value : null;}/*** 释放锁* @param lockKey 锁的key* @param value 锁的value* @return 是否释放成功*/public boolean unlock(String lockKey, String value) {// 1. 获取当前锁的值String currentValue = stringRedisTemplate.opsForValue().get(lockKey);// 2. 验证是否是自己的锁if (value.equals(currentValue)) {// 3. 删除锁return stringRedisTemplate.delete(lockKey);}return false;}
}

2. 基础实现的使用示例

@RestController
public class OrderController {@Autowiredprivate BasicRedisLock basicRedisLock;@PostMapping("/createOrder")public String createOrder() {String lockKey = "order_lock";String lockValue = null;try {// 尝试获取锁lockValue = basicRedisLock.lock(lockKey, 30);if (lockValue == null) {return "系统繁忙,请稍后再试";}// 执行业务逻辑return "订单创建成功";} finally {// 释放锁if (lockValue != null) {basicRedisLock.unlock(lockKey, lockValue);}}}
}

3. 基础实现的缺点

  1. 非原子性操作问题

    • 释放锁的操作分为"获取值"、"比较值"和"删除键"三步,不是原子操作

    • 在比较值和删除键之间,锁可能已过期并被其他客户端获取,导致误删别人的锁

  2. 网络延迟问题

    • 客户端A获取锁并执行时间过长,锁已自动释放

    • 客户端B获取了锁

    • 客户端A执行完任务后,仍会尝试释放锁,可能释放客户端B的锁

  3. 性能问题

    • 每次释放锁需要至少2次Redis操作(GET+DEL)

三、使用Lua脚本优化实现

1. Lua脚本实现的分布式锁

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;@Component
public class LuaRedisLock {private final StringRedisTemplate stringRedisTemplate;public LuaRedisLock(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}// 获取锁(与基础实现相同)public String lock(String lockKey, long expireTime) {String value = UUID.randomUUID().toString();Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS);return Boolean.TRUE.equals(success) ? value : null;}// 使用Lua脚本释放锁public boolean unlock(String lockKey, String value) {// Lua脚本String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"    return redis.call('del', KEYS[1]) " +"else " +"    return 0 " +"end";// 创建Redis脚本对象DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();redisScript.setScriptText(luaScript);redisScript.setResultType(Long.class);// 执行脚本Long result = stringRedisTemplate.execute(redisScript, Collections.singletonList(lockKey), value);return result != null && result == 1;}
}

2. Lua脚本详解

Lua脚本语法说明
-- KEYS[1] 表示第一个键参数
-- ARGV[1] 表示第一个非键参数
-- redis.call() 用于执行Redis命令-- 脚本逻辑:
if redis.call('get', KEYS[1]) == ARGV[1] then  -- 如果锁的值等于传入的值return redis.call('del', KEYS[1])          -- 则删除这个键
elsereturn 0                                   -- 否则返回0表示失败
end
Lua脚本在Redis中的优势
  1. 原子性:整个脚本作为一个整体执行,执行期间不会被其他命令打断

  2. 减少网络开销:多个操作合并为一个脚本,减少客户端与Redis的交互次数

  3. 灵活性:可以编写复杂的逻辑来处理各种场景

3. Lua脚本实现的使用示例

@RestController
public class PaymentController {@Autowiredprivate LuaRedisLock luaRedisLock;@PostMapping("/pay")public String payOrder(@RequestParam String orderId) {String lockKey = "pay_lock:" + orderId;String lockValue = null;try {// 尝试获取锁,设置30秒过期lockValue = luaRedisLock.lock(lockKey, 30);if (lockValue == null) {return "支付处理中,请勿重复提交";}// 执行业务逻辑processPayment(orderId);return "支付成功";} finally {// 释放锁if (lockValue != null) {luaRedisLock.unlock(lockKey, lockValue);}}}private void processPayment(String orderId) {// 支付处理逻辑}
}

四、两种实现的对比

特性基础实现Lua脚本实现
原子性非原子操作原子操作
安全性可能误删别人的锁不会误删别人的锁
网络开销至少2次Redis操作1次Redis操作
实现复杂度简单需要了解Lua脚本
性能较低较高
适用场景对安全性要求不高的简单场景对安全性和性能有要求的场景

五、Lua脚本的更多用法

1. 带重试的获取锁脚本

public String lockWithRetry(String lockKey, long expireTime, long waitTime) {String value = UUID.randomUUID().toString();String luaScript = "local wait = tonumber(ARGV[3]) * 1000 " +"local endTime = redis.call('time')[1] * 1000 + wait " +"while redis.call('time')[1] * 1000 < endTime do " +"    if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then " +"        redis.call('expire', KEYS[1], ARGV[2]) " +"        return ARGV[1] " +"    end " +"    -- 短暂休眠 " +"    redis.call('echo', 'waiting...') " +"end " +"return nil";DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();redisScript.setScriptText(luaScript);redisScript.setResultType(String.class);return stringRedisTemplate.execute(redisScript,Collections.singletonList(lockKey),value, String.valueOf(expireTime), String.valueOf(waitTime));
}

2. 锁续期脚本

public boolean renewLock(String lockKey, String value, long expireTime) {String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"    return redis.call('expire', KEYS[1], ARGV[2]) " +"else " +"    return 0 " +"end";DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();redisScript.setScriptText(luaScript);redisScript.setResultType(Long.class);Long result = stringRedisTemplate.execute(redisScript,Collections.singletonList(lockKey),value, String.valueOf(expireTime));return result != null && result == 1;
}

六、总结

  1. 基础实现简单但存在安全隐患,适合对一致性要求不高的场景

  2. Lua脚本实现通过原子操作解决了安全问题,是生产环境推荐的做法

  3. Lua脚本在Redis中执行是原子的,适合实现复杂的多步操作

  4. 实际应用中还可以结合Redisson等成熟框架,它们提供了更完善的分布式锁实现

 

http://www.dtcms.com/wzjs/64297.html

相关文章:

  • 中国大型建筑公司有哪些蔡甸seo排名公司
  • ui设计方向网站建设目标seo搜索引擎优化报价
  • 武汉网站开发哪家好海底捞口碑营销案例
  • 石家庄企业网站建设公司培训心得体会500字
  • wordpress 淘宝客页面西安seo高手
  • 行业门户网站模板公司搜索seo
  • 重庆市建设安全监督站的网站软件定制开发公司
  • 动效网站建设推广普通话手抄报图片大全
  • 在xampp下搭建本地网站域名地址查询
  • 北京P2P公司网站建设百度浏览器
  • 网页制作与网站设计论文一键优化下载
  • 烟台酒店网站建设下载百度2024最新版
  • wordpress调用文件上传抖音优化
  • 网站提取规则怎么设置bilibili推广网站
  • 中国最大的外贸平台宁波专业seo服务
  • 企业官网怎么注册网站seo技术能不能赚钱
  • 汕头制作网站软件百度推广多少钱一个月
  • 网站的资讯内容新站快速收录
  • 饰品公司网站建设策划书网站怎么优化排名靠前
  • 阿里云怎样做商城式网站百度关键词推广工具
  • 帮别人做ppt赚钱的网站seo的中文含义
  • 做网站需要租服务器吗推广平台怎么找客源
  • 如何让wordpress id连续网站及搜索引擎优化建议
  • 政府门户网站建设策划网络营销模式有哪些?
  • 19寸 网站做多大百度广告联盟平台的使用知识
  • 12306网站如何做火车票候补360优化大师安卓下载
  • 常用搜索网站如何做网络推广
  • 社区论坛自助建站网看片应该搜什么关键词哪些词
  • 企业网站推广可以选择哪些方法?网络营销的优势与不足
  • 网站片头怎么做深圳网络营销推广公司