看透 Spring MVC 源代碼分析與實踐 —— 網站基礎知識

網站架構及其演變過程

基礎結構

網絡傳輸分解方式:java

  • 標準的 OSI 參考模型sql

  • TCP/IP 參考模型數據庫

OSI-TCPIP

海量數據的解決方案

  • 緩存和頁面靜態化緩存

    • 緩存服務器

      • 經過程序直接保存在內存中網絡

      • 使用緩存框架 (Encache、Redis、Memcache)架構

    • 頁面靜態化併發

      • 使用模板技術生成(Velocity、FreeMaker等)框架

  • 數據庫優化socket

    • 表結構優化

    • SQL 語句優化

    • 分區

    • 分表

    • 索引優化

    • 使用存儲過程代替直接操做過程

  • 分離活躍數據

  • 批量讀取和延遲修改

  • 讀寫分離

read-write

  • 分佈式數據庫

sql-1

  • NoSQL 和 Hadoop

高併發的解決方案

  • 應用和靜態資源的分離:靜態文件(圖片、視頻、JS、CSS等)放在專門的服務器上

  • 頁面緩存(Nginx 服務器、Squid 服務器)

  • 集羣與分佈式

  • 反向代理

  • CDN

  • 底層優化:網絡傳輸協議

常見協議和標準

TCP/IP 協議

IP:查找地址,對應着國際互聯網

TCP:規範傳輸規則,對應着傳輸層

TCP 在傳輸以前會進行三次溝通,稱 「三次握手」,傳完數據斷開的時候要進行四次溝通,稱 「四次揮手」。

TCP 兩個序號,三個標誌位含義:

  • seq:表示所傳數據的序號。TCP 傳輸時每個字節都有一個序號,發送數據的時候會將數據的第一個序號發送給對方,接收方會按序號檢查是否接收完整了,若是沒接收完整就須要從新傳送,這樣就能夠保證數據的完整性。

  • ack:表示確認號。接收端用它來給發送端反饋已經成功接收到的數據信息,它的值爲但願接收的下一個數據包起始序號。

  • ACK:確認位,只有 ACK = 1 的時候 ack 才起做用。正常通訊時 ACK 爲 1,第一次發起請求時由於沒有須要確認接收的數據因此 ACK 爲 0。

  • SYN:同步位,用於在創建鏈接時同步序號。剛開始創建鏈接時並無歷史接收的數據,因此 ack 也就沒有辦法設置,這是按照正常的機制就沒法運行了,SYN 的做用就是解決這個問題的,當接收端接收到 SYN = 1 的報文時就會直接將 ack 設置爲接收到的 seq + 1 的值,注意這裏的值並非檢驗後設置的,而是根據 SYN 直接設置的,這樣正常的機制就能夠運行了,因此 SYN 叫同步位。SYN 會在前兩次握手時都爲 1,這是由於通訊的雙方的 ack 都須要設置一個初始值。

  • FIN:終止位,用來在數據傳輸完畢後釋放鏈接。

TCP

DNS 的設置

DNS 解析

參考域名設置,以下是我在騰訊雲域名的設置

dns

記錄類型:

A記錄: 將域名指向一個IPv4地址(例如:8.8.8.8)
CNAME:將域名指向另外一個域名(例如 www.54tianzhisheng.cn)
MX: 將域名指向郵件服務器地址
TXT: 可任意填寫,長度限制255,一般作SPF記錄(反垃圾郵件)
NS: 域名服務器記錄,將子域名指定其餘DNS服務器解析
AAAA:將域名指向一個iPv6地址(例如:ff06:0:0:0:0:0:0:c3)
SRV:記錄提供特定服務的服務器(例如_xmpp-server._tcp)
顯性URL:將域名301重定向到另外一個地址
隱性URL:相似顯性URL,可是會隱藏真實目標地址

主機記錄:

要解析 www.54tianzhisheng.cn,請填寫 www。
主機記錄就是域名前綴,常見用法有:

www: 解析後的域名爲 www.54tianzhisheng.cn。
@: 直接解析主域名 54tianzhisheng.cn。
: 泛解析,匹配其餘全部域名 .54tianzhisheng.cn。
mail: 將域名解析爲 mail.54tianzhisheng.cn,一般用於解析郵箱服務器。
二級域名: 如:abc.54tianzhisheng.cn,填寫abc。
手機網站: 如:m.54tianzhisheng.cn,填寫m。

Java 中 Socket 的用法

普通 Soket 的用法

Socket 分爲 ServerSocket 和 Socket 兩大類。

ServerSocket 用於服務器端,能夠經過 accept 方法監聽請求,監聽到請求後返回 Socket;

Socket 用戶具體完成數據傳輸,客戶端直接使用 Socket 發送請求並傳輸數據。

隨便寫了個單方面發送消息的 demo:

客戶端:

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

/**
 * Created by 10412 on 2017/5/2.
 * TCP客戶端:
 ①:創建tcp的socket服務,最好明確具體的地址和端口。這個對象在建立時,就已經能夠對指定ip和端口進行鏈接(三次握手)。
 ②:若是鏈接成功,就意味着通道創建了,socket流就已經產生了。只要獲取到socket流中的讀取流和寫入流便可,只要經過getInputStream和getOutputStream就能夠獲取兩個流對象。
 ③:關閉資源。
 */
//單方面的輸入!
public class TcpClient
{
    public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1", 9999);
            OutputStream o = s.getOutputStream();
            o.write("tcp sssss".getBytes());
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服務器端:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by 10412 on 2017/5/2.
 */
public class TcpServer
{
    public static void main(String[] args) {
        try {
            ServerSocket ss = new ServerSocket(9999);//創建服務端的socket服務
            Socket s = ss.accept();//獲取客戶端對象
            String ip = s.getInetAddress().getHostAddress();
            int port = s.getPort();
            System.out.println(ip + " : " + port + " connected");

            // 能夠經過獲取到的socket對象中的socket流和具體的客戶端進行通信。
            InputStream ins = s.getInputStream();//讀取客戶端的數據,使用客戶端對象的socket讀取流
            byte[] bytes = new byte[1024];
            int len = ins.read(bytes);
            String text = new String(bytes, 0, len);
            System.out.println(text);
            //關閉資源
            s.close();
            ss.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

NioSocket 的用法

見之前的一篇文章:Java NIO 系列教程

書中第五章簡單的講了下實現 HTTP 協議。第六章主要講 Servlet,寫了 Servlet 接口和其實現類。第七章把 Tomcat 分析的很不錯,若是有讀者感興趣的話,能夠去看看。

注:本文首發於zhisheng 的博客,可轉載但務必請註明原創地址爲:http://www.54tianzhisheng.cn/2017/07/14/Spring-MVC01/

相關文章
相關標籤/搜索