Java调用Shell引出的效率和完整性

HelloWorlddd 发布于 2016/08/11 11:05
阅读 535
收藏 1
首先看一段shell代码,下面的代码,用于Linux shell从远处电脑复制文件回本地电脑

文件expect_ssh_scp.sh
#!/usr/bin/expect                                                   #表示使用expect解释器
set timeout 100                                                      #设置下面的每一个expect需要等待的超时限制为100秒
spawn ssh userName@hremote_host command        #通过ssh连接远程主机执行命令
expect {                                                                 #expect表明需要等待的参数,send是要发送的消息
     "(yes/no)" {send "yes\r";exp_continue}
     "*assword:" {send "password\r"}
}


expect eof                                                               #指明命令交互结束
spawn scp source userName@hostName:dest            #通过scp复制远程电脑的文件到本地
expect {
"(yes/no)" {send "yes\r";exp_continue}
"*assword:" {send "password\r"}
}


expect 100%
expect eof
exit

这一段脚本被另一个脚本调用,对每一个传入的IP,执行远程复制的操作
比如,现在有本地电脑Computer0,和远程的电脑Computer1,Computer2....Computer200.
现在我需要对者200台电脑远程复制会文件夹,看起来并没什么问题

然后我打算用Java调用Shell脚本,出现了一些问题,同时可能涉及了一些概念,这里来研究下

多线程与IO流(效率)

线程:基本上来说一个处理器(或者说一个核)同时只能执行一个线程,现在的电脑基本是多处理器,那么多线程自然可以提升程序执行效率

IO流:一般来说多IO的程序,线程池的数量可以增多,因为IO操作和CPU是分开的,程序执行IO操作(CPU让IO设备开始工作),IO操作一般是阻塞的,然后CPU就空闲了,自然可以多一点线程,让CPU有别的事可做,从而提升效率

一般来说多个处理器是可以同时执行几个线程,执行多个代码块的,但对这种基本上全是数据传输的程序,多线程是否还有意义?

现在感觉传输所占比例太大,可以说90%的程序耗时都用在网络数据传输上面,那么也就是说瓶颈在IO设备,在网络等,感觉CPU再好,线程再多也没什么意义了,好比迅雷同时下载5部电影和下载5000部差别也不大

异常与超时(完整性)

程序在运行过程中都会碰到各种问题,Shell和Java采用了两种不同的处理方式

比如上面的Shell采用了人为强制设定程序执行时间限制,之所以这么干,是因为如果后面的代码如果一直执行不过去,那么没有超时限制的话,下一个ip就别想开始了,有了超时,那么如果其中一个ip出现问题,那么将错误写到log,后一个ip还是可以继续执行

而Java程序采用了异常处理机制,在程序执行过程中,如果出现了意外,比如远程电脑关机等,那么通过catch异常,然后立即处理(跳过),然后让程序继续执行,可以得到错误信息的同时,保证下一个ip继续执行,不用碰到问题,等100秒,100秒超时,程序都可以执行很多任务了

Shell中为什么有100秒超时呢?这涉及两方面的考虑:
1,ssh连接超时,如果连接不上,那么下一个ip
2,scp传输过程超时,如果传输过程中,出了问题,卡住了,那么下一个ip

但是基于第2点的超时存在一个问题,不设置超时不行,设了超时,就没法保证数据的完整性了,比如设置100秒,但是有的远程电脑文件非常大,需要200秒才能传完,但是100秒就超时了,导致传输回来的数据不完整

有一种办法是多设置几个入口shell脚本(将200个ip分成几组),然后如果超时卡住了,那么几个队列,总比一个队列好,这是纯shell脚本方式的多进程,但是这还是治标不治本,该卡住(连接不上)的还是会卡住,该在时限之内传送不完(远程文件太大了)的还是传不完,问题就出在Shell不设超时不行,设了超时也不够好,设了超时引起了效率的问题

看到这里不得不说异常比超时好,如果是纯Java也没什么问题,但是Java调用Shell,是不是有什么办法能将Shell中超时变成如同Java中的异常呢?即有效率的同时,又保证完整性

另外一点,验证数据传输的完整性,比如shell中的md5sum校验是否有帮助呢?

希望对这方面有研究的大神能指点一下,如果在效率,完整性,java,shell,多线程等合理的处理,

谢谢

加载中
返回顶部
顶部