Spring の組み込み分散ロックを使用したことがありますか?

Spring の組み込み分散ロックを使用したことがありますか?

環境: SpringBoot2.7.12

この記事では、Spring Integrationが提供する分散ロック機能について紹介します。

1. はじめに

Spring Integration は、イベント駆動型アプリケーションを構築するためのフレームワークです。 Spring Integration では、LockRegistry は分散ロックを管理するためのインターフェースです。分散ロックは、分散システム内の複数のノード間で共有リソースへの相互排他的アクセスを保証するために使用される同期メカニズムです。

LockRegistry と関連サブインターフェース (RenewableLockRegistry など) の主な機能は次のとおりです。

  • ロックの取得: アプリケーションが共有リソースにアクセスする必要がある場合、LockRegistry を通じてロックを取得できます。
  • ロックを解除する: アプリケーションが共有リソースへのアクセスを完了したら、他のアプリケーションがロックを取得できるようにロックを解除する必要があります (最初のポイントで述べたように、直接的なロック解除操作は提供されていませんが、内部で自動的に実行されます)。
  • 更新: 必要に応じてロック保持時間を延長するための更新メカニズムを提供します。

一般的な LockRegistry 実装には、データベース、ZooKeeper、Redis に基づくものが含まれます。

パブリック依存関係

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

2. データベースベースの分散ロック

依存関係の導入

<dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-jdbc</artifactId> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency>

構成

spring: datasource: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/spring_lock?serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&useSSL=false username: root password: xxxooo type: com.zaxxer.hikari.HikariDataSource hikari: minimumIdle: 10 maximumPoolSize: 200 --- spring: integration: jdbc: initialize-schema: always # 基于数据库需要执行初始化脚本schema: classpath:schema-mysql.sql

コアBeanオブジェクトの登録

@Bean public DefaultLockRepository defaultLockRepository(DataSource dataSource) { DefaultLockRepository lockRepository = new DefaultLockRepository(dataSource); // 这里根据你的业务需要,配置表前缀,默认:IN_ lockRepository.setPrefix("T_") ; return lockRepository ; } // 注册基于数据库的分布式锁@Bean public JdbcLockRegistry jdbcLockRegistry(DefaultLockRepository lockRepository) { return new JdbcLockRegistry(lockRepository) ; }

テストケース

@Test public void testLock() throws Exception int len = 10 ; CountDownLatch cdl = new CountDownLatch(len) ; CountDownLatch waiter = new CountDownLatch(len) ; Thread[] ts = new Thread[len] ; for (int i = 0; i < len; i++) { ts[i] = new Thread(() -> { waiter.countDown() ; System.out.println(Thread.currentThread().getName() + " - 准备获取锁") ; try { waiter.await() ; } catch (InterruptedException e1) { e1.printStackTrace(); } // 获取锁Lock lock = registry.obtain("drug_store_key_001") ; lock.lock() ; System.out.println(Thread.currentThread().getName() + " - 获取锁成功") ; try { try { TimeUnit.SECONDS.sleep(2) ; } catch (InterruptedException e) { e.printStackTrace(); } } finally { // 释放锁lock.unlock() ; cdl.countDown() ; System.out.println(Thread.currentThread().getName() + " - 锁释放成功") ; } }, "T - " + i) ; } for (int i = 0; i < len; i++) { ts[i].start() ; } cdl.await() ; }

データベース

写真

ロック実装 JdbcLock は java.util.concurrent.locks.Lock を実装するため、ロックは再入などの操作をサポートします。

ロック取得に失敗した後の再試行間隔を設定します。デフォルト値は100msです。

 JdbcLockRegistry jdbcLockRegistry = new JdbcLockRegistry(lockRepository); // 定义锁对象时设置当获取锁失败后重试间隔时间。 jdbcLockRegistry.setIdleBetweenTries(Duration.ofMillis(200)) ;

ロックの更新

jdbcLockRegistry.renewLock("drug_store_key_001");

3. Redisベースの分散ロック

依存関係の導入

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

構成

spring: redis: host: localhost port: 6379 password: xxxooo database: 8 lettuce: pool: maxActive: 8 maxIdle: 100 minIdle: 10 maxWait: -1

テストケース

テスト コードは上記の JDBC ベースのものと同じです。ロックを呼び出すコードを変更するだけで済みます。

 Lock lock = redisLockRegistry.obtain("001") ;

ロックの有効期間を設定します。デフォルトは60秒です。

 // 第三个参数设置了key的有效期,这里改成10s RedisLockRegistry redisLockRegistry = new RedisLockRegistry(connectionFactory, registryKey, 10000) ;

注: Redis キーの有効期間は 10 秒に設定されています。ビジネスの実行が 10 秒を超えると、プログラムはエラーを報告します。 Redis ウォッチドッグ メカニズムはありません。

 Exception in thread "T - 0" java.lang.IllegalStateException: Lock was released in the store due to expiration. The integrity of data protected by this lock may have been compromised. at org.springframework.integration.redis.util.RedisLockRegistry$RedisLock.unlock(RedisLockRegistry.java:450) at com.pack.SpringIntegrationDemoApplicationTests.lambda$1(SpringIntegrationDemoApplicationTests.java:83) at java.lang.Thread.run(Thread.java:748)

10 秒経過後にキーが自動的に削除される場合、他のスレッドはすぐにロックを取得できますか?単一ノードの場合、他のスレッドはロックを取得できず、前のスレッドが終了するまで待機する必要があります。これは、ReentrantLock ロックが内部的に維持され、分散ロックを取得する前にローカル ロックを取得する必要があるためです。

 private abstract class RedisLock implements Lock { private final ReentrantLock localLock = new ReentrantLock(); public final void lock() { this.localLock.lock(); while (true) { try { if (tryRedisLock(-1L)) { return; } } catch (InterruptedException e) { } catch (Exception e) { this.localLock.unlock(); rethrowAsLockException(e); } } } }

注: データベースベースでもRedisベースでも、まずローカルロックを取得する必要があります。

Spring Cloud Task は、Spring Integration のデータベースベースのロックを使用します。

概要: Spring Integration の分散ロックは、分散システムで信頼性の高い同期を実現する効果的な方法を開発者に提供します。これらのロック実装を適切に選択して使用することで、共有リソースへのアクセスが複数のノード間で調整され、一貫性が保たれ、システム全体の信頼性とパフォーマンスが向上します。

完了! ! !

<<:  分散技術:原理から応用まで、分散技術の魅力と未来を総合的に分析 - 分散計測指標

>>:  分散相互排除方式は分散技術に不可欠である

推薦する

Google ランキング アルゴリズムの調整: 広告が多すぎるとランキングに影響します

2月7日、Googleのアルゴリズムが新たな調整を受けたというニュースが届きました。その主な内容は、...

Mituo 1元体験サイト構築が正式に開始

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますユーザーエ...

crazydomains は、ドメイン名を超低価格で提供し続けています。.com1 ポンドなど。

crazydomains.com.au がドメイン名のプロモーションを再開しました。最も魅力的なもの...

ウェブサイトの最適化中にウェブサイトのランキングをより効果的に向上させる方法

SEO 最適化担当者の心の中では、最適化されていない Web サイトは、どれほど美しくてもゴミです。...

インターネット業界が発展するにつれて、SEO に終止符を打つのは誰でしょうか?

呉暁波氏はこう言っています。「企業がユーザーに見つけてもらいたいなら、インターネット検索に頼らざるを...

個人ウェブマスターの成功体験: 市場を効果的にセグメント化する方法

ウェブマスター、より正確に言えば草の根ウェブマスターとして、彼の背後には優秀なチームも、強力な財政支...

清華紫光クラウド:チップとクラウドの統合を基盤に、中国の産業インターネットの発展を推進

時代は思想の母であり、実践は理論の源である。 40年前、改革開放の壮大な幕が開き、中国は近代化の新た...

Baidu でウェブサイトを復元した私の体験

多くのウェブマスターのトラフィックの大部分は検索エンジンから来ていると思います。もちろん、一部のウェ...

百度、3B事件に初めて反応:競争を歓迎し、悪質な侵害に反対

南方都市報記者謝睿、高玲雲、研修生欧景紅 百度と奇虎360の戦いが本格化した。1日後、双方は一時的に...

Hostsolutions: 超大容量ハードディスク VPS 再入荷、14.6/半年、苦情防止/無制限コンテンツ

hostsolutionsは、新しいコンピュータルームを開設したことを正式に発表しました。ボスは比較...

マルチクラウドコンピューティングには慎重なITコスト配分が必要

マルチクラウド環境は企業にとって多くのメリットをもたらしますが、適切な管理がなければコストの配分が難...

tmthosting: シアトルの高セキュリティ VPS、年間 29 ドル、Windows システム、IPv6 サポート

tmthosting のシアトル VPS が 55% オフで販売されています。データ センターは米国...

クラウド コンピューティングにおける財務ガバナンスの重要性

[[343310]]今日、企業はますますデータ主導型になりつつあります。なぜなら、データは新製品の開...

NIKE の新年の大ヒット商品が到着しました。今回は旧正月も負けません!

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービス今年はまだ始まったばかり...

「ゼロからウェブサイトを構築し、90日間でBaiduキーワードのトップ5に入る」コースが始まりました

月収10万元の起業の夢を実現するミニプログラム起業支援プランコース名:ゼロからウェブサイトを構築し、...