分布式系统即为若干网络互联的计算机组成的软件硬件系统,进行紧密配合完成一个共同的目标。
分布式计算即为定义在分布式系统上的计算。
经典的分布式系统项目。
WWW
SETI@home寻找外星人的项目
BIOINC项目
分布式系统具有可靠性,可拓展性,可用性,高效性。这是比较易于理解的。
CAP理论
即一致性,可用性和分区容忍性。
1C.一致性:在分布式系统中的所有的数据备份,在同一时刻是否具有同样的值。所有的客户端总是有相同的数据视图。
2A.可用性:每个客户端总是能进行读和写。
3P.分区容忍性:集群中某些节点无法联系的时候仍然能够正常提供服务。
CA结合的系统可拓展性能不好,比如关系数据库。因为如果不同地区的通信中断,如果要保持一致性,就必须设置成同步,但是又需要有可用性,所以必须把数据集中在一个位置。可拓展性能变差。
CP为了满足一致性,在系统分区期间会停止服务。
AP注重系统的性能和可拓展性,而不是强的一致性,在系统分区的时候可以使用异步的方法来进行服务。
分布式系统的核心技术为IPC,即为进程间通信。
IPC的一个难点是如何进行各个进程间的同步。
在这些过程中进行死锁的预防解除也是非常重要的。
进程间通信的范型。
Socket API
远程过程调用RPC
远程方法调用RMI
socket编程
对于无连接的socket api
发送者往往可以通过这种方式
DatagramSocket sk=new DatagramSocket();或者DatagramSocket sk=new DatagramSocket(port);
一种是任意可用的端口,一种是指定的端口
byte [] buffer =message.getbytes();
DatagramPacket datagram=new Datagram(buffer,buffer.leng,reveivehost,receiveport);
sk.send();
接受者的方式
DatagramSocket sk=new DatagramSocket(port);
一种是任意可用的端口,一种是指定的端口
byte [] buffer =new byte[max_len];
DatagramPacket datagram=new Datagram(buffer,max_len);
sk.receive();
在基本的socket api 中,不管是有连接还是无连接的,send是非阻塞的,而receive是阻塞的,send发送后可以做其他的内容,而receive调用之后就会被挂起,直到接受数据包为止。如果设置了超时的间隔,在这个事件内仍然没有接收到数据,就会引发io。InterupteIOException异常。
此外还有一些其他的方法比如void setSoTimeout(int timeout)以毫秒为单位设置超时的时间。用于阻塞该socket的接受操作。
其中需要注意的是发送者的数据包中需要包含目标地址,接受者创建的数据包中不需要包含目标地址。而发送者的socket对象可以不和特定的端口绑定,这样就会随机分配给它端口,但是接收者需要特定端口绑定。
在实际中需要防止接受者的接受内存溢出的问题,还有当发送者发送但是接收者的socket对象没有创建的时候,数据包可能会被丢弃。
在上个例子中 是单向的通信,但是也可以是双工的,需要将发送者的socket绑定到特定的地址上,从而接受者能够向发送者发送数据,自己实现一个MyDatagramSocket类。
面向连接数据包socket API
这个不太常用,流式socket是面向连接中更为常用的方法
主要多包含两个方法
public void connect(InetAddress address,int port);
public void disconnnect();
连接之后可以双方通信,因为是全双工的
接收数据使用MyDatagramSocket.receiveMessage();返回值即为信息。
发送数据使用MyDatagramSocket.sendMessage(sendhost,sendport,message);
流式Socket API
流式socket api提供了UNIX系统的流式IO的数据传输模式。它仅仅支持面向连接的通信。
一个流式的Socket不能同时和两个及其以上的进程通信。
有两个类提供了流式的socket api
Socket用于发送连接
SevertSocket用于接受连接
其中的过程大概为
连接请求者:
创建数据socket并且请求连接
获取用于向socket写数据的输出流对象
向流中写数据
获取用于向socket读数据的输入流对象
向流中读数据
关闭数据socket
例子:
SocketAddress sockadd=new InetSocketAddress(accepthost,accpetport);
Socket socket=new Socket(); 在指定的端口创建数据socket
socket.connect(sockadd,timeout);
InputStream instream=socket.getInputStream();
BufferReader socketInput=new BufferReader(new InputStreamReader(instream));
string message=socketInput.readLine();
socket.close();
连接侦听者:
创建连接socket监听连接请求
接收连接
创建数据socket,用于向socket中读写数据
获取用于向socket写数据的输出流对象
向流中写数据
获取用于向socket读数据的输入流对象
向流中读数据
例子:SevertSocket con=new SevertSocket(port);在指定的端口创建数据socket
Socket socket=con.accept();调用accept时会被挂起,接受连接的时候解除挂起状态。
OutputStream outputstram=socket.getoutputStream();
PrintWrite socketoutput=new PrintWrite(new OutputStreamWrite(outstream));
socketoutput.println(message);
socketoutput.flush();
socket.close();
con.close();
关注点:
处理的是数据流,可以使用PrintWrite,BufferReader来进行读写。
如果读写是一部分数据println readLine可以换成print和read
PrintWrite写数据的时候,必须使用flush()刷新数据流,确保在socket意外关闭之前可以尽快从数据缓冲区写到数据流中。
主流的分布式计算范型。
消息传递范型,包括send,receive,connect,disconnect基本操作。
客户机服务器范型
P2P范型
消息系统范型
点对点消息范型
发布/订阅消息范型。
远程过程调用范型
分布式对象范型,远程方法调用就是面向对象版本的RPC,其中对象请求代理是重要的内容。
网络服务范型,包括java的jini和web service是属于该范型的网络设施。
移动代理范型
云服务范型:
1,基础设施即服务,即通过提供虚拟的硬件资源服务。
2.平台即服务,提供应用程序编程接口服务,运行平台等
3.软件即服务。通过浏览器来使用软件
RMI范型
分布式对象范型
分布式对象范型是在消息传递模型上提供抽象的一种范型,用户可以使用它访问分布式对象,他是面向行为的,请求进程调用分布式的某个方法和操作,数据作为方法的参数传递,方法在远程主机上运行,结果作为返回值返回给请求进程。