ejb3中的@Schedule中的persistent属性的深入探索

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 标题:ejb3中的@Schedule中的persistent属性的深入探索 1 实验环境:     应用服务器:glassfish4.0     数据库服务器: MYSQL Target Server Version : 50614     开发工具: netbeans8.0 2 我思考的问题:当我开发好了一个@Schedule定时任务之后,我开始思考这样一种场景,如果我的应用服务器(glassfish4)是集群,那么我的定时任务会怎么执行,因为在你发布一个项目到glassfish集群中,每一台jvm中都会运行相同的程序。

标题:ejb3中的@Schedule中的persistent属性的深入探索

1 实验环境:

    应用服务器:glassfish4.0

    数据库服务器: MYSQL Target Server Version : 50614

    开发工具: netbeans8.0

2 我思考的问题:当我开发好了一个@Schedule定时任务之后,我开始思考这样一种场景,如果我的应用服务器(glassfish4)是集群,那么我的定时任务会怎么执行,因为在你发布一个项目到glassfish集群中,每一台jvm中都会运行相同的程序。那定时器也必然存在多份。那么我的定时器组件会在同一时间点执行多次吗(执行在多个jvm中)?

如果不会,是什么机制控制定时器的统一性,如果会,那么我们又改怎么解决呢?

3 在编写一个定时器任务时,代码如下:

 @Schedule(second = "*/5", minute = "*", hour = "*", persistent = true,info = "我是定时器")
    public void doWork() {
	System.out.println("timer: " + System.currentTimeMillis());
 }
(1 ) persistent  值官方给出的说明是 Specifies whether the timer that is created is persistent.指定在创建该定时器是否需要持久化.

(2 )时间格式的参数你可以参考的别的文章,我本文中主要介绍persistent这个值的情况,该值的默认值是true,也就说定时器的数据信息室会保存到数据库去的,那么他保存到那个数据去了呢? 其实如果你设置了persistent等于true或者不设置,定时器的数据信息都会保存到内存数据库中。

对应的物理路径如下:D:\AppServer\my-glassfish4\glassfish\domains\domain1\lib\databases 你可以尝试删除该文件夹的内容试一试,看看变动后的效果。

4 那么既然是可以保存到数据库,那么是否也可以保存到mysql数据库呢。而不是内存数据库呢,答案是可以的。

 在mysql中配置GlassFish中使用EJBTimer,需要有一个独立的数据源,和数据表EJB__TIMER__TBL,建表语句可在[glassfish安装目录]\glassfish\lib\install\databases中找到。对于developer模式,GlassFish默认使用内置的__TimerPool,不需要你手工创建datasource和表;对于cluster模式,Admin Server会默认使用__TimerPool,Cluster则需要单独配置。如果让Admin Server和Cluster同时使用手工创建的datasource,则可能导致Cluster配置中的timer datasource在server重启后丢失,TimerService会出现异常,这应该是GlassFish的BUG,目前的解决方案就是Admin Server用默认的Timer配置,Cluster用另外的配置。

建表语句如下:

CREATE TABLE EJB__TIMER__TBL (
    `CREATIONTIMERAW`      BIGINT        NOT NULL,
    `BLOB`                 BLOB,
    `TIMERID`              VARCHAR(255)  NOT NULL,
    `CONTAINERID`          BIGINT        NOT NULL,
    `OWNERID`              VARCHAR(255)  NULL,
    `STATE`                INTEGER       NOT NULL,
    `PKHASHCODE`           INTEGER       NOT NULL,
    `INTERVALDURATION`     BIGINT        NOT NULL,
    `INITIALEXPIRATIONRAW` BIGINT        NOT NULL,
    `LASTEXPIRATIONRAW`    BIGINT        NOT NULL,
    `SCHEDULE`             VARCHAR(255)  NULL,
    `APPLICATIONID`        BIGINT        NOT NULL,
    CONSTRAINT `PK_EJB__TIMER__TBL` PRIMARY KEY (`TIMERID`) 
);

把该ejbtimer_mysql.sql放到数据中执行,然后配置一个数据库连接池,我这里就直接修改默认的数据连接池__TimerPool

<jdbc-resource pool-name="__TimerPool" jndi-name="jdbc/__TimerPool" object-type="system-admin"></jdbc-resource>
    <jdbc-resource pool-name="DerbyPool" jndi-name="jdbc/__default" object-type="system-all"></jdbc-resource>
    <jdbc-connection-pool max-pool-size="100" 
	datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" 
	res-type="javax.sql.XADataSource" 
	steady-pool-size="32" name="__TimerPool">
      <property name="password" value="Passw0rd"></property>
      <property name="user" value="root"></property>
      <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=GBK"></property>
      <property name="URL" value="jdbc:mysql://localhost:3306/test?characterEncoding=GBK"></property>
      <property name="Password" value="Passw0rd"></property>
      <property name="User" value="root"></property>
    </jdbc-connection-pool>

建表语句是在test库中执行的,这样配置之后你的ejb定时器使用的就是你自定义的数据库了。然后重新启动glassfish服务器,并把你定时器任务程序发布到glassfish上去。若果发布中提示EJB__TIMER__TBL表找不到,那你应该是忘记执行建表sql了。好了当我定时应用程序启动后:

这是我的代码程序:

/**
 * 测试定时器的持久化状态
 * @author 845885222@qq.com
 */
@Singleton
public class NewSessionBean {

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = true, info = "我是定时器")
    public void doWork() {
	System.out.println("timer: " + System.currentTimeMillis());
    }

    @Schedule(second = "*/6", minute = "*", hour = "*", persistent = true, info = "doWork2")
    public void doWork2() {
	System.out.println("doWork2: " + System.currentTimeMillis());
    }
}
控制台输出结果如下:

信息:   Redirecting to /common/index.jsf
信息:   Admin Console: Initializing Session Attributes...
信息:   timer: 1433846450001
信息:   doWork2: 1433846454001

观察我mysql数据test下的EJB__TIMER__TBL,结果如下


以后集群就不在担心定时器不同步的问题了。







相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
监控 Java 调度
Spring中的任务调度:探索@Scheduled和@Schedules注解的威力
Spring中的任务调度:探索@Scheduled和@Schedules注解的威力
106 0
|
Java
java使用Quartz任务调用crontab表达式的时候报错:Based on configured schedule, the given trigger will never fire
java使用Quartz任务调用crontab表达式的时候报错:Based on configured schedule, the given trigger will never fire
477 0
java使用Quartz任务调用crontab表达式的时候报错:Based on configured schedule, the given trigger will never fire
|
运维 资源调度 Kubernetes
Kubernetes Scheduler Framework 扩展: 1. Coscheduling
# 前言 ## 为什么Kubernetes需要Coscheduling功能? Kubernetes目前已经广泛的应用于在线服务编排,为了提升集群的的利用率和运行效率,我们希望将Kubernetes作为一个统一的管理平台来管理在线服务和离线作业。但是默认的调度器是以Pod为调度单元进行依次调度,不会考虑Pod之间的相互关系。但是很多数据计算类的作业具有All-or-Nothing特点,要求所有的
3053 0
|
4月前
|
Java Spring
如何通过配置文件给 @Scheduled(fixedRate= )传值
【4月更文挑战第18天】如何通过配置文件给 @Scheduled(fixedRate= )传值
307 3
|
28天前
|
Kubernetes API 调度
在k8S中,Scheduler作用及实现原理是什么?
在k8S中,Scheduler作用及实现原理是什么?
|
负载均衡 关系型数据库 MySQL
multiple-executor 模式部署 | 学习笔记
快速学习 multiple-executor 模式部署
multiple-executor 模式部署 | 学习笔记
|
前端开发 数据库 容器
AngularJS自定义服务(factory、service、provider)
AngularJS自定义服务(factory、service、provider)
|
Java 调度 Spring
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(上)
|
Java 调度 Spring
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)
【小家Spring】Spring任务调度核心接口(类)之---TaskScheduler(任务调度器)、Trigger(触发器)、ScheduledTask(调度任务)详解(下)
SAP Spartacus 定义在app.module.ts里的providers依赖注入元数据何时得到处理
我基于 SAP Spartacus library创建了一个自定义的Storefront实现。在其app.module.ts里,我采用自定义的MyCurrentProductService,去替换 SAP Spartacus 标准的CurrentProductService 实现:
SAP Spartacus 定义在app.module.ts里的providers依赖注入元数据何时得到处理