網站架構及其演變過程
友情提示:歡迎關註公眾號【芋道原始碼】。?關註後,拉你進【原始碼圈】微信群討論技術和原始碼。
友情提示:歡迎關註公眾號【芋道原始碼】。?關註後,拉你進【原始碼圈】微信群討論技術和原始碼。
友情提示:歡迎關註公眾號【芋道原始碼】。?關註後,拉你進【原始碼圈】微信群討論技術和原始碼。
基礎結構
網路傳輸分解方式:
-
標準的 OSI 參考模型
-
TCP/IP 參考模型
海量資料的解決方案
-
快取和頁面靜態化
-
快取
-
透過程式直接儲存在記憶體中
-
使用快取框架 (Encache、Redis、Memcache)
-
頁面靜態化
-
使用模板技術生成(Velocity、FreeMaker等)
-
資料庫最佳化
-
表結構最佳化
-
SQL 陳述句最佳化
-
分割槽
-
分表
-
索引最佳化
-
使用儲存過程代替直接操作過程
-
分離活躍資料
-
批次讀取和延遲修改
-
讀寫分離
-
分散式資料庫
-
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:終止位,用來在資料傳輸完畢後釋放連線。
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://www.54tianzhisheng.cn/2017/03/28/Java%20NIO%20%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8B/
書中第五章簡單的講了下實現 HTTP 協議。第六章主要講 Servlet,寫了 Servlet 介面和其實現類。第七章把 Tomcat 分析的很不錯,如果有讀者感興趣的話,可以去看看。