大公司的一道上机题,请高手帮忙看看
两个服务器提供文件共享服务。
1. 服务器A和服务器B提供文件上传下载服务。服务器A是主服务器,服务器B是备用服务器。
2. 有5个客户端同时上传不同的大文件(200M~500M),当上传开始1分钟后随意启动N个客户端(命令行输入),每个客户端在这5个上传中的文件中随机选择一个文件下载
3. 中间突然停掉服务器A并保持服务器B继续服务
整个过程能顺利进行,所有下载的文件是完整并且正确的。请用Java编写,不用写界面。
请高手给点思路,thankyou。
[解决办法]
1. 服务器A和服务器B提供文件上传下载服务。服务器A是主服务器,服务器B是
备用服务器
客户端如果是网络分布,那么你需要采用分布式来做,说白了就是一个服务器核心服务器提供任务部署,第二个服务器是为了防止意外情况的备用服务器。
2. 有5个客户端同时上传不同的大文件(200M~500M),当上传开始1分钟后随意启动N个客户端(命令行输入),每个客户端在这5个上传中的文件中随机选择一个文件下载
这里你用线程异步来做,主要是处理I/O的并发任务,也没什么。
3. 中间突然停掉服务器A并保持服务器B继续服务
主服务器出现异常,那么需要将主服务器的数据拷贝到备用服务器上,当然主服务器处理任务的时候需要备份副本,出现异常也就自动移动到备用服务器继续服务。
[解决办法]
要写一个发送端和一个接收端
同时监听线程
这样就可以实现
[解决办法]
写了个简单的,也没写完,用socket和IO写的
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server { private ServerSocket serverSocket = null; private Socket socket = null; public void getFile(int port) { try { serverSocket = new ServerSocket(port); System.out.println("server start...."); while (true) { socket = serverSocket.accept(); System.out.println(socket.getInetAddress() + " is connected the server..."); Thread serverThread = new ServerThread(socket); serverThread.start(); } } catch (IOException e) { e.printStackTrace(); } } class ServerThread extends Thread { private Socket socket; public ServerThread(Socket socket) { this.socket = socket; } public void run() { File file = null; DataInputStream in = null; DataOutputStream out = null; try { in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); if (in.readChar() == '?') { downloadFile(in, out, file); } else { uploadFile(in, out, file); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); if (out != null) out.close(); if(socket!=null){ socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } public void uploadFile(DataInputStream in, DataOutputStream out, File file) { try { String fileName = null; StringBuffer stringBuffer = new StringBuffer(); char c = '\\'; while ((c = in.readChar()) != '\\') { stringBuffer.append(c); } fileName=stringBuffer.toString().substring(0, stringBuffer.length()); file = new File("e:\\back\\" + fileName); long pointer=in.readLong(); out.writeLong(file.length()); if(file.length()==0){ out.write(-1); }else if(file.length()-pointer > -1){ in = new DataInputStream(new FileInputStream(file)); int i = -1; byte[] buffer = new byte[1024*512]; while ((i = in.read(buffer)) != -1) { out.write(buffer, 0, i); pointer+=i; } out.write(-1); }else{ out.write(-1); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); if (out != null) out.close(); if(socket!=null){ socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } public void downloadFile(DataInputStream in, DataOutputStream out, File file) { try { String fileName = null; StringBuffer stringBuffer = new StringBuffer(); char c = '\\'; while ((c = in.readChar()) != '\\') { stringBuffer.append(c); } fileName = socket.getInetAddress() + "-" + stringBuffer.toString(); file = new File("e:\\back\\" + fileName); out.writeLong(file.length()); out = new DataOutputStream(new FileOutputStream(file, true)); int i = -1; byte[] buffer = new byte[1024]; while ((i = in.read(buffer)) != -1) { out.write(buffer, 0, i); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); if (out != null) out.close(); if(socket!=null){ socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } }}
[解决办法]
用JAVA写热备份???
很有创意的想法
第一印象觉得很不可思议;
仔细想想光从热备的要求上来说,上传的时候备份服务器同步处理信息应该可以!
再想想,不对,A都挂了,客户端怎么知道B是来接班的?
IP漂移,那就不是JAVA能干的事
就算JAVA能干,进行中的事务不可能完美过渡
你的文件假设在A机上传/下载了10个包,同时这些动作同步映射到B服务器;
这些过程中,客户端只联系A,而不管B,B上的信息是由A主动让B进行同步;
当A处理到第11个包的时候,挂了,却没有把第11个包的内容发送给B,而客户端的确是把包已经发送出去了,A也告诉它收到了,这时候你让B从哪里变出第11个包?
也许可以让服务器对数据进行颗粒化处理,颗粒有序编号,每个服务器都标明自己当前事务的处理进度,当B接管的时候回应客户端“你发给我的是12,我连11都还没有呢,从11开始”
还有很多想法,说不完了,高可用性不是纯粹用代码写出来的!!!
[解决办法]
像你这种情况,如果不是高度要求的服务;
你只要做到服务器确定你完成了整个上传下载过程的时候,正确告诉客户端,同时客户端再来个反馈,像TCP/IP的三次握手那样;
另外,一定要着重确保,服务器不保存发生错误的数据;
也就是保证事务是完整的,而不保证事务总是被执行;
即使现在数据库这么牛X的年代,一个SQL执行一半,机器挂了,也没那个厂商的数据库服务器能做到这个SQL非得给我执行完不可!!!