JPPF,全称Java Parallel Processing Framework,即java并行处理框架,是一个开放源码的网格计算框架,它可以在一个分布执行环境中 同时运行多个java应用。
JPPF的突出特性
提供了负载平衡,
故障转移和错误恢复等服务。
提供一个基 于JMX的管理控制台,它既可以监视
节点也可以管理执行的任务。你可以远程取消和重启任务,或配置令其超时的截止日期或时间间隔。
想要运行JPPF并行计算任务,
需要至少一个Node节点(执行任务的节点),
一个driver节点(调度任务的节点),和本地调用节点
依次分别运行driver包里的startDriver.bat和
node包里的startNode.bat启动driver和node
然后开始写客户端:
/* * JPPF. * Copyright (C) 2005-2012 JPPF Team. * http://www.jppf.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jppf.application.template; import java.util.List; import org.jppf.client.*; import org.jppf.server.protocol.JPPFTask; /** * This is a template JPPF application runner. * It is fully commented and is designed to be used as a starting point * to write an application using JPPF. * @author Laurent Cohen */ public class TemplateApplicationRunner { /** * The JPPF client, handles all communications with the server. * It is recommended to only use one JPPF client per JVM, so it * should generally be created and used as a singleton. */ private static JPPFClient jppfClient = null; /** * The entry point for this application runner to be run from a Java command line. * @param args by default, we do not use the command line arguments, * however nothing prevents us from using them if need be. */ public static void main(final String...args) { try { // create the JPPFClient. This constructor call causes JPPF to read the configuration file // and connect with one or multiple JPPF drivers. jppfClient = new JPPFClient(); // create a runner instance. TemplateApplicationRunner runner = new TemplateApplicationRunner(); // Create a job JPPFJob job = runner.createJob(); // execute a blocking job runner.executeBlockingJob(job); // execute a non-blocking job //runner.executeNonBlockingJob(job); } catch(Exception e) { e.printStackTrace(); } finally { if (jppfClient != null) jppfClient.close(); } } /** * Create a JPPF job that can be submitted for execution. * @return an instance of the {@link org.jppf.client.JPPFJob JPPFJob} class. * @throws Exception if an error occurs while creating the job or adding tasks. */ public JPPFJob createJob() throws Exception { // create a JPPF job JPPFJob job = new JPPFJob(); // give this job a readable unique id that we can use to monitor and manage it. job.setName("Template Job Id"); // add a task to the job. job.addTask(new TemplateJPPFTask()); // add more tasks here ... // there is no guarantee on the order of execution of the tasks, // however the results are guaranteed to be returned in the same order as the tasks. return job; } /** * Execute a job in blocking mode. The application will be blocked until the job * execution is complete. * @param job the JPPF job to execute. * @throws Exception if an error occurs while executing the job. */ public void executeBlockingJob(final JPPFJob job) throws Exception { // set the job in blocking mode. job.setBlocking(true); // Submit the job and wait until the results are returned. // The results are returned as a list of JPPFTask instances, // in the same order as the one in which the tasks where initially added the job. List<JPPFTask> results = jppfClient.submit(job); // process the results processExecutionResults(results); } /** * Execute a job in non-blocking mode. The application has the responsibility * for handling the notification of job completion and collecting the results. * @param job the JPPF job to execute. * @throws Exception if an error occurs while executing the job. */ public void executeNonBlockingJob(final JPPFJob job) throws Exception { // set the job in non-blocking (or asynchronous) mode. job.setBlocking(false); // this call returns immediately. We will use the collector at a later time // to obtain the execution results asynchronously JPPFResultCollector collector = submitNonBlockingJob(job); // the non-blocking job execution is asynchronous, we can do anything else in the meantime System.out.println("Doing something while the job is executing ..."); // ... // We are now ready to get the results of the job execution. // We use JPPFResultCollector.waitForResults() for this. This method returns immediately with // the results if the job has completed, otherwise it waits until the job execution is complete. List<JPPFTask> results = collector.waitForResults(); // process the results processExecutionResults(results); } /** * Execute a job in non-blocking mode. The application has the responsibility * for handling the notification of job completion and collecting the results. * @param job the JPPF job to execute. * @return a JPPFResultCollector used to obtain the execution results at a later time. * @throws Exception if an error occurs while executing the job. */ public JPPFResultCollector submitNonBlockingJob(final JPPFJob job) throws Exception { // set the job in non-blocking (or asynchronous) mode. job.setBlocking(false); // We need to be notified of when the job execution has completed. // To this effect, we define an instance of the TaskResultListener interface, // which we will register with the job. // Here, we use an instance of JPPFResultCollector, conveniently provided by the JPPF API. // JPPFResultCollector implements TaskResultListener and has a constructor that takes // the number of tasks in the job as a parameter. JPPFResultCollector collector = new JPPFResultCollector(job); job.setResultListener(collector); // Submit the job. This call returns immediately without waiting for the execution of // the job to complete. As a consequence, the object returned for a non-blocking job is // always null. Note that we are calling the exact same method as in the blocking case. jppfClient.submit(job); // finally return the result collector, so it can be used to collect the exeuction results // at a time of our chosing. The collector can also be obtained at any time by calling // (JPPFResultCollector) job.getResultListener() return collector; } /** * Process the execution results of each submitted task. * @param results the tasks results after execution on the grid. */ public void processExecutionResults(final List<JPPFTask> results) { // process the results for (JPPFTask task: results) { // if the task execution resulted in an exception if (task.getException() != null) { // process the exception here ... } else { // process the result here ... } } } }
一个并行计算的任务,就是一个JPPFJob,每个job含有多个task,task之间是并行执行的,如果有多个nod节点,会按照其负载均衡策略分配到多个node上执行。通过client提交(submit)job后,会返回执行结果,为一个JPPFTask列表,列表里包含你add到job中每个task及其运行结果,作为后续计算处理之用。任务调用支持阻塞和非阻塞。