做网站下导航字号为多大重庆网站建设公司哪家好

news/2025/9/23 8:48:10/文章来源:
做网站下导航字号为多大,重庆网站建设公司哪家好,朔州市2018年建设工程网站,电子采购平台系统Redis系列之基于Jedis实现分布式锁 1、为什么需要分布式锁 在单机环境#xff0c;我们使用最多的是juc包里的单机锁#xff0c;但是随着微服务分布式项目的普及#xff0c;juc里的锁是不能控制分布锁环境的线程安全的#xff0c;因为单机锁只能控制同个进程里的线程安全我们使用最多的是juc包里的单机锁但是随着微服务分布式项目的普及juc里的锁是不能控制分布锁环境的线程安全的因为单机锁只能控制同个进程里的线程安全不能控制多节点的线程安全所以就需要使用分布式锁 2、redis分布式锁原理 学习之前先了解redis的命令setnx和expire setnx命令 SETNX是SET if not exists的简写设置key的值如果key值不存在则可以设置否则不可以设置这个有点像juc中cas锁的原理 # setnx命令相当于set和nx命令一起用 setnx tkey aaaEX 设置指定的到期时间(以秒为单位)。 PX : 设置指定的到期时间(以毫秒为单 NX 仅在键不存在时设置键。 XX 只有在键已存在时才设置。 expire命令 如果只使用setnx不加上过期时间手动释放锁时候出现异常就会导致一直解不了锁所以还是要加上expire命令来设置过期时间。 保证原子性 但是又有一个问题设置过期时间时候报错了也同样会导致锁释放不了所以为了保证原子性需要这两个命令一起执行 # set tkey过期时间10秒nx如果键不存在时设置 set tkey aaa ex 10 nx3、基于jedis手写分布锁锁 基于上面的原理我们就可以简单写一个分布锁锁 项目环境 JDK 1.8 SpringBoot 2.2.1 Maven 3.2 Mysql 8.0.26 spring-boot-starter-data-redis 2.2.1 jedis3.1.0 开发工具 IntelliJ IDEA smartGit 先搭建一个springboot集成jedis的例子工程参考我之前的博客大体的类图如图所示 写一个分布锁的通用接口因为以后可能会通过其它中间件实现分布锁锁 package com.example.jedis.common;public interface DistributedLock {default boolean acquire(String lockKey, String requestId) {return acquire(lockKey, requestId, RedisConstant.DEFAULT_EXPIRE);}default boolean acquire(String lockKey, String requestId, int expireTime) {return acquire(lockKey, requestId, expireTime, RedisConstant.DEFAULT_TIMEOUT);}boolean acquire(String lockKey, String requestId, int expireTime, int timeout);boolean release(String lockKey, String requestId);} 写一个抽象的分布锁锁类实现一些可以共用的逻辑其它的业务给子类去实现 package com.example.jedis.common;import lombok.extern.slf4j.Slf4j;import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit;import static com.example.jedis.common.RedisConstant.DEFAULT_EXPIRE; import static com.example.jedis.common.RedisConstant.DEFAULT_TIMEOUT;Slf4j public abstract class AbstractDistributedLock implements DistributedLock {Overridepublic boolean acquire(String lockKey, String requestId, int expireTime, int timeout) {expireTime expireTime 0 ? DEFAULT_EXPIRE : expireTime;timeout timeout 0 ? DEFAULT_TIMEOUT : timeout * 1000;long start System.currentTimeMillis();try {do {if (doAcquire(lockKey, requestId, expireTime)) {watchDog(lockKey, requestId, expireTime);return true;}TimeUnit.MILLISECONDS.sleep(100);} while (System.currentTimeMillis() - start timeout);} catch (Exception e) {Throwable cause e.getCause();if (cause instanceof SocketTimeoutException) {// ignore exceptionlog.error(sockTimeout exception:{}, e);}else if (cause instanceof InterruptedException) {// ignore exceptionlog.error(Interrupted exception:{}, e);}else {log.error(lock acquire exception:{}, e);}throw new LockException(e.getMessage(), e);}return false;}Overridepublic boolean release(String lockKey, String requestId) {try {return doRelease(lockKey, requestId);} catch (Exception e) {log.error(lock release exception:{}, e);throw new LockException(e.getMessage(), e);}}protected abstract boolean doAcquire(String lockKey, String requestId, int expireTime);protected abstract boolean doRelease(String lockKey, String requestId);protected abstract void watchDog(String lockKey, String requestId, int expireTime);} redis的分布锁锁抽象类 package com.example.jedis.common;public abstract class AbstractRedisLock extends AbstractDistributedLock{} 基于jedis的分布锁实现类主要通过lua脚本控制解锁的原子性同时加上watch dog定时续期避免有些长业务执行时间比较长而锁已经释放的情况 package com.example.jedis.common;import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.List; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit;Component Slf4j public class JedisLockTemplate extends AbstractRedisLock implements InitializingBean {private String UNLOCK_LUA if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end;private String WATCH_DOG_LUA local lock_keyKEYS[1]\n local lock_valueARGV[1]\n local lock_ttlARGV[2]\n local current_valueredis.call(get,lock_key)\n local result0\n if lock_valuecurrent_value then\n redis.call(expire,lock_key,lock_ttl)\n result1\n end\n return result;private static final Long UNLOCK_SUCCESS 1L;private static final Long RENEWAL_SUCCESS 1L;Autowiredprivate JedisTemplate jedisTemplate;private ScheduledThreadPoolExecutor scheduledExecutorService;Overridepublic void afterPropertiesSet() throws Exception {this.UNLOCK_LUA jedisTemplate.scriptLoad(UNLOCK_LUA);this.WATCH_DOG_LUA jedisTemplate.scriptLoad(WATCH_DOG_LUA);scheduledExecutorService new ScheduledThreadPoolExecutor(1);}Overridepublic boolean doAcquire(String lockKey, String requestId, int expire) {return jedisTemplate.setnxex(lockKey, requestId, expire);}Overridepublic boolean doRelease(String lockKey, String requestId) {Object eval jedisTemplate.evalsha(UNLOCK_LUA, CollUtil.newArrayList(lockKey), CollUtil.newArrayList(requestId));if (UNLOCK_SUCCESS.equals(eval)) {scheduledExecutorService.shutdown();return true;}return false;}Overridepublic void watchDog(String lockKey, String requestId, int expire) {int period getPeriod(expire);if (scheduledExecutorService.isShutdown()) {scheduledExecutorService new ScheduledThreadPoolExecutor(1);}scheduledExecutorService.scheduleAtFixedRate(new WatchDogTask(scheduledExecutorService, CollUtil.newArrayList(lockKey), CollUtil.newArrayList(requestId, Convert.toStr(expire))),1,period,TimeUnit.SECONDS);}class WatchDogTask implements Runnable {private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;private ListString keys;private ListString args;public WatchDogTask(ScheduledThreadPoolExecutor scheduledThreadPoolExecutor, ListString keys, ListString args) {this.scheduledThreadPoolExecutor scheduledThreadPoolExecutor;this.keys keys;this.args args;}Overridepublic void run() {log.info(watch dog for renewal...);Object evalsha jedisTemplate.evalsha(WATCH_DOG_LUA, keys, args);if (!evalsha.equals(RENEWAL_SUCCESS)) {scheduledThreadPoolExecutor.shutdown();}log.info(renewal result:{}, keys:{}, args:{}, evalsha, keys, args);}}private int getPeriod(int expire) {if (expire 1)throw new LockException(expire不允许小于1);return expire - 1;}} 写一个通用的jedis常有api的封装类setnxex加上synchronized因为redis是单线程的加上同步锁避免并发请求时候出现jedispool加载不到的情况 package com.example.jedis.common;import cn.hutool.core.collection.ConcurrentHashSet; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.params.SetParams;import javax.annotation.Resource; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; import java.util.function.Function;Slf4j Component public class JedisTemplate implements InitializingBean {Resourceprivate JedisPool jedisPool;private Jedis jedis;public JedisTemplate() {}Overridepublic void afterPropertiesSet() {jedis jedisPool.getResource();}public T T execute(FunctionJedis, T action) {T apply null;try {jedis jedisPool.getResource();apply action.apply(jedis);} catch (JedisException e) {handleException(e);throw e;} finally {jedis.close();}return apply;}public void execute(ConsumerJedis action) {try {jedis jedisPool.getResource();action.accept(jedis);} catch (JedisException e) {handleException(e);throw e;} finally {jedis.close();}}public JedisPool getJedisPool() {return this.jedisPool;}public synchronized Boolean setnxex(final String key, final String value, int seconds) {return execute(e - {SetParams setParams new SetParams();setParams.nx();setParams.ex(seconds);return isStatusOk(jedis.set(key, value, setParams));});}public Object eval(final String script,final Integer keyCount,final String... params) {return execute(e - {return jedis.eval(script, keyCount, params);});}public Object eval(final String script, final ListString keys, final ListString params) {return execute(e - {return jedis.eval(script, keys, params);});}public Object evalsha(final String script, final ListString keys, final ListString params) {return execute(e - {return jedis.evalsha(script, keys, params);});}public String scriptLoad(final String script) {return execute(e - {return jedis.scriptLoad(script);});}protected void handleException(JedisException e) {if (e instanceof JedisConnectionException) {log.error(redis connection exception:{}, e);} else if (e instanceof JedisDataException) {log.error(jedis data exception:{}, e);} else {log.error(jedis exception:{}, e);}}protected synchronized static boolean isStatusOk(String status) {return status ! null (OK.equals(status) || OK.equals(status));}} 常量类 package com.example.jedis.common;public class RedisConstant {public static final Integer DEFAULT_EXPIRE 30;public static final Integer DEFAULT_TIMEOUT 1;} 自定义的异常类 package com.example.jedis.common;public class LockException extends RuntimeException{public LockException(String message) {super(message);}public LockException(String message, Throwable t) {super(message, t);}} SpringBoot启动的Application类 package com.example.jedis;import cn.hutool.core.date.StopWatch; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling;import javax.annotation.PreDestroy; import javax.annotation.Resource;SpringBootApplication EnableScheduling EnableAsync Slf4j public class SpringbootJedisApplication {ResourceRedisConnectionFactory factory;public static void main(String[] args) {StopWatch stopWatch new StopWatch();stopWatch.start(springbootJedis);SpringApplication.run(SpringbootJedisApplication.class, args);stopWatch.stop();log.info(Springboot项目启动成功时间:{}ms \n, stopWatch.getTotalTimeMillis());log.info(stopWatch.prettyPrint());}PreDestroypublic void flushDB() {factory.getConnection().flushDb();}} 上面的逻辑已经基本实现了一款分布式锁也可以加一个自定义注解来实现 package com.example.jedis.common;import java.lang.annotation.*;Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface Lock {String lockKey();String requestId();int expire() default 30;int timeout() default 1;} 自定义一个切面类实现业务处理 package com.example.jedis.common;import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component;import javax.annotation.Resource; import java.lang.reflect.Method; import java.util.concurrent.Future;Component Aspect Slf4j public class WatchDog {Resourceprivate JedisLockTemplate jedisLockTemplate;Resourceprivate ThreadPoolTaskExecutor executor;Around(annotation(Lock))public Object proxy (ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature methodSignature (MethodSignature) joinPoint.getSignature();Method method methodSignature.getMethod();Lock lock method.getAnnotation(Lock.class);boolean acquire jedisLockTemplate.acquire(lock.lockKey(), lock.requestId(), lock.expire(), lock.timeout());if (!acquire)throw new LockException(获取锁失败!);FutureObject future executor.submit(() - {try {return joinPoint.proceed();} catch (Throwable e) {log.error(任务执行错误:{}, e);jedisLockTemplate.release(lock.lockKey(), lock.requestId());throw new RuntimeException(任务执行错误);} finally {jedisLockTemplate.release(lock.lockKey(), lock.requestId());}});return future.get();}} 写一个测试Controller类开始用SpringBoot测试类的但是发现有时候还是经常出现一些连接超时情况这个可能是框架兼容的bug package com.example.jedis.controller;import com.example.jedis.common.JedisLockTemplate; import com.example.jedis.common.Lock; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.stream.IntStream;RestController Slf4j public class TestController {private static final String REDIS_KEY test:lock;Autowiredprivate JedisLockTemplate jedisLockTemplate;GetMapping(test)public void test(RequestParam(threadNum)Integer threadNum) throws InterruptedException {CountDownLatch countDownLatch new CountDownLatch(threadNum);IntStream.range(0, threadNum).forEach(e-{new Thread(new RunnableTask(countDownLatch)).start();});countDownLatch.await();}GetMapping(testLock)Lock(lockKey test:api, requestId 123, expire 5, timeout 3)public void testLock() throws InterruptedException {doSomeThing();}class RunnableTask implements Runnable {CountDownLatch countDownLatch;public RunnableTask(CountDownLatch countDownLatch) {this.countDownLatch countDownLatch;}Overridepublic void run() {redisLock();countDownLatch.countDown();}}private void redisLock() {String requestId getRequestId();Boolean lock jedisLockTemplate.acquire(REDIS_KEY, requestId, 5, 3);if (lock) {try {doSomeThing();} catch (Exception e) {jedisLockTemplate.release(REDIS_KEY, requestId);} finally {jedisLockTemplate.release(REDIS_KEY, requestId);}} else {log.warn(获取锁失败!);}}private void doSomeThing() throws InterruptedException {log.info(do some thing);Thread.sleep(15 * 1000);}private String getRequestId() {String strabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;Random randomnew Random();StringBuffer sbnew StringBuffer();for(int i0;i32;i){int numberrandom.nextInt(62);sb.append(str.charAt(number));}return sb.toString();}} # 模拟100个并发请求 curl http://127.0.0.1:8080/springboot-jedis/test?threadNum100项目启动出现这种问题有可能是在SpringBoot的junit测试类里测试的setnxex方法加上synchronize同步锁 java.net.SocketTimeoutException: Read timed out Could not get a resource from the pool 总结本文基于jedis、jua脚本实现一个分布式锁redis分布式锁是基于AP模式的所以效率还是比较快的但是不能保证分布式的CP模式如果要保证高一致性可以选用其它分布式锁方案本文还考虑到长事务的情况使用watchdog对key进行续期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/911947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

卡尺 东莞网站建设做网站小语种翻译多少钱

本周刊记录有趣好玩的独立产品设计开发相关内容,每周发布,往期内容同样精彩,感兴趣的伙伴可以 点击订阅我的周刊。为保证每期都能收到,建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。 周刊继续发布 ❤️ 💻 产品推…

phpmysql网站开发全程实例个人做民宿需要建立网站吗

Windows系统下源代码下载编译、安装方式如下: https://blog.csdn.net/fxbjye/article/details/89152849 编译后得到库文件,把这两个文件复制到项目文件中, 修改项目文件的属性, 修改附加依赖项: 输入代码&#xff1…

网站怎么查询注册商北京 网站建设 京icp

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

后缀数组基础 Suffix Array

将字符串 \(s\) 的所有后缀按字典序排序。 SA 算法主要求以下数组:\(\text{sa}_i\):排名为 \(i\) 的后缀的下标。\(\text{rk}_i\):下标以 \(i\) 开始的排名。\(\text{ht}_i\):\(\text{height}\) 数组。\(\text{ht}…

网站后台管理优化wordpress 搜索框 位置

仪表应用背景 电力运维行业:运维服务系统实时采集大量用户站的运行和动环数据,经专业数据分析,当用户站发生异常情况或运行故障时,及时反馈到运维指挥中心,并通过移动终端通知相应的运维工程师,指导现场作…

一般做企业网站需要什么资料wordpress网站有哪些

一、源码特点 java 商机管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…

教师可以做网站吗顺德品牌网站建设

libcurl是C语言写成的网络编程工具库,asio是C写的网络编程的基础类型库 libcurl只用于客户端,asio既可以写客户端,也可以写服务端 libcurl实现了HTTP\FTP等应用层协议,但asio却只实现了传输层TCP/UDP等协议。 在学习http时介绍…

找能做网站的怎么做网站logo

在上一讲《Coursera自动驾驶课程第13讲:Least Squares》我们学习了最小二乘法相关知识。 本讲我们将学习20世纪最著名的一个算法:卡尔曼滤波。具体包括线性卡尔曼滤波(KF),扩展卡尔曼滤波(EKF),误差状态卡…

做网站怎么变现网站建设方案包括哪些内容

过犹不及——《论语先进》 大学考试时,有些老师允许带备cheet sheet(忘纸条),上面记着关键公式和定义,帮助我们快速作答提高分数。传统的检索增强生成(RAG)方法也类似,试图找出精准的知识片段来辅助大语言模型(LLM)。 但这种方法其实有问题…

有什么做分销的几个网站网站如何加速

What’s more 山东大学 2020级数据库系统 实验一 山东大学 2020级数据库系统 实验二 山东大学 2020级数据库系统 实验三 山东大学 2020级数据库系统 实验四 山东大学 2020级数据库系统 实验五 山东大学 2020级数据库系统 实验六 山东大学 2020级数据库系统 实验七 山东大学 20…

戴尔网站建设成功做企业网站的缺点

else 操作 我们有简单的用户处理程序: func handleRequest(user *User) {if user ! nil {showUserProfilePage(user)} else {showLoginPage()} }如果没有提供用户,则需要将收到的请求重定向到登录页面。If else 似乎是个不错的决定。但我们的主要任务是…

网站颜色搭配实例参考消息官方网站阅读

文档链接:https://programmercarl.com/ LeetCode509.斐波那契数 题目链接:https://leetcode.cn/problems/fibonacci-number/ 思路: 动规五部曲: 这里我们要用一个一维dp数组来保存递归的结果 1.确定dp数组以及下标的含义 d…

广州做外贸网站建设四川建设网和四川省公共资源交易信息网

转自PaddleOCR docker模式 - 简书 目的: 公司要放弃第三方的ocr工具(日语),需要自己搭建训练一套,这篇是搭建 图片要标出文字的选取框 因为是日文所以ocr有专门的工具,只需要文字坐标就好如图 日文的账票需要加密一下 我得环境是 Ubuntu 22.04.1 LTS 1,下载代码 cd /hom…

吉首自治州住房和城乡建设局网站阅读网站怎么做

Overfitting and Regularization 1. 过拟合添加正则化2. 具有正则化的损失函数2.1 正则化线性回归的损失函数2.2 正则化逻辑回归的损失函数 3. 具有正则化的梯度下降3.1 使用正则化计算梯度(线性回归 / 逻辑回归)3.2 正则化线性回归的梯度函数3.3 正则化…

用一部手机制作网站网站建设文化策划方案

领取福利记得长按,领取技术书籍哦随着互联网大潮的到来,越来越多网站,应用系统需要海量数据的支撑,高并发、低延迟、高可用、高扩展等要求在传统的关系型数据库中已经得不到满足,或者说关系型数据库应对这些需求已经显…

移动端网站教程微信怎样将网站的内容做

本文分享一个南网上行通信规约20140617 报文解析软件 下载链接: https://pan.baidu.com/s/1ngbBG-yL8ucRWLDflqzEnQ 提取码: y1de 主界面如下图所示: 本软件同时支持南网上行通信规约20140617-Fn查询功能 软件同时支持多种规约类型,如:国网…

做漆包线的招聘网站做会计题目的网站

Python作为一种流行的高级编程语言,它的独特特性之一就是全局解释器锁(Global Interpreter Lock,简称GIL)。本文将深入探讨GIL的定义、工作原理以及对Python的影响,并介绍如何应对GIL的限制。 1. 什么是GIL&#xff1…

网站建设标书模版怎么做情侣网站

目录 1. 什么是Docker1.1. 什么是容器1.2. 什么是Docker 2. 安装Docker3. 镜像操作3.1. 拉取镜像3.2. 卸载镜像/容器3.3. 使用镜像/容器 4. 相关指令说明 1. 什么是Docker 1.1. 什么是容器 虚拟机: 操作系统是一个很笨重的程序,即是啥都不干&#xff0c…

绘画做动作的网站网站做pc

目录 背影 极限学习机 爬山算法优化遗传算法优化极限学习机的多分类预测,p-ga-elm多分类预测 主要参数 MATLAB代码 效果图 结果分析 展望 完整代码下载链接:爬山算法优化遗传算法优化极限学习机的多分类预测,p-ga-elm多分类预测(代码完整,数据)资源-CSDN文库 https://d…

为什么做pc网站网站搭建软件d

什么是ArkTS? ArkTS是一个为鸿蒙组件而生的框架,语法亲人好用。基于TypeScript,ArkTS拓展了声明式UI、状态管理等的能力,从本质上来讲,是TypeScript的扩展,主要服务于前端。 ArkTS的开发可以满足“一次开…