4. 创建 Quartz RMI 服务端
你务必按几个步骤来配置 Quartz 来使用 RMI。其中的一些步骤会在创建 Quartz RMI 服务端用到,还有些步骤会在 Quartz 客户端连接服务端。我们先来阐述服务端的配置步骤。
·配置 Quartz RMI 服务端
第一步就是修改要部署到 Quartz RMI 服务端的
quartz.properties 文件。当在 Quartz 中使用 RMI,你还必须添加几个新的属性。表 9.1 包括了完整 RMI 属性列表。
表 9.1. RMI 服务端必要的属性| 属性 | 默认值 |
org.quartz.scheduler.rmi.export
注:假如你要使 Quartz 调度作为一个可用的 RMI 对象,这个标记必须设置为 true | false |
org.quartz.scheduler.rmi.registryHost
注:这是运行 RMI 注册表所在的主机 | localhost |
org.quartz.scheduler.rmi.registryPort
注:这是 RMI 注册服务监听所用的端口号(通常是1099) | 1099 |
org.quartz.scheduler.rmi.createRegistry
注:这项决定了 Quartz 是否会创建 RMI 注册服务。如果你不希望 Quartz 创建注册服务就设置为 false 或 never。如果是希望 Quartz 首先尝试去使用已存在的注册服务,如果失败的话自行创建一个就设置为 true 或 as_needed。假如注册服务创建好了,它会使用给定的 registryPort 绑定到所给的 registryHost 上。 | never |
org.quartz.scheduler.rmi.serverPort
注:这是 Quartz 调度器服务所绑定的端口号,在其中监听到来的连接。默认,RMI 服务会随机选择一个端口号作为调度器绑定到 RMI 注册服务的端口。 | -1 |
| 表 9.1 中的所有属性都必须加到Quartz RMI 服务端所使用的 quartz.properties 文件中去。虽然这些属性都有默认值的,但最好还是显式的为它们指定值,以免产生混乱。代码 9.1 是一个 Quartz RMI 服务端所用的属性文件的样例。 |
代码 9.1. 用于 Quartz RMI 服务端的 quartz.properties 文件样例
- #==============================================================
- # Configure Main Scheduler Properties
- #==============================================================
- org.quartz.scheduler.instanceName = RMIScheduler
- #==============================================================
- # Configure RMI Properties
- #==============================================================
- org.quartz.scheduler.rmi.export = true
- org.quartz.scheduler.rmi.registryHost = localhost
- org.quartz.scheduler.rmi.registryPort = 1099
- org.quartz.scheduler.rmi.serverPort = 0
- org.quartz.scheduler.rmi.createRegistry = true
- #==============================================================
- # Configure ThreadPool
- #==============================================================
- org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
- org.quartz.threadPool.threadCount = 10
- org.quartz.threadPool.threadPriority = 5
- #==============================================================
- # Configure JobStore
- #==============================================================
- org.quartz.jobStore.misfireThreshold = 60000
- org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
你认得代码 9.1 的 quartz.properties 文件的大部分设置的,这些在前面章节中讲过。我们只是往期中加了表 9.1 所列的属性。
·创建 Quartz RMI 服务端启动类为启动 Quartz RMI 服务端,你必须创建一个启动类,该类从工厂中获取到调度器实例,然后运行这个调度器。即使是不用 RMI 也需要这一步。因为我们要在这个例子中运用 RMI,所以还有一些新的步骤要做。
首先,为清晰起见,我们把
quartz.properties 文件更名为
server.properties,这时候要告诉 Quartz RMI 服务端去加载新命名的文件而不是默认的
quartz.properties 文件。更改文件名会让我们调试问题变得容易些。这样,我们可以确保 Quartz 加载的是正确的设置文件。
第二个改变是:我们加载了一个新的安全管理器(
SecurityManager),以便能够赋予 RMI 服务端必须的权限。我们在本章的前面讨论过 RMI 安全管理器(
RMISecurityManager)。
除了这些改变,代码 9.2 中的启动类看起还是很亲切的
- package org.cavaness.quartzbook.chapter9;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.util.Date;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.quartz.Scheduler;
- import org.quartz.SchedulerFactory;
- import org.quartz.impl.StdSchedulerFactory;
-
- public class QuartzRMIServer {
-
- public void run() throws Exception {
- Log log = LogFactory.getLog(QuartzRMIServer.class);
-
-
- System.setProperty("org.quartz.properties",
- "server.properties");
-
-
- if (System.getSecurityManager() == null) {
- System.setSecurityManager(new
- java.rmi.RMISecurityManager());
- }
-
- Scheduler scheduler =
- StdSchedulerFactory.getDefaultScheduler();
-
-
-
-
-
- scheduler.start();
-
- log.info("Quartz RMI Server started at " + new Date());
- log.info("RMI Clients may now access it. ");
-
- System.out.println("\n");
- System.out.println(
- "The scheduler will run until you type \"exit\"");
-
- BufferedReader rdr = new BufferedReader(
- new InputStreamReader(System.in));
-
- while (true) {
- System.out.print("Type 'exit' to shutdown server: ");
- if ("exit".equals(rdr.readLine())) {
- break;
- }
- }
-
- log.info("Scheduler is shutting down...");
- scheduler.shutdown(true);
- log.info("Scheduler has been stopped.");
- }
- public static void main(String[] args) throws Exception {
-
- QuartzRMIServer example = new QuartzRMIServer();
- example.run();
- }
- }
在代码 9.2 中,安装了
RMISecurityManager 之后,通过工厂方法获得调度器实例,并调用它的
start() 方法。服务端是设计成在控制台运行的,因此一旦调度器启动之后,直至用户在控制台上键入
exit 。接着调度器被关闭也不再为远程的客户端提供服务了。
除了要使用
RMISecurityManager,我们注意到用不着在代码中做任何特别的事情,就能让 Quartz 调度器作为一个远程调度器来用。那些全是托
server.properties 文件的福所致。当调度器被创建后,假如属性文件告诉它这么做,调度器就会把自己导出并注册到 RMI 注册服务器上,并使之可被远程调用。
5. 使用 RMI 注册服务
需要运行一个 RMI 注册服务让客户端能访问到服务对象。你可以选择在命令行下使用 Java 的
rmiregistry 命令来运行注册服务,或者你可以允许 Quartz 自动启动注册服务。完全由你自己选择,但是,假如你没什么偏爱的话,让 Quartz 自已在需要的时候启动注册服务大概要简单些。
假如你要通过命令行启动注册服务,要确保你启动时所用的端口号要与属性文件所指定的一致。要从命令行启动,你应先进入到
<JAVA_HOME>/bin 目录下,然后键入如下命令:
rmiregistry <port>假如你不指定端口号,会使用默认的 1099。这个默认值与 Quartz 所用的默认端口是一样的。
假如你不想从命令行中运行注册服务,在你为属性
org.quartz.scheduler.rmi.createRegistry 设置了正确值的情况下,Quartz 会自动启动注册服务。看表 9.1,这个属性可取以下几个值:
·
false (never)
·
true (as_needed)
·
always如果你想要 Quartz 来启动注册服务,为这个属性设置
true 或者
always 即可。
[译者注] 在为“Registry”和“Registry Server” 用词选择上感觉不怎么贴切,如今都是用的“注册服务”与之对等,确也有译作注册表的,但总觉不妥,太容易与 Windows 系统注册表搞混。
[版权声明]本站内文章,如未标注 [转载],均系原创或翻译之作,本人 Unmi 保留一切权利。本站原创及译作未经本人许可,不得用于商业用途及传统媒体。网络媒体可随意转载,或以此为基础进行演译,但务必以链接形式注明原始出处和作者信息,否则属于侵权行为。另对本站转载他处文章,俱有说明,如有侵权请联系本人,本人将会在第一时间删除侵权文章。及此说明,重之之重。