日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

这才是实现分布式锁的正确姿势!

發(fā)布時間:2025/3/21 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这才是实现分布式锁的正确姿势! 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

都9102年了,你還在手寫分布式鎖嗎?

經(jīng)常被問到”如何實現(xiàn)分布式鎖”,看來這是大家的一個痛點。

其實Java世界的”半壁江山”——Spring早就提供了分布式鎖的實現(xiàn)。早期,分布式鎖的相關(guān)代碼存在于Spring Cloud的子項目Spring Cloud Cluster中,后來被遷到Spring Integration中。

  • Spring Cloud Cluster的GitHub:https://github.com/spring-cloud/spring-cloud-cluster[1]?,里面有些用例,以及基于ETCD、hazelcast的分布式鎖實現(xiàn)值得一看
  • Spring Integration的GitHub:https://github.com/spring-projects/spring-integration[2]

TIPS

這就是明明?Spring Cloud官方[3]?說自己實現(xiàn)了?Global Locks?,但又無法找到任何相關(guān)文檔的原因——人家早把相關(guān)代碼搬遷到Spring Integration了。

可能有不少童鞋對Spring Integration不是很熟悉,簡單介紹一下——官方說法,這是一個?企業(yè)集成模式?的實現(xiàn);通俗地說,Spring Integration的定位是一個輕量級的ESB,盡管它做了很多ESB不做的事情。順便說一下,Spring Cloud Stream的底層也是Spring Integration。

Spring Integration提供的全局鎖目前為如下存儲提供了實現(xiàn):

  • Gemfire[4]
  • JDBC[5]
  • Redis[6]
  • Zookeeper[7]

它們使用相同的API抽象——這正是Spring最擅長的。這意味著,不論使用哪種存儲,你的編碼體驗是一樣的,有一天想更換實現(xiàn),只需要修改依賴和配置就可以了,無需修改代碼

TIPS

實現(xiàn)無關(guān)性:舉個例子,你目前有一個基于Redis的分布式鎖,但有一天想將存儲改為Consul。此時,統(tǒng)一的API至關(guān)重要——我相信你不會希望僅僅是修改了分布式鎖的存儲,就得讓開發(fā)把相關(guān)代碼翻新一遍

大學(xué)的時候,不也講過面向接口編程的重要性嘛。

因此,即使Spring Integration沒有為您使用的存儲提供實現(xiàn)(例如Consul),你也應(yīng)該基于Spring Integration的API去開發(fā)。這樣未來的某一天,一旦Spring Integration為你的存儲提供支持,你就可以無痛切換啦

編碼

下面以Redis為例,講解Spring Integration里面如何使用分布式鎖。

1 加依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId> </dependency> <dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-redis</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>

2 寫配置:

spring:redis:port: 6379host: localhost

3 寫代碼:初始化

@Configuration public class RedisLockConfiguration {@Beanpublic RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {return new RedisLockRegistry(redisConnectionFactory, "spring-cloud");} }

強烈建議閱讀一下?org.springframework.integration.redis.util.RedisLockRegistry?的注釋,它詳細描述了該類的特性,例如可重入性以及鎖在Redis中如何存儲等

4 寫代碼:測試

@GetMapping("test") public void test() throws InterruptedException {Lock lock = redisLockRegistry.obtain("lock");boolean b1 = lock.tryLock(3, TimeUnit.SECONDS);log.info("b1 is : {}", b1);TimeUnit.SECONDS.sleep(5);boolean b2 = lock.tryLock(3, TimeUnit.SECONDS);log.info("b2 is : {}", b2);lock.unlock();lock.unlock(); }

測試

1 啟動1個實例,訪問?http://localhost:8080/test?,會看到類似如下的日志:

2019-03-15 00:48:38.948 INFO 21893 --- [nio-8080-exec-1] c.itmuch.lock.SpringBootLockApplication : b1 is : true 2019-03-15 00:48:43.958 INFO 21893 --- [nio-8080-exec-1] c.itmuch.lock.SpringBootLockApplication : b2 is : true

2 啟動2個實例,并迅速訪問兩個實例的?/test?端點,會在第二個實例上看到類似如下日志:

2019-03-15 00:50:08.222 INFO 21898 --- [nio-8081-exec-3] c.itmuch.lock.SpringBootLockApplication : b1 is : false 2019-03-15 00:50:13.233 INFO 21898 --- [nio-8081-exec-3] c.itmuch.lock.SpringBootLockApplication : b2 is : true 2019-03-15 00:50:13.252 ERROR 21898 --- [nio-8081-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: You do not own lock at spring-cloud:lock] with root causejava.lang.IllegalStateException: You do not own lock at spring-cloud:lockat org.springframework.integration.redis.util.RedisLockRegistry$RedisLock.unlock(RedisLockRegistry.java:300) ~[spring-integration-redis-5.1.3.RELEASE.jar:5.1.3.RELEASE]at com.itmuch.lock.SpringBootLockApplication.test(SpringBootLockApplication.java:33) ~[classes/:na]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.16.jar:9.0.16]at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.16.jar:9.0.16]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.16.jar:9.0.16]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.16.jar:9.0.16]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 說明第二個實例沒有拿到鎖,證明了分布式鎖的存在。

至此,是不是讓你有刪掉手寫的那些蹩腳的分布式鎖的沖動呢?

總結(jié)

以上是生活随笔為你收集整理的这才是实现分布式锁的正确姿势!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 蜜桃成人免费视频 | 美女扒开粉嫩的尿囗给男生桶 | 午夜精品视频在线 | 蜜臀久久99精品久久久无需会员 | 亚洲免费国产视频 | 国产精品久久婷婷 | 美女张开腿露出尿口 | av中文资源在线 | 亚洲欲妇| 国内精品视频在线播放 | 与亲女洗澡时伦了毛片 | 日本性网站 | 日本爽爽爽爽爽爽在线观看免 | 免费观看的黄色网址 | 国产精品久久久久久久久毛片 | 国产乱码精品一区二区 | 国产999在线 | 黄色片xxxx | 日韩欧美精品在线视频 | 国产美女免费视频 | 久久狠狠爱 | 可以直接观看的av | 国产视频一区二区不卡 | 欧美性色黄大片手机版 | 88久久精品无码一区二区毛片 | 青青青青青青青青草 | 久久久久久久国产精品美女 | 亚洲iv一区二区三区 | 国产精品四虎 | 美女网站在线看 | 操你啦免费视频 | 亚洲毛片一区二区 | xxsm.com| 五月婷婷狠狠 | 艳母动漫在线播放 | 色屁屁影院www国产高清麻豆 | 91麻豆精品久久久久蜜臀 | 亚洲精品视频导航 | 国产骚b | 中文在线字幕免费观 | 黄色亚洲精品 | 欧美激情一二三区 | 日本中文在线观看 | 成年人精品视频 | 色啪网站 | 国产精品欧美日韩 | 亚洲精品视频大全 | japanese24hdxxxx中文字幕 | 亚洲精品888 | 国产思思99re99在线观看 | 91区| 无码成人精品区在线观看 | 久热精品在线 | 亚洲高清二区 | 91久久久久久久久久 | 日韩欧美一区视频 | 日本福利一区二区三区 | 天堂中文资源在线观看 | 日韩国产二区 | 精品人妻无码一区二区性色 | 天天色成人 | www亚洲精品 | 国产美女主播在线 | 国产一区免费在线 | 亚洲精品影院在线 | 国产视频一区在线观看 | 99精品中文字幕 | 日韩高清片 | 亚洲一区中文字幕在线 | 一女双乳被两男吸视频 | 亚洲三级免费观看 | 国产裸体网站 | 黄色污污网站在线观看 | 20日本xxxxxxxxx46 欧美激情一级 | 国产91免费观看 | 91丨porny在线 | 日本人妻换人妻毛片 | 日韩一区二区精品视频 | 9i精品福利一区二区三区 | 搡老熟女老女人一区二区 | 国产精品一区二区三区久久 | 末路1997全集免费观看完整版 | 欧美日韩在线中文字幕 | aⅴ天堂网| 国产欧美在线观看视频 | 四虎影视在线 | 亚洲一区有码 | 欧美三级一区二区 | 国产精品成人免费 | 高清在线一区二区 | 亚洲第一二三四区 | 先锋影音av资源在线 | 色爱AV综合网国产精品 | 日韩少妇精品 | 国产成人精品一区二区三区视频 | 男人插女人视频网站 | 免费久久久久 | 中文字幕在线精品 | 久久福利网 |