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

网站数据库 备份台州seo排名优化

网站数据库 备份,台州seo排名优化,怎样在华为云服务器里建设网站,青岛做网站服务商1 分布式锁 Java锁能保证一个JVM进程里多个线程交替使用资源。而分布式锁保证多个JVM进程有序交替使用资源,保证数据的完整性和一致性。 分布式锁要求 互斥。一个资源在某个时刻只能被一个线程访问。避免死锁。避免某个线程异常情况不释放资源,造成死锁…

1 分布式锁

Java锁能保证一个JVM进程里多个线程交替使用资源。而分布式锁保证多个JVM进程有序交替使用资源,保证数据的完整性和一致性。
分布式锁要求

  1. 互斥。一个资源在某个时刻只能被一个线程访问。
  2. 避免死锁。避免某个线程异常情况不释放资源,造成死锁。
  3. 可重入。
  4. 高可用。高性能。
  5. 非阻塞,没获取到锁直接返回失败。

2 实现

1 lua脚本

为了实现redis操作的原子性,使用lua脚本。为了方便改脚本,将脚本单独写在文件里。

-- 加锁脚本
if redis.call('setnx', KEYS[1], ARGV[1]) == 1 thenredis.call('pexpire', KEYS[1], ARGV[2]);return true;
elsereturn false;
end-- 解锁脚本
if redis.call('get', KEYS[1]) == ARGV[1] thenredis.call('del', KEYS[1]);return true;
elsereturn false;
end-- 更新锁脚本
if redis.call('get', KEYS[1]) == ARGV[1] thenredis.call('pexpire', KEYS[1], ARGV[2]);-- pexpire与expire的区别是:pexpire毫秒级,expire秒级return true;
elsereturn false;
end

将脚本装在Springboot容器管理的bean里。

@Configuration
public class RedisConfig {@Bean("lock")public RedisScript<Boolean> lockRedisScript() {DefaultRedisScript redisScript = new DefaultRedisScript<>();redisScript.setResultType(Boolean.class);redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("/ratelimit/lock.lua")));return redisScript;}@Bean("unlock")public RedisScript<Boolean> unlockRedisScript() {DefaultRedisScript redisScript = new DefaultRedisScript<>();redisScript.setResultType(Boolean.class);redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("/ratelimit/unlock.lua")));return redisScript;}@Bean("refresh")public RedisScript<Boolean> refreshRedisScript() {DefaultRedisScript redisScript = new DefaultRedisScript<>();redisScript.setResultType(Boolean.class);redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("/ratelimit/refresh.lua")));return redisScript;}
}

redis分布式锁业务类

@Service
public class LockService {private static final long LOCK_EXPIRE = 30_000;private static final Logger LOGGER = LoggerFactory.getLogger(LockService.class);@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowired@Qualifier("lock")private RedisScript<Boolean> lockScript;@Autowired@Qualifier("unlock")private RedisScript<Boolean> unlockScript;@Autowired@Qualifier("refresh")private RedisScript<Boolean> refreshScript;public boolean lock(String key, String value) {boolean res = redisTemplate.execute(lockScript, List.of(key), value, LOCK_EXPIRE);if (res == false) {return false;}refresh(key, value);LOGGER.info("lock, key: {}, value: {}, res: {}", key, value, res);return res;}public boolean unlock(String key, String value) {Boolean res = redisTemplate.execute(unlockScript, List.of(key), value);LOGGER.info("unlock, key: {}, value: {}, res: {}", key, value, res);return res != null && Boolean.TRUE.equals(res);}private void refresh(String key, String value) {Thread t = new Thread(() -> {while (true) {redisTemplate.execute(refreshScript, List.of(key), value, LOCK_EXPIRE);try {Thread.sleep(LOCK_EXPIRE / 2);} catch (InterruptedException e) {e.printStackTrace();}LOGGER.info("refresh, current time: {}, key: {}, value: {}", System.currentTimeMillis(), key, value);}});t.setDaemon(true); // 守护线程t.start();}
}

测试类

@SpringBootTest(classes = DemoApplication.class)
public class LockServiceTest {@Autowiredprivate LockService service;private int count = 0;@Testpublic void test() throws Exception {List<CompletableFuture<Void>> taskList = new ArrayList<>();for (int threadIndex = 0; threadIndex < 10; threadIndex++) {CompletableFuture<Void> task = CompletableFuture.runAsync(() -> addCount());taskList.add(task);}CompletableFuture.allOf(taskList.toArray(new CompletableFuture[0])).join();}public void addCount() {String id = UUID.randomUUID().toString().replace("-", "");boolean tryLock = service.lock("account", id);while (!tryLock) {tryLock = service.lock("account", id);}for (int i = 0; i < 10_000; i++) {count++;}try {Thread.sleep(100_000);} catch (Exception e) {System.out.println(e);}for (int i = 0; i < 3; i++) {boolean releaseLock = service.unlock("account", id);if (releaseLock) {break;}}}
}

3 存在的问题

这个分布式锁实现了互斥,redis键映射资源,如果存在键,则资源正被某个线程持有。如果不存在键,则资源空闲。
避免死锁,靠的是设置reds键的过期时间,同时开启守护线程动态延长redis键的过期时间,直到该线程任务完结。
高性能。redis是内存数据库,性能很高。同时lua脚本使得redis以原子性更新锁状态,避免多次spirngboot与redis的网络IO。
非阻塞。lock()方法没有获取到锁立即返回false,不会阻塞当前线程。

没有实现可重入和高可用。高可用需要redis集群支持。

http://www.hengruixuexiao.com/news/31235.html

相关文章:

  • 文化建设的重要性关键词优化一般收费价格
  • 做网站素材网seo关键词优化怎么做
  • wordpress英语转换成汉文抖音seo优化系统招商
  • 建设政府网站十强公司网站的收录情况怎么查
  • 网站如何做问卷调查报告网络视频营销策略有哪些
  • 易乐自助建站政府免费培训面点班
  • 自己做的网站用国外的空间怎么样滕州今日头条新闻
  • 刘强东自己做网站南宁最新消息今天
  • 做别人一样的网站吗湖南百度推广代理商
  • 帝国网站管理系统教程seo网站优化培
  • 小狐狸动画制作软件app下载关键词优化意见
  • 五台建设局网站如何让百度搜索到自己的网站
  • seo网站优化详解可以推广的软件
  • 做网站接私活竞价推广工具
  • 网站开发知识产权归属拓客平台有哪些
  • 蛋糕网站制作答辩网站seo优化分析
  • 深圳自助网站建设费用女教师网课入06654侵录屏
  • 申请手机网站网址ip地址查询工具
  • 在社保网站上怎么做员工的退费在线优化seo
  • 网页设计素材为什么拖不进ps网站seo方案模板
  • 黑色网站模板广州seo网站优化培训
  • 网站备案拍照好麻烦徐州新站百度快照优化
  • 专业做网站设计哪家好seo顾问服务公司
  • icp备案网站接入信息ip地址段怎么填搜索引擎营销seo
  • 百度收录收费 重大网站今日刚刚发生的军事新闻
  • 合肥网站优化哪家好营销活动有哪些
  • 做旅游项目用哪家网站好营销型网站分为哪几种
  • 做一个赚钱的网站好广州推广引流公司
  • 网站建设 助力社会组织百度搜索指数的数据来源
  • 建设成一个网站的程序ks刷粉网站推广马上刷