使用Hazelcast调度Spring tasks

栏目: Java · 发布时间: 5年前

内容简介:在我工作的公司,我们使用无论如何,有时在超高峰期间,Quartz表会遇到数据库锁定问题。所以我在想什么是Quartz替代品。以下项目前景看好:但是,让我们尝试一些轻松简单的方法,如何使用

在我工作的公司,我们使用 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的一种方式。

演示

让我们有两个微服务在工作后每两秒启动一次:

<b>private</b> <b>void</b> doJob(<b>final</b> String microServiceName)抛出InterruptedException { 
        System.out.println(microServiceName +“in critical section ...”); 
        <b>for</b>(<b>int</b> i = 0; i <4; i ++){ 
            Thread.sleep(1000); 
            System.out.println(“在做什么”+ microServiceName); 
        } 
    }

用ILock演示

如上所述,我们希望确保只有线程处于关键部分:(ILock解决方案)

<b>public</b> <b>void</b> performJobWithLock(<b>final</b> String microServiceName) {
        <b>final</b> ILock lock = hazelcastConfiguration.getJobLock();
        <b>if</b> (lock.tryLock()) {
            <b>try</b> {
                doJob(microServiceName);
            } <b>catch</b> (InterruptedException e) {
                e.printStackTrace();
            } <b>finally</b> {
                lock.unlock();
            }
        }
    }

@Scheduled(fixedRate = 2000)
    <b>public</b> <b>void</b> performJob() {
        jobServices.performJobWithLock(<font>"service1"</font><font>);
    }   
</font>

请注意,在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是从另一个线程异步释放的:

<b>public</b> <b>void</b> performJobWithSemaphore(<b>final</b> String microServiceName) {
        <b>final</b> ISemaphore semaphore = hazelcastConfiguration.getJobSemaphore();
        <b>try</b> {
            semaphore.acquire();
            Thread thread = <b>new</b> Thread() {
                <b>public</b> <b>void</b> run() {
                    <b>try</b> {
                        <b>try</b> {
                            doJob(microServiceName);
                        } <b>catch</b> (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } <b>finally</b> {
                        semaphore.release();
                        System.out.println(<font>"Thread released semaphore..."</font><font>+microServiceName);
                    }
                }
            };
            thread.start();
        } <b>catch</b> (InterruptedException e) {
            e.printStackTrace();
        }
    }
</font>

不要忘记将ISemaphore permits 的数量设置为1.我们希望ISemaphore表现为ILock,但我们需要能够从另一个线程中释放临界区。

@Bean
    <b>public</b> ISemaphore getJobSemaphore() {
        ISemaphore semaphore = hazelcastInstance().getSemaphore(<font>"criticalJobSemaphore"</font><font>);
        semaphore.init(1);
        <b>return</b> semaphore;
    }
</font>

测试

以与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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通Git(第2版)

精通Git(第2版)

Scott Chacon、Ben Straub / 门佳、刘梓懿 / 人民邮电出版社 / 2017-9 / 89.00元

Git 仅用了几年时间就一跃成为了几乎一统商业及开源领域的版本控制系统。本书全面介绍Git 进行版本管理的基础和进阶知识。全书共10 章,内容由浅入深,展现了普通程序员和项目经理如何有效利用Git提高工作效率,掌握分支概念,灵活地将Git 用于服务器和分布式工作流,如何将开发项目迁移到Git,以及如何高效利用GitHub。一起来看看 《精通Git(第2版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具