使用Hazelcast排程Spring tasks
在我工作的公司,我們使用Quartz進行作業排程。大部分時間Quartz都在為我們提供所需的一切:
- 透過cron表示式進行排程。
- 監控和啟動已啟動的工作......
無論如何,有時在超高峰期間,Quartz表會遇到資料庫鎖定問題。所以我在想什麼是Quartz替代品。以下專案前景看好:
- Cron4J
- Apache Ignite(哦,是的!)
但是,讓我們嘗試一些輕鬆簡單的方法,如何使用Spring Scheduling實現任務啟動,以及使用Hazelcast資料網格實現叢集編排?
Spring Scheduling和Hazelcast一起執行
任務目標:假設我想在兩個微服務上每2秒啟動一次特定任務,我想確保群集中始終只有一個任務在執行!
這是Hazelcast派上用場的時刻。我們將為它測試兩種Hazelcast解決方案:
- ILock - Hazelcast分散式鎖,用於訪問關鍵部分。只允許一個執行緒位於關鍵部分。
- ISemaphore - 用於關鍵部分編排的叢集範圍計數訊號量。允許多個執行緒位於關鍵部分。取決於設定。
在ILock和ISemaphore這兩個分散式物件之間的重要區別在於ILock需要由請求鎖定的同一執行緒釋放。另一方面,ISemaphore可以透過完全另一個執行緒釋放。
- ISemaphore - 如果你想非同步解鎖關鍵部分,那麼ISemaphore就是你的方式。
- ILock - 訪問需要同步應答的一些共享資源是ILock的一種方式。
演示
讓我們有兩個微服務在工作後每兩秒啟動一次:
private void doJob(final String microServiceName)丟擲InterruptedException { System.out.println(microServiceName +“in critical section ...”); for(int i = 0; i <4; i ++){ Thread.sleep(1000); System.out.println(“在做什麼”+ microServiceName); } } |
用ILock演示
如上所述,我們希望確保只有執行緒處於關鍵部分:(ILock解決方案)
public void performJobWithLock(final String microServiceName) { final ILock lock = hazelcastConfiguration.getJobLock(); if (lock.tryLock()) { try { doJob(microServiceName); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } @Scheduled(fixedRate = 2000) public void performJob() { jobServices.performJobWithLock("service1"); } |
請注意,在try / finally塊之前獲取鎖定(tryLock方法)。我使用的tryLock方法在獲取鎖定方面更安全,因為跳過了try / finally塊。但是當使用ILock.lock()方法時,您需要知道未授予鎖定的可能性,然後ILock.unlock()方法引發IllegalStateException。
測試
- 開啟兩個終端視窗。
- git clone https://bitbucket.org/tomask79/spring-integration-hazelcast.git
- 在pom.xml的頂級目錄中執行“mvn clean install”
- 第一個終端中的java -jar spring-microservice-service1 / target / service1-0.0.1-SNAPSHOT.war。
- java -jar spring-microservice-service2 / target / service2-0.0.1-SNAPSHOT.war在第二個終端。
- 在你啟動兩個微服務之後,輸出將出現在兩個視窗中,但絕不會同時出現!
第一個終端:
service1 in critical section... Doing something in service1 Doing something in service1 Doing something in service1 Doing something in service1 |
第二個終端:
service2 in critical section... Doing something in service2 Doing something in service2 Doing something in service2 Doing something in service2 |
使用ISemaphore進行演示
與ILock相同,但這次ISemaphore是從另一個執行緒非同步釋放的:
public void performJobWithSemaphore(final String microServiceName) { final ISemaphore semaphore = hazelcastConfiguration.getJobSemaphore(); try { semaphore.acquire(); Thread thread = new Thread() { public void run() { try { try { doJob(microServiceName); } catch (InterruptedException e) { e.printStackTrace(); } } finally { semaphore.release(); System.out.println("Thread released semaphore..."+microServiceName); } } }; thread.start(); } catch (InterruptedException e) { e.printStackTrace(); } } |
不要忘記將ISemaphore permits 的數量設定為1.我們希望ISemaphore表現為ILock,但我們需要能夠從另一個執行緒中釋放臨界區。
@Bean public ISemaphore getJobSemaphore() { ISemaphore semaphore = hazelcastInstance().getSemaphore("criticalJobSemaphore"); semaphore.init(1); return semaphore; } |
測試
以與ILock相同的方式啟動兩個微服務。以下輸出將在兩個終端視窗中顯示,但同樣,永遠不會同時出現!
第一個終端
Doing something in service1 Doing something in service1 Doing something in service1 Doing something in service1 Thread released semaphore...service1 |
第二終端
Doing something in service2 Doing something in service2 Doing something in service2 Doing something in service2 Thread released semaphore...service2 |
相關文章
- Spring中Quartz排程器的使用Springquartz
- 使用HazelCast實現Spring Config Server配置ASTSpringServer
- Spring Boot 參考指南(Hazelcast)Spring BootAST
- Spring 指南(排程任務)Spring
- Hazelcast JET在Spring Boot上執行ASTSpring Boot
- 使用Spring Boot排程WebSocket推送的教程和原始碼 - BaeldungSpring BootWeb原始碼
- Flink排程之排程器、排程策略、排程模式模式
- 使用Spring Integration和Hazelcast進行叢集領導者選舉SpringAST
- 使用Hazelcast作為Spring資料儲存庫的開源案例ASTSpring
- 在Spring中使用JDK定時器實現排程任務SpringJDK定時器
- Spring排程定時任務的方式Spring
- 在Kubernetes上使用Spring Boot實現Hazelcast分散式快取 – PiotrSpring BootAST分散式快取
- Linux核心排程分析(程式排程)Linux
- Spring Boot應用中進行任務排程Spring Boot
- Spring使用Quartz定時排程Job無法Autowired注入Service的解決方案Springquartz
- Spark中資源排程和任務排程Spark
- 結合Hazelcast和Spring的分散式快取 - reflectoringASTSpring分散式快取
- Celery非同步排程框架(一)基本使用非同步框架
- oracle使用DBMS_SCHEDULER排程作業Oracle
- 配置hadoop 使用fair scheduler排程器HadoopAI
- Go語言排程器之主動排程(20)Go
- Go排程器系列(3)圖解排程原理Go圖解
- 使用Kafka分割槽擴充套件Spring Batch大資料排程批處理 – ArnoldKafka套件SpringBAT大資料
- Tasks in parallelParallel
- 排程器簡介,以及Linux的排程策略Linux
- Go排程器系列(2)巨集觀看排程器Go
- Go語言排程器之排程main goroutine(14)GoAI
- 【Spark篇】---Spark資源排程和任務排程Spark
- Pod的排程是由排程器(kube-scheduler)
- Go runtime 排程器精講(五):排程策略Go
- 使用Java實現定時任務排程Java
- Java後端開發中的任務排程:使用Spring Batch實現批處理Java後端SpringBAT
- Spring Boot Quartz 分散式叢集任務排程實現Spring Bootquartz分散式
- 任務排程
- 資料排程
- spark排程管理Spark
- async-await:協作排程 vs 搶佔排程AI
- k8s排程器介紹(排程框架版本)K8S框架