分布式系列二: 分布式系統的通信
通信是分布式架構的一個基本問題, 通信是基於通信協議, 通過網絡IO來實現的, 基本的通信協議有TCP,HTTP,UDP等, Java的IO分為BIO,NIO,AIO等, java領域有很多支持通信的技術, 如RMI,MINA,JMS等.
網絡協議
TCP/IP:
五層模型: 基於OSI七層模型. 包含: 應用層,傳輸層(TCP/IP協議),網絡層(ICMP,IGMP),鏈路層,物理層. OSI還包含表現層,會話層.
三次握手:
Dos攻擊就是在第三步發生, 發送大量連接請求, 使網絡處在半連接狀態. server端的連接未完成, 導致阻塞.
四次揮手:
TCP協議是全雙工的, 全雙工是雙方可以相互發起通信, 數據可以往兩個方向傳輸; 半雙工是某個階段只能一方傳輸; 單工是只能一方往另一方傳輸數據.
UDP/IP:
阻塞的概念
了解阻塞, 就首先需要了解TCP傳輸協議的緩存區概念.
應用層發送數據的時候, 首先數據會暫存到傳輸層的緩存區.
數據傳輸的時候有個滑動窗口的概念, 窗口的大小可以控制, 這樣可以保證接收方緩存區不夠大導致緩存溢出. 窗口的數據全部發送且接收方確認收到後才可以向前繼續滑動.
發送方和接收方均有緩存區, 當緩存區滿(或空, 分別對應寫和讀)的時候就會發生阻塞, 必須等緩存區有足夠空間容納更多數據的時候才能繼續發送或接收.
阻塞分為BIO(同步阻塞),NIO(同步非阻塞, 同路復用技術,netty等使用這種方式),AIO(異步非阻塞, java7開始)
阻塞和非阻塞, 同步和異步分開理解比較好.阻塞和非阻塞是針對調用者, 阻塞是緩沖區讀寫沒有數據的時候線程等待, 非阻塞是緩沖區讀寫沒有數據時立即返回, 線程去做其他的事情; 同步和異步是針對被調用者, 被調用者處理時不返回時, 調用者需要等待結果是同步, 被調用者立即返回,同時做處理時異步.
Java 網絡通信
TCP Socket通信
// 服務端 public class SocketServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; try{ serverSocket = new ServerSocket(8888); Socket socket= serverSocket.accept(); // 緩沖區讀取 BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println(reader.readLine()); reader.close(); socket.close(); }catch (Exception e){ }finally { if(serverSocket!=null){ serverSocket.close(); } } } } //客戶端 public class SocketClient { public static void main(String[] args) throws IOException { try{ Socket socket = new Socket("localhost",8888); PrintWriter writer = new PrintWriter(socket.getOutputStream(),true); writer.println("this is a message from client"); writer.close(); socket.close(); }catch (Exception e){ }finally { } } }
Multicast 多播, 使用UDP協議
// 服務端
public class MulticastServer {
public static void main(String[] args) throws IOException, InterruptedException {
// 多播必須是224網段
InetAddress group = InetAddress.getByName("224.7.8.9");
MulticastSocket socket = new MulticastSocket();
for (int i = 0; i < 10; i++) {
String data = "multcast"+i;
byte[] bytes = data.getBytes();
socket.send(new DatagramPacket(bytes,bytes.length,group,8888));
TimeUnit.SECONDS.sleep(2);
}
}
}
// 客戶端
public class MulticastClient {
public static void main(String[] args) throws IOException, InterruptedException {
// 多播必須是224網段
InetAddress group = InetAddress.getByName("224.7.8.9");
MulticastSocket socket = new MulticastSocket(8888);
socket.joinGroup(group);
byte[] buf = new byte[32];
while (true){
DatagramPacket packet = new DatagramPacket(buf,buf.length);
socket.receive(packet);
String reveived = new String(packet.getData());
System.out.println("received:"+reveived);
}
}
}
分布式系列二: 分布式系統的通信