1. 程式人生 > >分布式系列二: 分布式系統的通信

分布式系列二: 分布式系統的通信

rmi 異步 表現 圖片 傳輸層 基本 rgs pac 包含

通信是分布式架構的一個基本問題, 通信是基於通信協議, 通過網絡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);
        }
    }
}

分布式系列二: 分布式系統的通信