CompletionException-0

问题描述:在win7下使用cygwin启动hadoop,但是报 null\bin\winutils.exe in the Hadoop binaries. 大家好,给大家分享一下一个有趣的事情,很多人还不知道这一点。下面详细解释一下。现在让我们来看看!

数据库mysql创建表格老是出错,看不懂英文提示?

CompletionException-0的相关图片

win7下调试Hadoop2.2.0程序的方法:。

一、环境准备

1 eclipse Juno Service Release 4.2的本 。

2 操作系统 Windows7 。

3 hadoop的eclipse插件 hadoop-eclipse-plugin-2.2.0.jar 。

4 hadoop的集群环境 虚拟机Linux的Centos6.5单机伪分布式 。

5 调试程序 Hellow World 。

二、注意事项:

异常如下:

java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries. 。

解决办法:

在org.apache.hadoop.util.Shell类的checkHadoopHome()方法的返回值里写固定的 。

本机hadoop的路径,在这里更改如下:

private static String checkHadoopHome() {。

// first check the Dflag hadoop.home.dir with JVM scope。

//System.setProperty("hadoop.home.dir", "...");。

String home = System.getProperty("hadoop.home.dir");。

// fall back to the system/user-global env variable。

if (home == null) {。

home = System.getenv("HADOOP_HOME");。

try {

// couldn't find either setting for hadoop's home directory。

if (home == null) {。

throw new IOException("HADOOP_HOME or hadoop.home.dir are not set.");。

if (home.startsWith("\"") && home.endsWith("\"")) {。

home = home.substring(1, home.length()-1);。

// check that the home setting is actually a directory that exists。

File homedir = new File(home);。

if (!homedir.isAbsolute() || !homedir.exists() || !homedir.isDirectory()) {。

throw new IOException("Hadoop home directory " + homedir。

+ " does not exist, is not a directory, or is not an absolute path.");。

home = homedir.getCanonicalPath();。

} catch (IOException ioe) {。

if (LOG.isDebugEnabled()) {。

LOG.debug("Failed to detect a valid hadoop home directory", ioe);。

home = null;

//固定本机的hadoop地址。

home="D:\\hadoop-2.2.0";。

return home;

第二个异常,Could not locate executable D:\Hadoop\tar\hadoop-2.2.0\hadoop-2.2.0\bin\winutils.exe in the Hadoop binaries. 找不到win上的执行程序,可以去https://github.com/srccodes/hadoop-common-2.2.0-bin下载bin包,覆盖本机的hadoop跟目录下的bin包即可 。

第三个异常:

Exception in thread "main" java.lang.IllegalArgumentException: Wrong FS: hdfs://192.168.130.54:19000/user/hmail/output/part-00000, expected: file:/// 。

at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:310) 。

at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:47) 。

at org.apache.hadoop.fs.RawLocalFileSystem.getFileStatus(RawLocalFileSystem.java:357) 。

at org.apache.hadoop.fs.FilterFileSystem.getFileStatus(FilterFileSystem.java:245) 。

at org.apache.hadoop.fs.ChecksumFileSystem$ChecksumFSInputChecker.<init>(ChecksumFileSystem.java:125) 。

at org.apache.hadoop.fs.ChecksumFileSystem.open(ChecksumFileSystem.java:283) 。

at org.apache.hadoop.fs.FileSystem.open(FileSystem.java:356) 。

at com.netease.hadoop.HDFSCatWithAPI.main(HDFSCatWithAPI.java:23) 。

出现这个异常,一般是HDFS的路径写的有问题,解决办法,拷贝集群上的core-site.xml和hdfs-site.xml文件,放在eclipse的src根目录下即可。

package com.qin.wordcount;。

import java.io.IOException;。

import org.apache.hadoop.fs.FileSystem;。

import org.apache.hadoop.fs.Path;。

import org.apache.hadoop.io.IntWritable;。

import org.apache.hadoop.io.LongWritable;。

import org.apache.hadoop.io.Text;。

import org.apache.hadoop.mapred.JobConf;。

import org.apache.hadoop.mapreduce.Job;。

import org.apache.hadoop.mapreduce.Mapper;。

import org.apache.hadoop.mapreduce.Reducer;。

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;。

import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;。

import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;。

import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;。

/***

*

* Hadoop2.2.0测试。

* 放WordCount的例子。

*

* @author qindongliang。

*

* hadoop技术交流群: 376932160。

*

*

* */

public class MyWordCount {。

/**

* Mapper

*

* **/

private static class WMapper extends Mapper<LongWritable, Text, Text, IntWritable>{。

private IntWritable count=new IntWritable(1);。

private Text text=new Text();。

@Override

protected void map(LongWritable key, Text value,Context context)。

throws IOException, InterruptedException {。

String values[]=value.toString().split("#");。

//System.out.println(values[0]+"========"+values[1]);。

count.set(Integer.parseInt(values[1]));。

text.set(values[0]);。

context.write(text,count);。

/**

* Reducer

*

* **/

private static class WReducer extends Reducer<Text, IntWritable, Text, Text>{。

private Text t=new Text();。

@Override

protected void reduce(Text key, Iterable<IntWritable> value,Context context)。

throws IOException, InterruptedException {。

int count=0;

for(IntWritable i:value){。

count+=i.get();。

t.set(count+"");。

context.write(key,t);。

/**

* 改动一

* (1)shell源码里添加checkHadoopHome的路径。

* (2)974行,FileUtils里面。

* **/

public static void main(String[] args) throws Exception{。

// String path1=System.getenv("HADOOP_HOME");。

// System.out.println(path1);。

// System.exit(0);。

JobConf conf=new JobConf(MyWordCount.class);。

//Configuration conf=new Configuration();。

//conf.set("mapred.job.tracker","192.168.75.130:9001");。

//读取person中的数据字段。

// conf.setJar("tt.jar");。

//注意这行代码放在最前面,进行初始化,否则会报。

/**Job任务**/

Job job=new Job(conf, "testwordcount");。

job.setJarByClass(MyWordCount.class);。

System.out.println("模式: "+conf.get("mapred.job.tracker"));;。

// job.setCombinerClass(PCombine.class);。

// job.setNumReduceTasks(3);//设置为3。

job.setMapperClass(WMapper.class);。

job.setReducerClass(WReducer.class);。

job.setInputFormatClass(TextInputFormat.class);。

job.setOutputFormatClass(TextOutputFormat.class);。

job.setMapOutputKeyClass(Text.class);。

job.setMapOutputValueClass(IntWritable.class);。

job.setOutputKeyClass(Text.class);。

job.setOutputValueClass(Text.class);。

String path="hdfs://192.168.46.28:9000/qin/output";。

FileSystem fs=FileSystem.get(conf);。

Path p=new Path(path);。

if(fs.exists(p)){。

fs.delete(p, true);。

System.out.println("输出路径存在,已删除!");。

FileInputFormat.setInputPaths(job, "hdfs://192.168.46.28:9000/qin/input");。

FileOutputFormat.setOutputPath(job,p );。

System.exit(job.waitForCompletion(true) ? 0 : 1); 。

如何解决map /reduce程序执行时卡住现象的相关图片

如何解决map /reduce程序执行时卡住现象

来自:51CTO(作者:superZS)

我在刚开始学习数据库的时候,没少走弯路。经常会遇到各种稀奇古怪的 error 信息,遇到报错会很慌张,急需一个解决问题的办法。跟无头苍蝇一样,会不加思索地把错误粘到百度上,希望赶紧查找一下有没有好的处理问题的方法。我想这个应该是刚从事数据库的小白,都会遇到窘境。

今天就给大家列举 MySQL 数据库中,最经典的十大错误案例,并附有处理问题的解决思路和方法,希望能给刚入行,或数据库爱好者一些帮助,今后再遇到任何报错,我们都可以很淡定地去处理。

学习任何一门技术的同时,其实就是自我修炼的过程。沉下心,尝试去拥抱数据的世界!

Top 1:

Too many connections(连接数过多,导致连接不上数据库,业务无法正常进行)

问题还原

解决问题的思路:

1、首先先要考虑在我们 MySQL 数据库参数文件里面,对应的 max_connections 这个参数值是不是设置的太小了,导致客户端连接数超过了数据库所承受的最大值。

● 该值默认大小是151,我们可以根据实际情况进行调整。

● 对应解决办法:set global max_connections=500。

但这样调整会有隐患,因为我们无法确认数据库是否可以承担这么大的连接压力,就好比原来一个人只能吃一个馒头,但现在却非要让他吃 10 个,他肯定接受不了。反应到服务器上面,就有可能会出现宕机的可能。

所以这又反应出了,我们在新上线一个业务系统的时候,要做好压力测试。保证后期对数据库进行优化调整。

2、其次可以限制 Innodb 的并发处理数量,如果 innodb_thread_concurrency = 0(这种代表不受限制) 可以先改成 16或是64 看服务器压力。如果非常大,可以先改的小一点让服务器的压力下来之后,然后再慢慢增大,根据自己的业务而定。个人建议可以先调整为 16 即可。

MySQL 随着连接数的增加性能是会下降的,可以让开发配合设置 thread pool,连接复用。在MySQL商业版中加入了thread pool这项功能。

另外对于有的监控程序会读取 information_schema 下面的表,可以考虑关闭下面的参数。

innodb_stats_on_metadata=0。

set global innodb_stats_on_metadata=0。

Top 2:(主从复制报错类型)

Last_SQL_Errno: 1062 (从库与主库数据冲突)

Last_Errno: 1062。

Last_Error: Could not execute Write_rows event on table test.t;。

Duplicate entry '4' for key 'PRIMARY',。

Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY;。

the event's master log mysql-bin.000014, end_log_pos 1505。

针对这个报错,我们首先要考虑是不是在从库中误操作导致的。结果发现,我们在从库中进行了一条针对有主键表的 sql 语句的插入,导致主库再插入相同 sql 的时候,主从状态出现异常。发生主键冲突的报错。

解决方法:

在确保主从数据一致性的前提下,可以在从库进行错误跳过。一般使用 percona-toolkit 中的 pt-slave-restart 进行。

在从库完成如下操作

[root@zs bin]# ./pt-slave-restart -uroot -proot123。

2017-07-20T14:05:30 p=...,u=root node4-relay-bin.000002 1506 1062。

之后最好在从库中开启 read_only 参数,禁止在从库进行写入操作。

Last_IO_Errno: 1593(server-id冲突)

Last_IO_Error:

Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids;。

these ids must be different for replication to work。

(or the --replicate-same-server-id option must be used on slave but this。

does not always make sense; please check the manual before using it)。

这个报错出现之后,就看一目了然看到两台机器的 server-id 是一样的。

在搭建主从复制的过程中,我们要确保两台机器的 server-id 是唯一的。这里再强调一下 server-id 的命名规则(服务器 ip 地址的最后一位+本 MySQL 服务的端口号)

解决方法:

在主从两台机器上设置不同的 server-id。

Last_SQL_Errno: 1032(从库少数据,主库更新的时候,从库报错)

Last_SQL_Error:。

Could not execute Update_rows event on table test.t; Can't find record。

in 't', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the。

event's master log mysql-bin.000014, end_log_pos 1708。

解决问题的办法:

根据报错信息,我们可以获取到报错日志和position号,然后就能找到主库执行的哪条sql,导致的主从报错。

在主库执行:

/usr/local/mysql/bin/mysqlbinlog --no-defaults -v -v --base64-output=decode-rows /data/mysql/mysql-bin.000014 |grep -A 10 1708 > 1.log。

cat 1.log

#170720 14:20:15 server id 3 end_log_pos 1708 CRC32 0x97b6bdec Update_rows: table id 113 flags: STMT_END_F。

### UPDATE `test`.`t`。

### WHERE

### @1=4 /* INT meta=0 nullable=0 is_null=0 */。

### @2='dd' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */。

### SET

### @1=4 /* INT meta=0 nullable=0 is_null=0 */。

### @2='ddd' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */。

# at 1708

#170720 14:20:15 server id 3 end_log_pos 1739 CRC32 0xecaf1922 Xid = 654。

COMMIT/*!*/;

DELIMITER ;

# End of log file。

ROLLBACK /* added by mysqlbinlog */;。

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;。

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;。

获取到 sql 语句之后,就可以在从库反向执行 sql 语句。把从库缺少的 sql 语句补全,解决报错信息。

在从库依次执行:

mysql> insert into t (b) values ('ddd');。

Query OK, 1 row affected (0.01 sec)。

mysql> stop slave;。

Query OK, 0 rows affected (0.00 sec)。

mysql> exit

Bye

[root@node4 bin]# ./pt-slave-restart -uroot -proot123。

2017-07-20T14:31:37 p=...,u=root node4-relay-bin.000005 283 1032。

Top 3:MySQL安装过程中的报错。

[root@zs data]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &[1] 3758。

[root@zs data]# 170720 14:41:24 mysqld_safe Logging to '/data/mysql/error.log'.。

170720 14:41:24 mysqld_safe Starting mysqld daemon with databases from /data/mysql170720。

14:41:25 mysqld_safe mysqld from pid file /data/mysql/node4.pid ended。

170720 14:41:24 mysqld_safe Starting mysqld daemon with databases from /data/mysql2017-07-20。

14:41:25 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated.。

Please use --explicit_defaults_for_timestamp server option。

(see documentation for more details)./usr/local/mysql/bin/mysqld:。

File '/data/mysql/mysql-bin.index' not found (Errcode: 13 - Permission denied)。

2017-07-20 14:41:25 4388 [ERROR] Aborting。

解决思路:

遇到这样的报错信息,我们要学会时时去关注错误日志 error log 里面的内容。看见了关键的报错点 Permission denied。证明当前 MySQL 数据库的数据目录没有权限。

解决方法:

[root@zs data]# chown mysql:mysql -R mysql。

[root@zs data]# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &。

[1] 4402

[root@zs data]# 170720 14:45:56 mysqld_safe Logging to '/data/mysql/error.log'.。

170720 14:45:56 mysqld_safe Starting mysqld daemon with databases from /data/mysql。

启动成功。

如何避免这类问题,个人建议在安装 MySQL 初始化的时候,一定加上--user=mysql,这样就可以避免权限问题。

./mysql_install_db --basedir=/usr/local/mysql/ --datadir=/data/mysql/ --defaults-file=/etc/my.cnf --user=mysql。

Top 4:数据库密码忘记的问题。

[root@zs ~]# mysql -uroot -p。

Enter password:。

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)。

[root@zs ~]# mysql -uroot -p。

Enter password:。

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)。

我们有可能刚刚接手别人的 MySQL 数据库,而且没有完善的交接文档。root 密码可以丢失或者忘记了。

解决思路:

目前是进入不了数据库的情况,所以我们要考虑是不是可以跳过权限。因为在数据库中,mysql数据库中user表记录着我们用户的信息。

解决方法:

启动 MySQL 数据库的过程中,可以这样执行:

/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf --skip-grant-tables &。

这样启动,就可以不用输入密码,直接进入 mysql 数据库了。然后在修改你自己想要改的root密码即可。

update mysql.user set password=password('root123') where user='root';。

Top 5:truncate 删除数据,导致自动清空自增ID,前端返回报错 not found。

这个问题的出现,就要考虑下 truncate 和 delete 的区别了。

看下实验演练:

首先先创建一张表;

CREATE TABLE `t` (。

`a` int(11) NOT NULL AUTO_INCREMENT,。

`b` varchar(20) DEFAULT NULL,。

PRIMARY KEY (`a`),。

KEY `b` (`b`)

) ENGINE=InnoDB AUTO_INCREMENT=300 DEFAULT CHARSET=utf8。

插入三条数据:

mysql> insert into t (b) values ('aa');。

Query OK, 1 row affected (0.00 sec)。

mysql> insert into t (b) values ('bb');。

Query OK, 1 row affected (0.00 sec)。

mysql> insert into t (b) values ('cc');。

Query OK, 1 row affected (0.00 sec)。

mysql> select * from t;。

+-----+------+

| a | b |

+-----+------+

| 300 | aa |

| 301 | bb |

| 302 | cc |

+-----+------+

3 rows in set (0.00 sec)。

先用 delete 进行删除全表信息,再插入新值。

结果发现 truncate 把自增初始值重置了,自增属性从1开始记录了。当前端用主键id进行查询时,就会报没有这条数据的错误。

个人建议不要使用 truncate 对表进行删除操作,虽然可以回收表空间,但是会涉及自增属性问题。这些坑,我们不要轻易钻进去。

Top 6:

阿里云 MySQL 的配置文件中,需要注意一个参数设置就是:

lower_case_table_names = 0;默认情况。

lower_case_table_names = 1;是不区分大小写 . 如果报你小写的表名找不到, 那你就把远端数据库的表名改成小写 , 反之亦然 . 注意 Mybatis 的 Mapper 文件的所有表名也要相应修改。

Top 7:

有同学经常会问张老师,为什么我的数据库总会出现中文乱码的情况。一堆????不知道怎么回事。当向数据库中写入创建表,并插入中文时,会出现这种问题。此报错会涉及数据库字符集的问题。

解决思路:

对于中文乱码的情况,记住老师告诉你的三个统一就可以。还要知道在目前的mysql数据库中字符集编码都是默认的UTF8。

处理办法:

1、数据终端,也就是我们连接数据库的工具设置为 utf8。

2、操作系统层面;可以通过 cat /etc/sysconfig/i18n 查看;也要设置为 utf8。

3、数据库层面;在参数文件中的 mysqld 下,加入 character-set-server=utf8。

Emoji 表情符号录入 mysql 数据库中报错。

Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x97\xF0\x9F...' for column 'CONTENT' at row 1。

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)。

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)。

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)。

at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)。

at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)。

at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)。

at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)。

at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1379)。

解决思路:针对表情插入的问题,一定还是字符集的问题。

处理方法:我们可以直接在参数文件中,加入。

vim /etc/my.cnf。

[mysqld]

init-connect='SET NAMES utf8mb4'。

character-set-server=utf8mb4。

注:utf8mb4 是 utf8 的超集。

Top 8:使用 binlog_format=statement 这种格式,跨库操作,导致从库丢失数据,用户访问导致出现错误数据信息。

当前数据库二进制日志的格式为:binlog_format=statement。

在主库设置binlog-do-db=mydb1(只同步mydb1这一个库)

在主库执行use mydb2;

insert into mydb1.t1 values ('bb');这条语句不会同步到从库。

但是这样操作就可以;

use mydb1;

insert into mydb1.t1 values ('bb');因为这是在同一个库中完成的操作。

在生产环境中建议使用binlog的格式为row,而且慎用binlog-do-db参数。

Top 9:MySQL 数据库连接超时的报错 ;

org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08S01。

org.hibernate.util.JDBCExceptionReporter - The last packet successfully received from the server was43200 milliseconds ago.The last packet sent successfully to the server was 43200 milliseconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection 'autoReconnect=true' to avoid this problem.。

org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session。

org.hibernate.exception.JDBCConnectionException: Could not execute JDBC batch update。

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.。

org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08003。

org.hibernate.util.JDBCExceptionReporter - No operations allowed after connection closed. Connection was implicitly closed due to underlying exception/error:。

** BEGIN NESTED EXCEPTION **。

大多数做 DBA 的同学,可能都会被开发人员告知,你们的数据库报了这个错误了。赶紧看看是哪里的问题。

这个问题是由两个参数影响的,wait_timeout 和 interactive_timeout。数据默认的配置时间是28800(8小时)意味着,超过这个时间之后,MySQL 数据库为了节省资源,就会在数据库端断开这个连接,Mysql服务器端将其断开了,但是我们的程序再次使用这个连接时没有做任何判断,所以就挂了。

解决思路:

先要了解这两个参数的特性;这两个参数必须同时设置,而且必须要保证值一致才可以。

我们可以适当加大这个值,8小时太长了,不适用于生产环境。因为一个连接长时间不工作,还占用我们的连接数,会消耗我们的系统资源。

解决方法:

可以适当在程序中做判断;强烈建议在操作结束时更改应用程序逻辑以正确关闭连接;然后设置一个比较合理的timeout的值(根据业务情况来判断)

Top 10 :can't open file (errno:24)。

有的时候,数据库跑得好好的,突然报不能打开数据库文件的错误了。

解决思路:

首先我们要先查看数据库的 error log。然后判断是表损坏,还是权限问题。还有可能磁盘空间不足导致的不能正常访问表;操作系统的限制也要关注下;用 perror 工具查看具体错误!

linux:/usr/local/mysql/bin # ./perror 24。

OS error code 24: Too many open files。

超出最大打开文件数限制!ulimit -n查看系统的最大打开文件数是65535,不可能超出!那必然是数据库的最大打开文件数超出限制!

在 MySQL 里查看最大打开文件数限制命令:show variables like 'open_files_limit';。

发现该数值过小,改为2048,重启 MySQL,应用正常。

处理方法:

repair table ;

chown mysql权限

清理磁盘中的垃圾数据

如何在win7下的eclipse中调试Hadoop2.2.0的程序的相关图片

如何在win7下的eclipse中调试Hadoop2.2.0的程序

一、首先要知道此前提转载若在windows的Eclipse工程中直接启动mapreduc程序,需要先把hadoop集群的配置目录下的xml都拷贝到src目录下,让程序自动读取集群的地址后去进行分布式运行(您也可以自己写java代码去设置job的configuration属性)。若不拷贝,工程中bin目录没有完整的xml配置文件,则windows执行的mapreduce程序全部通过本机的jvm执行,作业名也是带有“local"字眼的作业,如job_local2062122004_0001。这不是真正的分布式运行mapreduce程序。估计得研究org.apache.hadoop.conf.Configuration的源码,反正xml配置文件会影响执行mapreduce使用的文件系统是本机的windows文件系统还是远程的hdfs系统;还有影响执行mapreduce的mapper和reducer的是本机的jvm还是集群里面机器的jvm二、本文的结论第一点就是:windows上执行mapreduce,必须打jar包到所有slave节点才能正确分布式运行mapreduce程序。(我有个需求是要windows上触发一个mapreduce分布式运行)第二点就是:Linux上,只需拷贝jar文件到集群master上,执行命令hadoopjarPackage.jarMainClassName即可分布式运行mapreduce程序。第三点就是:推荐使用附一,实现了自动打jar包并上传,分布式执行的mapreduce程序。附一、推荐使用此方法:实现了自动打jar包并上传,分布式执行的mapreduce程序:请先参考博文五篇:Hadoop作业提交分析(一)~~(五)引用博文的附件中EJob.java到你的工程中,然后main中添加如下方法和代码。publicstaticFilecreatePack()throwsIOException{FilejarFile=EJob.createTempJar("bin");ClassLoaderclassLoader=EJob.getClassLoader();Thread.currentThread().setContextClassLoader(classLoader);returnjarFile;}在作业启动代码中使用打包:Jobjob=Job.getInstance(conf,"testAnaAction");添加:StringjarPath=createPack().getPath();job.setJar(jarPath);即可实现直接runasjavaapplication在windows跑分布式的mapreduce程序,不用手工上传jar文件。附二、得出结论的测试过程(未有空看书,只能通过愚笨的测试方法得出结论了)一.直接通过windows上Eclipse右击main程序的java文件,然后"runasapplication"或选择hadoop插件"runonhadoop"来触发执行MapReduce程序的测试。1,如果不打jar包到进集群任意linux机器上,它报错如下:[work]2012-06-2515:42:47,360-org.apache.hadoop.mapreduce.Job-10244[main]INFOorg.apache.hadoop.mapreduce.Job-map0%reduce0%[work]2012-06-2515:42:52,223-org.apache.hadoop.mapreduce.Job-15107[main]INFOorg.apache.hadoop.mapreduce.Job-TaskId:attempt_1403517983686_0056_m_000000_0,Status:FAILEDError:java.lang.RuntimeException:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountMappernotfoundatorg.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)atorg.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)atorg.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:721)atorg.apache.hadoop.mapred.MapTask.run(MapTask.java:339)atorg.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)atjava.security.AccessController.doPrivileged(NativeMethod)atjavax.security.auth.Subject.doAs(Subject.java:415)atorg.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)atorg.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)Causedby:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountMappernotfoundatorg.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1626)atorg.apache.hadoop.conf.Configuration.getClass(Configuration.java:1718)8more#Error:后重复三次2012-06-2515:44:53,234-org.apache.hadoop.mapreduce.Job-37813[main]INFOorg.apache.hadoop.mapreduce.Job-map100%reduce100%现象就是:报错,无进度,无运行结果。2,拷贝jar包到“只是”集群master的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse"runasapplication"和通过hadoop插件"runonhadoop"来触发执行,它报错同上。现象就是:报错,无进度,无运行结果。3,拷贝jar包到集群某些slave的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse"runasapplication"和通过hadoop插件"runonhadoop"来触发执行和报错:Error:java.lang.RuntimeException:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountMappernotfoundatorg.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)atorg.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)和报错:Error:java.lang.RuntimeException:java.lang.ClassNotFoundException:ClassbookCount.BookCount$BookCountReducernotfound现象就是:有报错,但仍然有进度,有运行结果。4,拷贝jar包到集群所有slave的$HADOOP_HOME/share/hadoop/mapreduce/目录上,直接通过windows的eclipse"runasapplication"和通过hadoop插件"runonhadoop"来触发执行:现象就是:无报错,有进度,有运行结果。第一点结论就是:windows上执行mapreduce,必须打jar包到所有slave节点才能正确分布式运行mapreduce程序。二在Linux上的通过以下命令触发MapReduce程序的测试。hadoopjar$HADOOP_HOME/share/hadoop/mapreduce/bookCount.jarbookCount.BookCount1,只拷贝到master,在master上执行。现象就是:无报错,有进度,有运行结果。2,拷贝随便一个slave节点,在slave上执行。现象就是:无报错,有进度,有运行结果。但某些节点上运行会报错如下,且运行结果。:14/06/2516:44:02INFOmapreduce.JobSubmitter:Cleaningupthestagingarea/tmp/hadoop-yarn/staging/hduser/.staging/job_1403517983686_0071Exceptioninthread"main"java.lang.NoSuchFieldError:DEFAULT_MAPREDUCE_APPLICATION_CLASSPATHatorg.apache.hadoop.mapreduce.v2.util.MRApps.setMRFrameworkClasspath(MRApps.java:157)atorg.apache.hadoop.mapreduce.v2.util.MRApps.setClasspath(MRApps.java:198)atorg.apache.hadoop.mapred.YARNRunner.createApplicationSubmissionContext(YARNRunner.java:443)atorg.apache.hadoop.mapred.YARNRunner.submitJob(YARNRunner.java:283)atorg.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:415)atorg.apache.hadoop.mapreduce.Job$10.run(Job.java:1268)atorg.apache.hadoop.mapreduce.Job$10.run(Job.java:1265)atjava.security.AccessController.doPrivileged(NativeMethod)atjavax.security.auth.Subject.doAs(Subject.java:415)atorg.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)atorg.apache.hadoop.mapreduce.Job.submit(Job.java:1265)atorg.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1286)atcom.etrans.anaSpeed.AnaActionMr.run(AnaActionMr.java:207)atorg.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)atcom.etrans.anaSpeed.AnaActionMr.main(AnaActionMr.java:44)atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)atjava.lang.reflect.Method.invoke(Method.java:606)atorg.apache.hadoop.util.RunJar.main(RunJar.java:212)第二点结论就是:Linux上,只需拷贝jar文件到集群master上,执行命令hadoopjarPackage.jarMainClassName即可分布式运行mapreduce程序。

如何:创建和运行长时间运行的工作流的相关图片

如何:创建和运行长时间运行的工作流

如何eclipse中调试hadoop2.2.0,如果你使用的还是hadoop1.x的版本,那么,也没事,散仙在以前的博客。

里,也写过eclipse调试1.x的hadoop程序,两者最大的不同之处在于使用的eclipse插件不同,hadoop2.x与hadoop1.x。

的API,不太一致,所以插件也不一样,我们只需要使用分别对应的插件即可. 。

下面开始进入正题: 。

序号

名称 。

描述 。

1

eclipse 。

Juno Service Release 4.2的本 。

2

操作系统 。

Windows7 。

3

hadoop的eclipse插件 。

hadoop-eclipse-plugin-2.2.0.jar 。

4

hadoop的集群环境 。

虚拟机Linux的Centos6.5单机伪分布式 。

5

调试程序 。

Hellow World 。

遇到的几个问题如下:

java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.。

解决办法:

在org.apache.hadoop.util.Shell类的checkHadoopHome()方法的返回值里写固定的 。

本机hadoop的路径,散仙在这里更改如下:

private static String checkHadoopHome() {。

// first check the Dflag hadoop.home.dir with JVM scope。

//System.setProperty("hadoop.home.dir", "...");。

String home = System.getProperty("hadoop.home.dir");。

// fall back to the system/user-global env variable。

if (home == null) {。

home = System.getenv("HADOOP_HOME");。

}

try {

// couldn't find either setting for hadoop's home directory。

if (home == null) {。

throw new IOException("HADOOP_HOME or hadoop.home.dir are not set.");。

}

if (home.startsWith("\"") && home.endsWith("\"")) {。

home = home.substring(1, home.length()-1);。

}

// check that the home setting is actually a directory that exists。

File homedir = new File(home);。

if (!homedir.isAbsolute() || !homedir.exists() || !homedir.isDirectory()) {。

throw new IOException("Hadoop home directory " + homedir。

+ " does not exist, is not a directory, or is not an absolute path.");。

}

home = homedir.getCanonicalPath();。

} catch (IOException ioe) {。

if (LOG.isDebugEnabled()) {。

LOG.debug("Failed to detect a valid hadoop home directory", ioe);。

}

home = null;。

}

//固定本机的hadoop地址。

home="D:\\hadoop-2.2.0";。

return home;。

}

第二个异常,Could not locate executable 。

D:\Hadoop\tar\hadoop-2.2.0\hadoop-2.2.0\bin\winutils.exe in the Hadoop 。

binaries. 找不到win上的执行程序,可以去 https://github.com/srccodes/hadoop-common-2.2.0-bin。

下载bin包,覆盖本机的hadoop跟目录下的bin包即可 。

第三个异常:

Exception in thread "main" java.lang.IllegalArgumentException: Wrong FS: hdfs://192.168.130.54:19000/user/hmail/output/part-00000, expected: file:/// 。

at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:310) 。

at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:47) 。

at org.apache.hadoop.fs.RawLocalFileSystem.getFileStatus(RawLocalFileSystem.java:357) 。

at org.apache.hadoop.fs.FilterFileSystem.getFileStatus(FilterFileSystem.java:245) 。

at org.apache.hadoop.fs.ChecksumFileSystem$ChecksumFSInputChecker.<init>(ChecksumFileSystem.java:125) 。

at org.apache.hadoop.fs.ChecksumFileSystem.open(ChecksumFileSystem.java:283) 。

at org.apache.hadoop.fs.FileSystem.open(FileSystem.java:356) 。

at com.netease.hadoop.HDFSCatWithAPI.main(HDFSCatWithAPI.java:23)。

出现这个异常,一般是HDFS的路径写的有问题,解决办法,拷贝集群上的core-site.xml和hdfs-site.xml文件,放在eclipse的src根目录下即可。

第四个异常:

Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z。

出现这个异常,一般是由于HADOOP_HOME的环境变量配置的有问题,在这里散仙特别说明一下,如果想在Win上的eclipse中成功调试Hadoop2.2,就需要在本机的环境变量上,添加如下的环境变量:

(1)在系统变量中,新建HADOOP_HOME变量,属性值为D:\hadoop-2.2.0.也就是本机对应的hadoop目录 。

(2)在系统变量的Path里,追加%HADOOP_HOME%/bin即可 。

以上的问题,是散仙在测试遇到的,经过对症下药,我们的eclipse终于可以成功的调试MR程序了,散仙这里的Hellow World源码如下:

package com.qin.wordcount;。

import java.io.IOException;。

import org.apache.hadoop.fs.FileSystem;。

import org.apache.hadoop.fs.Path;。

import org.apache.hadoop.io.IntWritable;。

import org.apache.hadoop.io.LongWritable;。

import org.apache.hadoop.io.Text;。

import org.apache.hadoop.mapred.JobConf;。

import org.apache.hadoop.mapreduce.Job;。

import org.apache.hadoop.mapreduce.Mapper;。

import org.apache.hadoop.mapreduce.Reducer;。

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;。

import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;。

import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;。

import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;。

/***

*

* Hadoop2.2.0测试。

* 放WordCount的例子。

*

* @author qindongliang。

*

* hadoop技术交流群: 376932160。

*

*

* */

public class MyWordCount {。

/**

* Mapper

*

* **/

private static class WMapper extends Mapper<LongWritable, Text, Text, IntWritable>{。

private IntWritable count=new IntWritable(1);。

private Text text=new Text();。

@Override

protected void map(LongWritable key, Text value,Context context)。

throws IOException, InterruptedException {。

String values[]=value.toString().split("#");。

//System.out.println(values[0]+"========"+values[1]);。

count.set(Integer.parseInt(values[1]));。

text.set(values[0]);。

context.write(text,count);。

}

}

/**

* Reducer

*

* **/

private static class WReducer extends Reducer<Text, IntWritable, Text, Text>{。

private Text t=new Text();。

@Override

protected void reduce(Text key, Iterable<IntWritable> value,Context context)。

throws IOException, InterruptedException {。

int count=0;。

for(IntWritable i:value){。

count+=i.get();。

}

t.set(count+"");。

context.write(key,t);。

}

}

/**

* 改动一

* (1)shell源码里添加checkHadoopHome的路径。

* (2)974行,FileUtils里面。

* **/

public static void main(String[] args) throws Exception{。

// String path1=System.getenv("HADOOP_HOME");。

// System.out.println(path1);。

// System.exit(0);。

JobConf conf=new JobConf(MyWordCount.class);。

//Configuration conf=new Configuration();。

//conf.set("mapred.job.tracker","192.168.75.130:9001");。

//读取person中的数据字段。

// conf.setJar("tt.jar");。

//注意这行代码放在最前面,进行初始化,否则会报。

/**Job任务**/

Job job=new Job(conf, "testwordcount");。

job.setJarByClass(MyWordCount.class);。

System.out.println("模式: "+conf.get("mapred.job.tracker"));;。

// job.setCombinerClass(PCombine.class);。

// job.setNumReduceTasks(3);//设置为3。

job.setMapperClass(WMapper.class);。

job.setReducerClass(WReducer.class);。

job.setInputFormatClass(TextInputFormat.class);。

job.setOutputFormatClass(TextOutputFormat.class);。

job.setMapOutputKeyClass(Text.class);。

job.setMapOutputValueClass(IntWritable.class);。

job.setOutputKeyClass(Text.class);。

job.setOutputValueClass(Text.class);。

String path="hdfs://192.168.46.28:9000/qin/output";。

FileSystem fs=FileSystem.get(conf);。

Path p=new Path(path);。

if(fs.exists(p)){。

fs.delete(p, true);。

System.out.println("输出路径存在,已删除!");。

}

FileInputFormat.setInputPaths(job, "hdfs://192.168.46.28:9000/qin/input");。

FileOutputFormat.setOutputPath(job,p );。

System.exit(job.waitForCompletion(true) ? 0 : 1); 。

求助 用hadoop-mapreduce-examples-2.7.3.jar怎么查询特定的词

右击本地服务器上的“数据库”节点,然后选择“新建数据库”。 将新数据库命名为 WF45GettingStartedTutorial,接受所有其他值,然后选择“确定”。 注意 在创建数据库前,确保您在本地服务器上具有创建数据库权限。 从“文件”菜单中选择“打开”,然后单击“文件”。 浏览到:C:\Windows\Microsoft.NET\Framework\4.0.30319\sql\en 以下文件夹 选择以下两个文件,然后单击“打开”。 SqlWorkflowInstanceStoreLogic.sql SqlWorkflowInstanceStoreSchema.sql 从”窗口“菜单选择“SqlWorkflowInstanceStoreSchema.sql”。 从“查询”菜单确保“WF45GettingStartedTutorial”选择“可用数据库”下拉菜单,然后选择“执行”。 从”窗口“菜单选择“SqlWorkflowInstanceStoreLogic.sql”。 从“查询”菜单确保“WF45GettingStartedTutorial”选择“可用数据库”下拉菜单,然后选择“执行”。 注意 按正确的顺序执行前面的两个步骤,这一点非常重要。 如果不按顺序执行查询,系统会发生错误,并且持久性数据库会配置不正确。 向DurableInstancing 程序集中添加引用 在“解决方案资源管理器”中右击“NumberGuessWorkflowHost”,然后选择“添加引用”。 在“添加引用”列表中选择“程序集”,并在“搜索程序集”框中键入 DurableInstancing。 这会筛选程序集,并使所需引用更便于选择。 从“搜索结果”列表检查旁边的复选框“System.Activities.DurableInstancing”和“System.Runtime.DurableInstancing”,然后单击“确定”。 创建工作流宿主窗体注意 此过程中的步骤描述了如何手动添加和配置窗体。 如果需要,可以下载教程的解决方案文件,并将完成的窗体添加至项目中。 下载教程文件,请参见 Windows Workflow Foundation (WF45) - 入门教程 。 文件下载后,在“解决方案资源管理器”中右击“NumberGuessWorkflowHost”,并选择“添加”,“现有项”。 浏览至项目文件中的 Asset 文件夹,并选择 “WorkflowHostForm”。 在“解决方案资源管理器”中右击“NumberGuessWorkflowHost”并选择“添加”,“新项目”。 在“已安装”模板列表中,选择“Windows 窗体”,在“名称”框中键入WorkflowHostForm,并单击“添加”。 配置窗体上的以下属性。 属性 Value FormBorderStyle FixedSingle MaximizeBox False 大小 400, 420 按指定的顺序将以下控件添加到窗体中,并按照需要配置属性。 控制 属性 Value 按钮 名称 btnNew 位置 13, 13 大小 75, 23 Text 新游戏 标签 位置 94, 18 Text 猜测一个数字从 1 至 ComboBox 名称 cboRange DropDownStyle DropDownList 项 10 100 1000 位置 228, 12 大小 143, 21 标签 位置 13, 43 Text 工作流类型 ComboBox 名称 cboType DropDownStyle DropDownList 项 StateMachineNumberGuessWorkflow FlowchartNumberGuessWorkflow SequentialNumberGuessWorkflow 位置 94, 40 大小 277, 21 标签 名称 lblVersion 位置 13, 362 Text 工作流版本 GroupBox 位置 13, 84 大小 358, 270 Text Game 注意 以下控件包含在“GroupBox”中。 在将它们添加至窗体时,将它们放到“GroupBox”上。 标签 位置 7, 20 Text 工作流实例 Id ComboBox 名称 cboInstanceId DropDownStyle DropDownList 位置 121, 17 大小 231, 21 标签 位置 7, 47 Text 猜测TextBox 名称 txtGuess 位置 50, 44 大小 65, 20 按钮 名称 btnGuess 位置 121, 42 大小 75, 23 Text 转至按钮 名称 btnQuit 位置 277, 42 大小 75, 23 Text 退出TextBox 名称 txtStatus 位置 10, 73 Multiline True ReadOnly True ScrollBars 垂直 大小 342, 191 将窗体的“AcceptButton”属性设置为“btnGuess”。 下面的示例阐释已完成的窗体。 添加窗体的属性和帮助器方法 本节的步骤将属性和帮助器添加至窗体类,此窗体类将配置窗体的 UI,以支持运行和继续执行数字猜测工作流。 在“解决方案资源管理器”中右击“WorkflowHostForm”并选择“查看代码”。 添加以下 using(或 Imports)语句和另一些using(或 Imports)语句到文件的顶部。 using System.Activities.DurableInstancing; using System.Activities; using System.Data.SqlClient; using System.IO; 将以下成员声明添加到“WorkflowHostForm”类中。 const string connectionString = "Server=.\\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=SSPI"; SqlWorkflowInstanceStore store; bool WorkflowStarting;注意 如果您的连接字符串不同,请更新 connectionString 引用数据库。 将WorkflowInstanceId 属性添加到 WorkflowFormHost 类中。 public Guid WorkflowInstanceId { get { return cboInstanceId.SelectedIndex == -1 ? Guid.Empty : (Guid)cboInstanceId.SelectedItem; } }cboInstanceId 组合框显示保留的工作流实例 ID 列表,且 WorkflowInstanceId 属性返回当前选定的工作流。 为窗体 Load 事件添加下面的处理程序。 若要添加处理程序,则切换到窗体的“设计视图”,单击“属性”窗口顶部的“事件”图标,并双击“加载”。 private void WorkflowHostForm_Load(object sender, EventArgs e) { // Initialize the store and configure it so that it can be used for // multiple WorkflowApplication instances. store = new SqlWorkflowInstanceStore(connectionString); WorkflowApplication.CreateDefaultInstanceOwner(store, null, WorkflowIdentityFilter.Any); // Set default ComboBox selections. cboRange.SelectedIndex = 0; cboType.SelectedIndex = 0; ListPersistedWorkflows(); } 在窗体加载时,SqlWorkflowInstanceStore 进行配置,范围和工作流类型组合框将会设置为默认值,且保留的工作流实例将添加到 cboInstanceIds 中。 为cboInstanceId 添加以下 SelectedIndexChanged 处理程序。 若要添加处理程序,则切换到窗体的“设计视图”,选择 cboInstanceId 组合框,单击“属性”窗口顶部的“事件”图标,并双击“SelectedIndexChanged”。 无论用户何时使用组合框选择工作流,此处理程序均更新状态窗口。 private void cboInstanceId_SelectedIndexChanged(object sender, EventArgs e) { if (cboInstanceId.SelectedItem == null) { return; } // Clear the status window. txtStatus.Clear(); // Get the workflow version and display it. // If the workflow is just starting then this info will not // be available in the persistence store so do not try and retrieve it. if (!WorkflowStarting) { WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(this.WorkflowInstanceId, store); lblVersion.Text = WorkflowVersionMap.GetIdentityDescription(instance.DefinitionIdentity); // Unload the instance. instance.Abandon(); } } 将下面的 ListPersistedWorkflows 方法添加到窗体类中。 private void ListPersistedWorkflows() { using (SqlConnection localCon = new SqlConnection(connectionString)) { string localCmd = "Select [InstanceId] from [System.Activities.DurableInstancing].[Instances] Order By [CreationTime]"; SqlCommand cmd = localCon.CreateCommand(); cmd.CommandText = localCmd; localCon.Open(); using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { while (reader.Read()) { // Get the InstanceId of the persisted Workflow Guid id = Guid.Parse(reader[0].ToString()); cboInstanceId.Items.Add(id); } } } }ListPersistedWorkflows 查询保留的工作流实例的实例存储区,并将实例 ID 添加到 cboInstanceId 组合框中。 将下面的 UpdateStatus 方法和对应的委托添加到窗体类中。 此方法使用当前正在运行的工作流的状态来更新窗体上的状态窗口。 private delegate void UpdateStatusDelegate(string msg); public void UpdateStatus(string msg) { // We may be on a different thread so we need to // make this call using BeginInvoke. if (txtStatus.InvokeRequired) { BeginInvoke(new UpdateStatusDelegate(UpdateStatus), msg); } else { if (!msg.EndsWith("\r\n")) { msg += "\r\n"; } txtStatus.Text += msg; txtStatus.SelectionStart = txtStatus.Text.Length; txtStatus.ScrollToCaret(); } } 将下面的 GameOver 方法和对应的委托添加到窗体类中。 当工作流完成时,此方法通过从“工作流实例 ID”组合框中删除完成的工作流实例 ID 来更新窗体 UI。 private delegate void GameOverDelegate(); private void GameOver() { if (this.InvokeRequired) { BeginInvoke(new GameOverDelegate(GameOver)); } else { // Remove this instance from the combo box cboInstanceId.Items.Remove(cboInstanceId.SelectedItem); cboInstanceId.SelectedItem = null; } }配置实例存储区、工作流生命周期处理程序和扩展 向窗体类添加 ConfigureWorkflowApplication 方法。 private void ConfigureWorkflowApplication(WorkflowApplication wfApp) { } 此方法配置 WorkflowApplication,添加所需扩展,并添加工作流生命周期事件的处理程序。 在ConfigureWorkflowApplication中,为 WorkflowApplication 指定SqlWorkflowInstanceStore。 // Configure the persistence store. wfApp.InstanceStore = store; 接下来创建 StringWriter 实例,并将它添加到 WorkflowApplication 的Extensions 集合中。 在将StringWriter 添加到扩展中时,它会捕获所有 WriteLine 活动输出 。在工作流进入空闲状态时,可从 StringWriter 中提取 WriteLine 输出,并显示在窗体上。 // Add a StringWriter to the extensions. This captures the output // from the WriteLine activities so we can display it in the form. StringWriter sw = new StringWriter(); wfApp.Extensions.Add(sw); 为Completed 事件添加以下处理程序。 在工作流成功完成时,执行猜测数字的轮数会显示到状态窗口。 如果工作流终止,系统会显示导致终止的异常信息。 在处理程序结束时,系统会调用 GameOver 方法,此方法从工作流列表中删除完成的工作流。 wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e) { if (e.CompletionState == ActivityInstanceState.Faulted) { UpdateStatus(string.Format("Workflow Terminated. Exception: {0}\r\n{1}", e.TerminationException.GetType().FullName, e.TerminationException.Message)); } else if (e.CompletionState == ActivityInstanceState.Canceled) { UpdateStatus("Workflow Canceled."); } else { int Turns = Convert.ToInt32(e.Outputs["Turns"]); UpdateStatus(string.Format("Congratulations, you guessed the number in {0} turns.", Turns)); } GameOver(); }; 添加以下 Aborted 和OnUnhandledException 处理程序。 GameOver 方法不从 Aborted 处理程序中调用,因为在工作流实例中止时,它并未终止,且以后可能继续执行实例。 wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { UpdateStatus(string.Format("Workflow Aborted. Exception: {0}\r\n{1}", e.Reason.GetType().FullName, e.Reason.Message)); }; wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e) { UpdateStatus(string.Format("Unhandled Exception: {0}\r\n{1}", e.UnhandledException.GetType().FullName, e.UnhandledException.Message)); GameOver(); return UnhandledExceptionAction.Terminate; }; 添加以下 PersistableIdle 处理程序。 此处理程序检索所添加的 StringWriter 扩展,从 WriteLine 活动中提取输出,并将它显示在状态窗口中。 wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { // Send the current WriteLine outputs to the status window. var writers = e.GetInstanceExtensions<StringWriter>(); foreach (var writer in writers) { UpdateStatus(writer.ToString()); } return PersistableIdleAction.Unload; }; PersistableIdleAction 枚举有三个值: None、 Persist 和 Unload。 Persist 会导致工作流保留,但不会导致工作流卸载。 Unload 会导致工作流保留并卸载。 以下示例是完整的 ConfigureWorkflowApplication 方法。 private void ConfigureWorkflowApplication(WorkflowApplication wfApp) { // Configure the persistence store. wfApp.InstanceStore = store; // Add a StringWriter to the extensions. This captures the output // from the WriteLine activities so we can display it in the form. StringWriter sw = new StringWriter(); wfApp.Extensions.Add(sw); wfApp.Completed = delegate(WorkflowApplicationCompletedEventArgs e) { if (e.CompletionState == ActivityInstanceState.Faulted) { UpdateStatus(string.Format("Workflow Terminated. Exception: {0}\r\n{1}", e.TerminationException.GetType().FullName, e.TerminationException.Message)); } else if (e.CompletionState == ActivityInstanceState.Canceled) { UpdateStatus("Workflow Canceled."); } else { int Turns = Convert.ToInt32(e.Outputs["Turns"]); UpdateStatus(string.Format("Congratulations, you guessed the number in {0} turns.", Turns)); } GameOver(); }; wfApp.Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { UpdateStatus(string.Format("Workflow Aborted. Exception: {0}\r\n{1}", e.Reason.GetType().FullName, e.Reason.Message)); }; wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e) { UpdateStatus(string.Format("Unhandled Exception: {0}\r\n{1}", e.UnhandledException.GetType().FullName, e.UnhandledException.Message)); GameOver(); return UnhandledExceptionAction.Terminate; }; wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { // Send the current WriteLine outputs to the status window. var writers = e.GetInstanceExtensions<StringWriter>(); foreach (var writer in writers) { UpdateStatus(writer.ToString()); } return PersistableIdleAction.Unload; }; }启用对多个工作流类型的启动和继续执行 要继续执行工作流实例,主机必须提供工作流定义。 在此教程中有三个工作流类型,且后续教程步骤会介绍这些类型的多个版本。 WorkflowIdentity 为主机应用程序提供一种方法,此方法用于将标识信息与保留的工作流实例关联。 本节的步骤演示了如何创建实用工具类,以帮助从保留的工作流实例到对应的工作流定义映射工作流标识。 有关 有关 WorkflowIdentity 和版本管理的信息,请参见 使用WorkflowApplication 标识和版本控制。 在“解决方案资源管理器”中右击“NumberGuessWorkflowHost”并选择“添加”,“类”。 在“名称”框中键入 “WorkflowVersionMap”,然后单击“添加”。 添加以下 using 或Imports 语句和另一些using 或Imports 语句到文件的顶部。 using NumberGuessWorkflowActivities; using System.Activities; 使用以下声明替换 WorkflowVersionMap 类声明。 public static class WorkflowVersionMap { static Dictionary<WorkflowIdentity, Activity> map; // Current version identities. static public WorkflowIdentity StateMachineNumberGuessIdentity; static public WorkflowIdentity FlowchartNumberGuessIdentity; static public WorkflowIdentity SequentialNumberGuessIdentity; static WorkflowVersionMap() { map = new Dictionary<WorkflowIdentity, Activity>(); // Add the current workflow version identities. StateMachineNumberGuessIdentity = new WorkflowIdentity { Name = "StateMachineNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; FlowchartNumberGuessIdentity = new WorkflowIdentity { Name = "FlowchartNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; SequentialNumberGuessIdentity = new WorkflowIdentity { Name = "SequentialNumberGuessWorkflow", Version = new Version(1, 0, 0, 0) }; map.Add(StateMachineNumberGuessIdentity, new StateMachineNumberGuessWorkflow()); map.Add(FlowchartNumberGuessIdentity, new FlowchartNumberGuessWorkflow()); map.Add(SequentialNumberGuessIdentity, new SequentialNumberGuessWorkflow()); } public static Activity GetWorkflowDefinition(WorkflowIdentity identity) { return map[identity]; } public static string GetIdentityDescription(WorkflowIdentity identity) { return identity.ToString(); } }WorkflowVersionMap 包含三个工作流标识,这些工作流标识从本教程映射到三个工作流定义,且在工作流启动和继续执行时用于以下小节。 启动新工作流 为btnNew 添加Click 处理程序。 若要添加处理程序,则切换到窗体的“设计视图”,并双击 btnNew。 系统将添加 btnNew_Click 处理程序,且视图切换到窗体的代码视图。 无论用户何时单击此按钮,均会启动新工作流。 private void btnNew_Click(object sender, EventArgs e) { // Start a new workflow. } 将下面的代码添加到单击处理程序中。 此代码可创建由工作流的输入参数组成的字典,由参数名称进行键控。 此字典有一个项,包含在范围组合框中检索的随机生成数的范围。 var inputs = new Dictionary<string, object>(); inputs.Add("MaxNumber", Convert.ToInt32(cboRange.SelectedItem)); 接下来添加以下启动工作流的代码。 使用WorkflowVersionMap 帮助器类来检索 WorkflowIdentity 以及与选定工作流的类型对应的工作流定义。 接下来,使用工作流定义、WorkflowIdentity 和由输入参数组成的字典来创建新的 WorkflowApplication 实例。 WorkflowIdentity identity = null; switch (cboType.SelectedItem.ToString()) { case "SequentialNumberGuessWorkflow": identity = WorkflowVersionMap.SequentialNumberGuessIdentity; break; case "StateMachineNumberGuessWorkflow": identity = WorkflowVersionMap.StateMachineNumberGuessIdentity; break; case "FlowchartNumberGuessWorkflow": identity = WorkflowVersionMap.FlowchartNumberGuessIdentity; break; }; Activity wf = WorkflowVersionMap.GetWorkflowDefinition(identity); WorkflowApplication wfApp = new WorkflowApplication(wf, inputs, identity); 接下来,添加以下代码,此代码将工作流添加到工作流列表中,并在窗体上显示工作流的版本信息。 // Add the workflow to the list and display the version information. WorkflowStarting = true; cboInstanceId.SelectedIndex = cboInstanceId.Items.Add(wfApp.Id); lblVersion.Text = identity.ToString(); WorkflowStarting = false; 调用ConfigureWorkflowApplication 为此WorkflowApplication 实例配置实例存储区、扩展和工作流生命周期处理程序。 // Configure the instance store, extensions, and // workflow lifecycle handlers. ConfigureWorkflowApplication(wfApp); 最后,调用 Run。 // Start the workflow. wfApp.Run(); 以下示例是完整的 btnNew_Click 处理程序。 private void btnNew_Click(object sender, EventArgs e) { // Start a new workflow. var inputs = new Dictionary<string, object>(); inputs.Add("MaxNumber", Convert.ToInt32(cboRange.SelectedItem)); WorkflowIdentity identity = null; switch (cboType.SelectedItem.ToString()) { case "SequentialNumberGuessWorkflow": identity = WorkflowVersionMap.SequentialNumberGuessIdentity; break; case "StateMachineNumberGuessWorkflow": identity = WorkflowVersionMap.StateMachineNumberGuessIdentity; break; case "FlowchartNumberGuessWorkflow": identity = WorkflowVersionMap.FlowchartNumberGuessIdentity; break; }; Activity wf = WorkflowVersionMap.GetWorkflowDefinition(identity); WorkflowApplication wfApp = new WorkflowApplication(wf, inputs, identity); // Add the workflow to the list and display the version information. WorkflowStarting = true; cboInstanceId.SelectedIndex = cboInstanceId.Items.Add(wfApp.Id); lblVersion.Text = identity.ToString(); WorkflowStarting = false; // Configure the instance store, extensions, and // workflow lifecycle handlers. ConfigureWorkflowApplication(wfApp); // Start the workflow. wfApp.Run(); }继续执行工作流 为btnGuess 添加Click 处理程序。 若要添加处理程序,则切换到窗体的“设计视图”,并双击 btnGuess。 无论用户何时单击此按钮,均会继续执行工作流。 private void btnGuess_Click(object sender, EventArgs e) { } 添加以下代码,以确保在工作流列表中选择工作流,且用户的猜测是有效的。 if (this.WorkflowInstanceId == Guid.Empty) { MessageBox.Show("Please select a workflow."); return; } int guess; if (!Int32.TryParse(txtGuess.Text, out guess)) { MessageBox.Show("Please enter an integer."); txtGuess.SelectAll(); txtGuess.Focus(); return; } 接下来,检索已保留工作流实例的 WorkflowApplicationInstance。 WorkflowApplicationInstance 表示保留的工作流实例,此工作流实例还未与工作流定义关联。 WorkflowApplicationInstance 的DefinitionIdentity 包含已保留工作流实例的 WorkflowIdentity。 本教程中使用 WorkflowVersionMap 实用工具类,将 WorkflowIdentity 映射到正确的工作流定义。 对工作流定义进行检索后,即可使用正确的工作流定义创建 WorkflowApplication。 WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(this.WorkflowInstanceId, store); // Use the persisted WorkflowIdentity to retrieve the correct workflow // definition from the dictionary. Activity wf = WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity); // Associate the WorkflowApplication with the correct definition WorkflowApplication wfApp = new WorkflowApplication(wf, instance.DefinitionIdentity); 创建WorkflowApplication 后,即可通过调用 ConfigureWorkflowApplication 来配置实例存储区、工作流生命周期处理程序和扩展。 这些步骤必须在每次创建新的 WorkflowApplication 时执行,且必须在将工作流实例加载到 WorkflowApplication 中之前执行。 在加载工作流后,此工作流通过用户的猜测继续执行。 // Configure the extensions and lifecycle handlers. // Do this before the instance is loaded. Once the instance is // loaded it is too late to add extensions. ConfigureWorkflowApplication(wfApp); // Load the workflow. wfApp.Load(instance); // Resume the workflow. wfApp.ResumeBookmark("EnterGuess", guess); 最后,清除猜测文本框,并使窗体准备接受其他猜测。 // Clear the Guess textbox. txtGuess.Clear(); txtGuess.Focus(); 以下示例是完整的 btnGuess_Click 处理程序。 private void btnGuess_Click(object sender, EventArgs e) { if (this.WorkflowInstanceId == Guid.Empty) { MessageBox.Show("Please select a workflow."); return; } int guess; if (!Int32.TryParse(txtGuess.Text, out guess)) { MessageBox.Show("Please enter an integer."); txtGuess.SelectAll(); txtGuess.Focus(); return; } WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(this.WorkflowInstanceId, store); // Use the persisted WorkflowIdentity to retrieve the correct workflow // definition from the dictionary. Activity wf = WorkflowVersionMap.GetWorkflowDefinition(instance.DefinitionIdentity); // Associate the WorkflowApplication with the correct definition WorkflowApplication wfApp = new WorkflowApplication(wf, instance.DefinitionIdentity); // Configure the extensions and lifecycle handlers. // Do this before the instance is loaded. Once the instance is // loaded it is too late。

原文地址:http://www.qianchusai.com/CompletionException-0.html

碇源堂和碇唯,碇源堂说了什么

碇源堂和碇唯,碇源堂说了什么

结上等缘,结上等缘发中等愿享下等福书法作品

结上等缘,结上等缘发中等愿享下等福书法作品

61575,61575129

61575,61575129

心痗-0

心痗-0

文档库网站-20,文档库在什么位置

文档库网站-20,文档库在什么位置

允容-70,允容高还是昭仪高

允容-70,允容高还是昭仪高

cc/保护母亲河的一张画,保护母亲河简单的画 一等奖

cc/保护母亲河的一张画,保护母亲河简单的画 一等奖

以手为话题的议论文800,以手为话题的议论文800字高中

以手为话题的议论文800,以手为话题的议论文800字高中

ture,ture结尾的单词

ture,ture结尾的单词

SLS2684-30

SLS2684-30