TCP 半連接隊列和全連接隊列滿了會發生什麼?又該如何應對?_網頁設計

2{icon} {views}

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

前言

網上許多博客針對增大 TCP 半連接隊列和全連接隊列的方式如下:

  • 增大 TCP 半連接隊列的方式是增大 /proc/sys/net/ipv4/tcp_max_syn_backlog;
  • 增大 TCP 全連接隊列的方式是增大 listen() 函數中的 backlog;

這裏先跟大家說下,上面的方式都是不準確的。

“你怎麼知道不準確?”

很簡單呀,因為我做了實驗和看了 TCP 協議棧的內核源碼,發現要增大這兩個隊列長度,不是簡簡單單增大某一個參數就可以的。

接下來,就會以實戰 + 源碼分析,帶大家解密 TCP 半連接隊列和全連接隊列。

“源碼分析,那不是勸退嗎?我們搞 Java 的看不懂呀”

放心,本文的源碼分析不會涉及很深的知識,因為都被我刪減了,你只需要會條件判斷語句 if、左移右移操作符、加減法等基本語法,就可以看懂。

另外,不僅有源碼分析,還會介紹 Linux 排查半連接隊列和全連接隊列的命令。

“哦?似乎很有看頭,那我姑且看一下吧!”

行,沒有被勸退的小夥伴,值得鼓勵,下面這圖是本文的提綱:

本文提綱

正文

什麼是 TCP 半連接隊列和全連接隊列?

在 TCP 三次握手的時候,Linux 內核會維護兩個隊列,分別是:

  • 半連接隊列,也稱 SYN 隊列;
  • 全連接隊列,也稱 accepet 隊列;

服務端收到客戶端發起的 SYN 請求后,內核會把該連接存儲到半連接隊列,並向客戶端響應 SYN+ACK,接着客戶端會返回 ACK,服務端收到第三次握手的 ACK 后,內核會把連接從半連接隊列移除,然後創建新的完全的連接,並將其添加到 accept 隊列,等待進程調用 accept 函數時把連接取出來。

半連接隊列與全連接隊列

不管是半連接隊列還是全連接隊列,都有最大長度限制,超過限制時,內核會直接丟棄,或返回 RST 包。

實戰 – TCP 全連接隊列溢出

如何知道應用程序的 TCP 全連接隊列大小?

在服務端可以使用 ss 命令,來查看 TCP 全連接隊列的情況:

但需要注意的是 ss 命令獲取的 Recv-Q/Send-Q 在「LISTEN 狀態」和「非 LISTEN 狀態」所表達的含義是不同的。從下面的內核代碼可以看出區別:

在「LISTEN 狀態」時,Recv-Q/Send-Q 表示的含義如下:

  • Recv-Q:當前全連接隊列的大小,也就是當前已完成三次握手並等待服務端 accept() 的 TCP 連接;
  • Send-Q:當前全連接最大隊列長度,上面的輸出結果說明監聽 8088 端口的 TCP 服務,最大全連接長度為 128;

在「非 LISTEN 狀態」時,Recv-Q/Send-Q 表示的含義如下:

  • Recv-Q:已收到但未被應用進程讀取的字節數;
  • Send-Q:已發送但未收到確認的字節數;

如何模擬 TCP 全連接隊列溢出的場景?

測試環境

實驗環境:

  • 客戶端和服務端都是 CentOs 6.5 ,Linux 內核版本 2.6.32
  • 服務端 IP 192.168.3.200,客戶端 IP 192.168.3.100
  • 服務端是 Nginx 服務,端口為 8088

這裏先介紹下 wrk 工具,它是一款簡單的 HTTP 壓測工具,它能夠在單機多核 CPU 的條件下,使用系統自帶的高性能 I/O 機制,通過多線程和事件模式,對目標機器產生大量的負載。

本次模擬實驗就使用 wrk 工具來壓力測試服務端,發起大量的請求,一起看看服務端 TCP 全連接隊列滿了會發生什麼?有什麼觀察指標?

客戶端執行 wrk 命令對服務端發起壓力測試,併發 3 萬個連接:

在服務端可以使用 ss 命令,來查看當前 TCP 全連接隊列的情況:

其間共執行了兩次 ss 命令,從上面的輸出結果,可以發現當前 TCP 全連接隊列上升到了 129 大小,超過了最大 TCP 全連接隊列。

當超過了 TCP 最大全連接隊列,服務端則會丟掉後續進來的 TCP 連接,丟掉的 TCP 連接的個數會被統計起來,我們可以使用 netstat -s 命令來查看:

上面看到的 41150 times ,表示全連接隊列溢出的次數,注意這個是累計值。可以隔幾秒鐘執行下,如果這個数字一直在增加的話肯定全連接隊列偶爾滿了。

從上面的模擬結果,可以得知,當服務端併發處理大量請求時,如果 TCP 全連接隊列過小,就容易溢出。發生 TCP 全連接隊溢出的時候,後續的請求就會被丟棄,這樣就會出現服務端請求數量上不去的現象。

全連接隊列溢出

Linux 有個參數可以指定當 TCP 全連接隊列滿了會使用什麼策略來回應客戶端。

實際上,丟棄連接只是 Linux 的默認行為,我們還可以選擇向客戶端發送 RST 複位報文,告訴客戶端連接已經建立失敗。

tcp_abort_on_overflow 共有兩個值分別是 0 和 1,其分別表示:

  • 0 :如果全連接隊列滿了,那麼 server 扔掉 client 發過來的 ack ;
  • 1 :如果全連接隊列滿了,server 發送一個 reset 包給 client,表示廢掉這個握手過程和這個連接;

如果要想知道客戶端連接不上服務端,是不是服務端 TCP 全連接隊列滿的原因,那麼可以把 tcp_abort_on_overflow 設置為 1,這時如果在客戶端異常中可以看到很多 connection reset by peer 的錯誤,那麼就可以證明是由於服務端 TCP 全連接隊列溢出的問題。

通常情況下,應當把 tcp_abort_on_overflow 設置為 0,因為這樣更有利於應對突發流量。

舉個例子,當 TCP 全連接隊列滿導致服務器丟掉了 ACK,與此同時,客戶端的連接狀態卻是 ESTABLISHED,進程就在建立好的連接上發送請求。只要服務器沒有為請求回復 ACK,請求就會被多次重發。如果服務器上的進程只是短暫的繁忙造成 accept 隊列滿,那麼當 TCP 全連接隊列有空位時,再次接收到的請求報文由於含有 ACK,仍然會觸發服務器端成功建立連接。

所以,tcp_abort_on_overflow 設為 0 可以提高連接建立的成功率,只有你非常肯定 TCP 全連接隊列會長期溢出時,才能設置為 1 以儘快通知客戶端。

如何增大 TCP 全連接隊列呢?

是的,當發現 TCP 全連接隊列發生溢出的時候,我們就需要增大該隊列的大小,以便可以應對客戶端大量的請求。

TCP 全連接隊列足最大值取決於 somaxconn 和 backlog 之間的最小值,也就是 min(somaxconn, backlog)。從下面的 Linux 內核代碼可以得知:

  • somaxconn 是 Linux 內核的參數,默認值是 128,可以通過 /proc/sys/net/core/somaxconn 來設置其值;
  • backloglisten(int sockfd, int backlog) 函數中的 backlog 大小,Nginx 默認值是 511,可以通過修改配置文件設置其長度;

前面模擬測試中,我的測試環境:

  • somaxconn 是默認值 128;
  • Nginx 的 backlog 是默認值 511

所以測試環境的 TCP 全連接隊列最大值為 min(128, 511),也就是 128,可以執行 ss 命令查看:

現在我們重新壓測,把 TCP 全連接隊列搞大,把 somaxconn 設置成 5000:

接着把 Nginx 的 backlog 也同樣設置成 5000:

最後要重啟 Nginx 服務,因為只有重新調用 listen() 函數 TCP 全連接隊列才會重新初始化。

重啟完后 Nginx 服務后,服務端執行 ss 命令,查看 TCP 全連接隊列大小:

從執行結果,可以發現 TCP 全連接最大值為 5000。

增大 TCP 全連接隊列后,繼續壓測

客戶端同樣以 3 萬個連接併發發送請求給服務端:

服務端執行 ss 命令,查看 TCP 全連接隊列使用情況:

從上面的執行結果,可以發現全連接隊列使用增長的很快,但是一直都沒有超過最大值,所以就不會溢出,那麼 netstat -s 就不會有 TCP 全連接隊列溢出個數的显示:

說明 TCP 全連接隊列最大值從 128 增大到 5000 后,服務端抗住了 3 萬連接併發請求,也沒有發生全連接隊列溢出的現象了。

如果持續不斷地有連接因為 TCP 全連接隊列溢出被丟棄,就應該調大 backlog 以及 somaxconn 參數。

實戰 – TCP 半連接隊列溢出

如何查看 TCP 半連接隊列長度?

很遺憾,TCP 半連接隊列長度的長度,沒有像全連接隊列那樣可以用 ss 命令查看。

但是我們可以抓住 TCP 半連接的特點,就是服務端處於 SYN_RECV 狀態的 TCP 連接,就是在 TCP 半連接隊列。

於是,我們可以使用如下命令計算當前 TCP 半連接隊列長度:

如何模擬 TCP 半連接隊列溢出場景?

模擬 TCP 半連接溢出場景不難,實際上就是對服務端一直發送 TCP SYN 包,但是不回第三次握手 ACK,這樣就會使得服務端有大量的處於 SYN_RECV 狀態的 TCP 連接。

這其實也就是所謂的 SYN 洪泛、SYN 攻擊、DDos 攻擊。

測試環境

實驗環境:

  • 客戶端和服務端都是 CentOs 6.5 ,Linux 內核版本 2.6.32
  • 服務端 IP 192.168.3.200,客戶端 IP 192.168.3.100
  • 服務端是 Nginx 服務,端口為 8088

注意:本次模擬實驗是沒有開啟 tcp_syncookies,關於 tcp_syncookies 的作用,後續會說明。

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

本次實驗使用 hping3 工具模擬 SYN 攻擊:

當服務端受到 SYN 攻擊后,連接服務端 ssh 就會斷開了,無法再連上。只能在服務端主機上執行查看當前 TCP 半連接隊列大小:

同時,還可以通過 netstat -s 觀察半連接隊列溢出的情況:

上面輸出的數值是累計值,表示共有多少個 TCP 連接因為半連接隊列溢出而被丟棄。隔幾秒執行幾次,如果有上升的趨勢,說明當前存在半連接隊列溢出的現象

大部分人都說 tcp_max_syn_backlog 是指定半連接隊列的大小,是真的嗎?

很遺憾,半連接隊列的大小並不單單隻跟 tcp_max_syn_backlog 有關係。

上面模擬 SYN 攻擊場景時,服務端的 tcp_max_syn_backlog 的默認值如下:

但是在測試的時候發現,服務端最多只有 256 個半連接隊列,而不是 512,所以半連接隊列的最大長度不一定由 tcp_max_syn_backlog 值決定的

接下來,走進 Linux 內核的源碼,來分析 TCP 半連接隊列的最大值是如何決定的。

TCP 第一次握手(收到 SYN 包)的 Linux 內核代碼如下,其中縮減了大量的代碼,只需要重點關注 TCP 半連接隊列溢出的處理邏輯:

從源碼中,我可以得出共有三個條件因隊列長度的關係而被丟棄的:

  1. 如果半連接隊列滿了,並且沒有開啟 tcp_syncookies,則會丟棄;
  2. 若全連接隊列滿了,且沒有重傳 SYN+ACK 包的連接請求多於 1 個,則會丟棄;
  3. 如果沒有開啟 tcp_syncookies,並且 max_syn_backlog 減去 當前半連接隊列長度小於 (max_syn_backlog >> 2),則會丟棄;

關於 tcp_syncookies 的設置,後面在詳細說明,可以先給大家說一下,開啟 tcp_syncookies 是緩解 SYN 攻擊其中一個手段。

接下來,我們繼續跟一下檢測半連接隊列是否滿的函數 inet_csk_reqsk_queue_is_full 和 檢測全連接隊列是否滿的函數 sk_acceptq_is_full :

從上面源碼,可以得知:

  • 連接隊列的最大值是 sk_max_ack_backlog 變量,sk_max_ack_backlog 實際上是在 listen() 源碼里指定的,也就是 min(somaxconn, backlog)
  • 連接隊列的最大值是 max_qlen_log 變量,max_qlen_log 是在哪指定的呢?現在暫時還不知道,我們繼續跟進;

我們繼續跟進代碼,看一下是哪裡初始化了半連接隊列的最大值 max_qlen_log:

從上面的代碼中,我們可以算出 max_qlen_log 是 8,於是代入到 檢測半連接隊列是否滿的函數 reqsk_queue_is_full :

也就是 qlen >> 8 什麼時候為 1 就代表半連接隊列滿了。這計算這不難,很明顯是當 qlen 為 256 時,256 >> 8 = 1

至此,總算知道為什麼上面模擬測試 SYN 攻擊的時候,服務端處於 SYN_RECV 連接最大隻有 256 個。

可見,半連接隊列最大值不是單單由 max_syn_backlog 決定,還跟 somaxconn 和 backlog 有關係。

在 Linux 2.6.32 內核版本,它們之間的關係,總體可以概況為:

  • 當 max_syn_backlog > min(somaxconn, backlog) 時, 半連接隊列最大值 max_qlen_log = min(somaxconn, backlog) * 2;
  • 當 max_syn_backlog < min(somaxconn, backlog) 時, 半連接隊列最大值 max_qlen_log = max_syn_backlog * 2;

半連接隊列最大值 max_qlen_log 就表示服務端處於 SYN_REVC 狀態的最大個數嗎?

依然很遺憾,並不是。

max_qlen_log 是理論半連接隊列最大值,並不一定代表服務端處於 SYN_REVC 狀態的最大個數。

在前面我們在分析 TCP 第一次握手(收到 SYN 包)時會被丟棄的三種條件:

  1. 如果半連接隊列滿了,並且沒有開啟 tcp_syncookies,則會丟棄;
  2. 若全連接隊列滿了,且沒有重傳 SYN+ACK 包的連接請求多於 1 個,則會丟棄;
  3. 如果沒有開啟 tcp_syncookies,並且 max_syn_backlog 減去 當前半連接隊列長度小於 (max_syn_backlog >> 2),則會丟棄;

假設條件 1 當前半連接隊列的長度 「沒有超過」理論的半連接隊列最大值 max_qlen_log,那麼如果條件 3 成立,則依然會丟棄 SYN 包,也就會使得服務端處於 SYN_REVC 狀態的最大個數不會是理論值 max_qlen_log。

似乎很難理解,我們繼續接着做實驗,實驗見真知。

服務端環境如下:

配置完后,服務端要重啟 Nginx,因為全連接隊列最大和半連接隊列最大值是在 listen() 函數初始化。

根據前面的源碼分析,我們可以計算出半連接隊列 max_qlen_log 的最大值為 256:

客戶端執行 hping3 發起 SYN 攻擊:

服務端執行如下命令,查看處於 SYN_RECV 狀態的最大個數:

可以發現,服務端處於 SYN_RECV 狀態的最大個數並不是 max_qlen_log 變量的值。

這就是前面所說的原因:如果當前半連接隊列的長度 「沒有超過」理論半連接隊列最大值 max_qlen_log,那麼如果條件 3 成立,則依然會丟棄 SYN 包,也就會使得服務端處於 SYN_REVC 狀態的最大個數不會是理論值 max_qlen_log。

我們來分析一波條件 3 :

從上面的分析,可以得知如果觸發「當前半連接隊列長度 > 192」條件,TCP 第一次握手的 SYN 包是會被丟棄的。

在前面我們測試的結果,服務端處於 SYN_RECV 狀態的最大個數是 193,正好是觸發了條件 3,所以處於 SYN_RECV 狀態的個數還沒到「理論半連接隊列最大值 256」,就已經把 SYN 包丟棄了。

所以,服務端處於 SYN_RECV 狀態的最大個數分為如下兩種情況:

  • 如果「當前半連接隊列」沒超過「理論半連接隊列最大值」,但是超過 max_syn_backlog – (max_syn_backlog >> 2),那麼處於 SYN_RECV 狀態的最大個數就是 max_syn_backlog – (max_syn_backlog >> 2);
  • 如果「當前半連接隊列」超過「理論半連接隊列最大值」,那麼處於 SYN_RECV 狀態的最大個數就是「理論半連接隊列最大值」;

每個 Linux 內核版本「理論」半連接最大值計算方式會不同。

在上面我們是針對 Linux 2.6.32 版本分析的「理論」半連接最大值的算法,可能每個版本有些不同。

比如在 Linux 5.0.0 的時候,「理論」半連接最大值就是全連接隊列最大值,但依然還是有隊列溢出的三個條件:

如果 SYN 半連接隊列已滿,只能丟棄連接嗎?

並不是這樣,開啟 syncookies 功能就可以在不使用 SYN 半連接隊列的情況下成功建立連接,在前面我們源碼分析也可以看到這點,當開啟了 syncookies 功能就不會丟棄連接。

syncookies 是這麼做的:服務器根據當前狀態計算出一個值,放在己方發出的 SYN+ACK 報文中發出,當客戶端返回 ACK 報文時,取出該值驗證,如果合法,就認為連接建立成功,如下圖所示。

開啟 syncookies 功能

syncookies 參數主要有以下三個值:

  • 0 值,表示關閉該功能;
  • 1 值,表示僅當 SYN 半連接隊列放不下時,再啟用它;
  • 2 值,表示無條件開啟功能;

那麼在應對 SYN 攻擊時,只需要設置為 1 即可:

如何防禦 SYN 攻擊?

這裏給出幾種防禦 SYN 攻擊的方法:

  • 增大半連接隊列;
  • 開啟 tcp_syncookies 功能
  • 減少 SYN+ACK 重傳次數

方式一:增大半連接隊列

在前面源碼和實驗中,得知要想增大半連接隊列,我們得知不能只單純增大 tcp_max_syn_backlog 的值,還需一同增大 somaxconn 和 backlog,也就是增大全連接隊列。否則,只單純增大 tcp_max_syn_backlog 是無效的。

增大 tcp_max_syn_backlog 和 somaxconn 的方法是修改 Linux 內核參數:

增大 backlog 的方式,每個 Web 服務都不同,比如 Nginx 增大 backlog 的方法如下:

最後,改變了如上這些參數后,要重啟 Nginx 服務,因為半連接隊列和全連接隊列都是在 listen() 初始化的。

方式二:開啟 tcp_syncookies 功能

開啟 tcp_syncookies 功能的方式也很簡單,修改 Linux 內核參數:

方式三:減少 SYN+ACK 重傳次數

當服務端受到 SYN 攻擊時,就會有大量處於 SYN_REVC 狀態的 TCP 連接,處於這個狀態的 TCP 會重傳 SYN+ACK ,當重傳超過次數達到上限后,就會斷開連接。

那麼針對 SYN 攻擊的場景,我們可以減少 SYN+ACK 的重傳次數,以加快處於 SYN_REVC 狀態的 TCP 連接斷開。

巨人的肩膀

[1] 系統性能調優必知必會.陶輝.極客時間.

[2] https://www.cnblogs.com/zengkefu/p/5606696.html

[3] https://blog.cloudflare.com/syn-packet-handling-in-the-wild/

小林是專為大家圖解的工具人,Goodbye,我們下次見!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

一篇文章,全面掌握Git_貨運

1{icon} {views}

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

版本控制

版本控制就是記錄項目文件的歷史變化。它為我們查閱日誌回退協作等方面提供了有力的幫助。

版本控制一般分為集中化版本控制和分佈式版本控制。

集中化主要的版本數據都保存服務端。

分佈式版本數據分散在多端。

Git

Git屬於分佈式版本控制,也是現在比較流行的一種版本管理工具。

Git項目有三個區塊:工作區 / 暫存區 / 版本庫

  • 工作區存放從版本庫提取出來的文件,供我們編輯修改;
  • 暫存區保存了下一次要提交的目錄信息;
  • 版本庫保存項目版本元數據和Objects數據,後文會詳解。

Git工作流程

# 下載
<<==== clone 
# 上傳
====>> add ====>> commit ====>> push
# 更新
<<==== merge|rebase <<===== fetch

區分 Pull vs Fetch

我們將一個更新操作拆分為數據更新+合併處理兩部分,這樣來看 fetch 只是進行數據更新。而pull 其實是 ( fetch + (merge|rebase) )組合操作,它執行數據更新同時執行合併處理。pull 默認是fetch+merge 組合 ,也可以通過參數 –rebase 指定為 fetch + rebase。

區分Merge vs Rebase

合併處理是Git很重要的一塊知識。兩個命令在工作中也經常使用,區分它們對我們很有用。

場景如下

項目有一個mywork分支。C2時間點我和小明各自下載項目進行功能開發,小明效率比較高,先推送了C3 C4 到遠程倉庫。我本地倉庫現在有C5 C6兩個提交,要推送到遠程倉庫,需先同步遠程倉庫版本。

如果通過 fetch + merge 方式,Git會將遠程最新(C4)和本地最新(C6)進行合併併產生一個新的(C7)。

衝突處理步驟

git merge # 發生衝突會出現衝突標記
“<<<<<<< HEAD
40
=======
41
>>>>>>> 41”
# 手動處理衝突
git add .
git commit -m 'fix conflict'
git push origin HEAD

如果通過 fetch + rebase 方式,git會先將C5 C6存儲到.git/rebase零時目錄,合併成功后刪除。

衝突處理步驟

git rebase # 發生衝突會出現衝突標記
“<<<<<<< HEAD
40
=======
41
>>>>>>> 41”
# 手動處理衝突
git add .
git rebase --continue
git push origin HEAD

小結

git merge 會產生大量Merge日誌,可能會對查看帶來不便。不過大家還是根據實際情況進行選取。

關於撤銷回退幾種場景

提交后發現有文件漏了,又不想提交兩次。此時通過 “git commit –amend” 可以合併為一個提交。

git commit -m 'initial commit'
git add .gitignore
git commit --amend

如果文件想撤回且尚未提交,執行下面命令撤出暫存空間(index)

git reset HEAD <file>...

關於 reset 其它用法

# 重置到指定版本,之前提交內容將丟失
git reset --hard HEAD 
# 重置到指定版本,保留更改的文件但未標記為提交
git reset --mixed HEAD 
# 重置到指定版本,保留所有改動文件
git reset –soft HEAD 

特別注意 當你使用 “git reset –hard HEAD” 重置到某一版本,發現搞錯了想回退。這時你可能會執行“git log”,但是發現已經沒有以前的版本記錄,怎麼辦?送你一瓶後悔葯如下

# reflog 是Git操作的全日誌記錄
git reflog

6241462 (HEAD -> master) HEAD@{0}: reset: moving to 6241462
ea9b5ab HEAD@{1}: reset: moving to ea9b5ab
6241462 (HEAD -> master) HEAD@{2}: commit: Hello
34cd1e3 HEAD@{3}: commit: 3
ea9b5ab HEAD@{4}: commit: 2
729a8b1 (origin/master) HEAD@{5}: commit (initial): 1

# 找到最左邊對應hash值就可以回退到任意位置
git reset --hard {index}

如果想撤迴文件修改內容且文件尚未提交,執行下面命令

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

git checkout -- <file>

如果創建的分支名稱需要更改

git branch -m old new

# 如果分支已經推送到遠程,先刪除再推送新分支
git push origin --delete old
git push origin new

如果需要撤回的提交已經推送到了遠程倉庫,那麼補救的方式只有創建新的提交。

可以利用revert快速撤回到需要回退的版本。

# 還原最近一個提交
git revert HEAD
# 還原倒數第二個
git revert HEAD^
# 還原倒數第第四個
git revert HEAD~3

版本庫 Objects

這一節介紹一下Git版本庫的存儲模型。

項目歷史變動信息都記錄在object文件。文件名稱是通過哈希算法 ( 這裡是SHA1(對象內容) ) 產生的40位字符。

這種做法的一個優點就是“在對比兩對象是否相同時,只需要比較文件名稱就能迅速得出結果”

哈希算法:簡單來說就是向函數輸入一些內容,輸出長度固定的字符串。這裏SHA1函數固定輸出40長度字符。

object文件分 blob tree commit tag 四種類型

  • blob 存儲文件數據,一般是一個文件;

  • tree 存儲目錄和樹的引用(子文件目錄);

  • commit 存儲單一樹引用,時間點,提交作者,上一次提交指針;

  • tag 標記特定的commit 比如說發版。

特別注意:Subversion,CVS,Perforce,Mercurial等是存儲前後兩次提交的差異數據。Gi-每次提交時,它都會以樹狀結構存儲項目中所有文件的外觀快照。

Blob

Blob 是二進制數據塊,不會引用其它東西。如果目錄樹(或存儲庫中多個不同版本)中的兩個文件具有內容相同,它們將共享相同的Blob對象。

Tree

Tree 存儲blob和tree的引用。

# 我查詢 add1a1306e20...
git ls-tree add1a1306e20...

100644 blob 4661b39c3460a5c1f9e9309e6341962e0499b037	README.md
040000 tree ad46b24a4b0648ede3ca090dde32c89b89f7f2c1	src
...

Commit

Commit 包含下面幾個信息

  1. tree 提交時間點的目錄;
  2. parent 上一個提交;
  3. author 提交人;
git show -s --pretty=raw add1a1306e....

commit add1a1306e....
tree 81d4e4271a56575da7f992dc0dfc72ff7ddff94c
parent cd397e4c373013b19825b857b43ad8f677607f5d
author lixingping <lixingping233@gmail.com> 1589783810 +0800
committer lixingping <lixingping233@gmail.com> 1589783810 +0800

Tag

git cat-file tag v_1.0

object 24d16acd6aa08f74556c7ce551fa571b4bfe4079
type commit
tag v_1.0
tagger lixingping <lixingping233@gmail.com> 1588591122 +0800

例子

假設項目目錄結構如下,我們進行一個初始提交。幾種文件關係如下圖

|-- read.txt
    --| lib
      --| hello.java

附上一些常用命令

生成SSH key

ssh-keygen -t rsa -b 4096 -C "email@example.com"
# 指定生成的文件
ssh-keygen -t rsa -b 4096 -C "email@example.com" -f ~/.ssh/id_rsa_example
# id_rsa_example.pub 粘貼遠程倉庫

# 配置多個遠程倉庫
touch ~/.ssh/config

#添加一下內容
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github

Host example.com
HostName example.com
User git
IdentityFile ~/.ssh/id_rsa_example

配置

git config –global user.name “xxx”
git config –global user.email “xxx@email.com“
git config --global core.autocrlf true # 建議配置 windows mac換行符不統一問題
git config --global core.editor vim # 配置默認編輯器
git config --global core.excludesfile ~/.gitignore_global # 配置全局忽略文件
git config –list # 查看配置信息

分支管理

git branch --list # 羅列本地所有分支
git branch --all  # 羅列本地和遠程所有分支
git branch -r     # 羅列遠程所有分支
git branch -v     # 显示各分支最後提交信息
git checkout <branch name> # 切換分支
git checkout -b <new branch name> # 創建新分支
git push origin <new branch name> # 推送新分支到遠程
git checkout -m <old branch> <new branch> # 重命名分支名稱
git branch -d <[list]branch name> # 刪除本地分支
git push origin --delete <branch name> # 刪除遠程分支

標籤管理

git tag -l # 羅列本地所有標籤
git show <tag name> # 显示指定標籤
git tag -a v_1.0.0 -m "備註" # 創建標籤
git push origin <tag name> # 推送標籤到遠程
git tag -d <tag name> # 刪除本地標籤
git push --delete origin <tag name> # 刪除遠程標籤

總結

工作多年以來一直在使用Git,但是對Git沒有一個系統了解,所以寫這篇文章歸整一下。

歡迎大家留言交流,一起學習分享!!!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

TechEmpower Web 框架性能第19輪測試結果正式發布,ASP.NET Core在主流框架中拔得頭籌_網頁設計公司

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

TechEmpower 第19輪編程語言框架性能排行榜2020年5月28日正式發布,詳見官方博客:https://www.techempower.com/blog/2020/05/28/framework-benchmarks-round-19/,TechEmpower基準測試有許多場景(也稱為測試類型),此次評測多了一個綜合評分選項,把擁有完整測試覆蓋的框架現在將具有綜合分數,這反映了測試項目類型的總體性能得分:JSON serialization, Single-query, Multi-query, Updates, Fortunes 和 Plaintext. 。對於每一輪,我們使每個測試類型的結果規範化,然後為每個測試類型應用主觀權重(例如,Fortunes的權重比 Plaintext 高,因為Fortunes 是一種更現實的測試類型)。asp.net core排第6名,asp.net 排名倒數第二,第103名, 微軟從倒數一路追趕到第一。

表上前綴T標籤表示精選的主流編程語言

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

  • 第1名 C++的drogon 9676分
  • 第2名 Rust的actix 9064分
  • 第6名 C#的ASP.NET Core 5659分
  • 第29名 Go的Chi 2229分
  • 第34名 Java的Spring 1867分
  • 第73名 Nodejs的Express 821分
  • 第94名 PHP的laravel 348分
  • 第103名 C#的老框架ASP.NET(倒數第2),43分

在主流的編程語言中ASP.NET Core 獲得了排名三的好成績,本次的測試的是ASP.NET Core 3.1, .NET 5 在生產任務調度方面還在繼續優化,相信未來性能還會繼續提升,具體可以關注:https://aka.ms/aspnet/benchmarks。

在當今無服務器和容器的時代,很高興看到行業競爭並在冷啟動和內存消耗方面進行艱難的測試,PlaintText單項排名很好的體現了這一項:

Fortunes測試類型是最有趣的,因為它包括使用對象關係映射器(ORM)和數據庫。這是Web應用程序/服務中的常見用例。以前版本的ASP.NET Core在這種情況下錶現不佳。由於堆棧和PostgreSQL驅動程序中的優化,ASP.NET Core 2.1得到了顯著改進, 3.1 版本又 提升到了27萬。 其他方案不太代表典型的應用程序。他們強調堆棧的特定方面。如果它們與您的用例緊密匹配,它們可能會很有趣。對於框架開發人員,他們幫助識別進一步優化堆棧的機會。 例如,考慮Plaintext方案。此方案涉及客戶端發送16個請求背靠背(流水線),服務器知道響應,而無需執行I / O操作或計算。這不代表典型的請求,但它是解析HTTP請求的良好壓力測試。 每個實現都有一個類。例如,ASP.NET Core Plaintext具有platform, micro和full 實現。full 的實現是使用MVC中間件。Micro實現在管道級實現,platform實現直接建立在Kestrel之上。雖然Platform 類提供了引擎功能強大的概念,但它不是用於應用程序開發人員編程的API。 基準測試結果包括Latency選項卡。一些實現每秒實現非常多的請求,但是以相當大的延遲成本。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

王箏發文爆料老公出軌:與小姑娘婚外戀4年謊話連篇_電子煙

桃園外送茶莊、喝茶吃宵夜首選

外送服務地區有台北、新北、桃園、中壢、新竹、台中、彰化、台南、高雄外送茶。給您尊榮般的浪漫享受!

      10月19日,曾演唱《我們都是好孩子》等歌曲的歌手王箏曝丈夫出軌,她表示丈夫在2016年就開始與一名年輕女子有着不正當的聯繫,到現在為止仍然保持着這種關係。因為考慮到孩子和家庭,她一直也沒有將離婚說出口,但是最近又發現丈夫與這名女子有聯繫,訂的機票剛好是去往該女子所在地,她也決定將這件事情說出來。不過目前這條微博已經刪除。

 

  王箏發文:

  我經常說,天吶,劇本都不敢這麼寫。可這就是人生。比編劇更殘忍的人生。

電子煙有爭議?真相解密

採用迷你陶瓷芯結構~發熱速度快~可重覆注油~耐用度及味道都是非常優秀 電量650mah , 支援1A MICRO USB 充電,約45分可充滿電唷

  從他們2016年裸聊被我發現,至今拖拖拉拉已經四年。我一次一次收到各種各樣的解釋,一次次在離婚邊緣把自己勸住,我不信一個小姑娘會真的愛比自己爸爸都老的傢伙,他再不堪,總還是我孩子們的父親,把臉撕的破破的,照顧孩子還需要低頭不見抬頭見,多尷尬。於是證據素材攢了一堆,我並沒告他們也沒寫出一首關於他倆怎樣沒底線的歌。 一開始猜他們就像告訴我的一樣,幾個月關係,然後變成一年,兩年,三年,不過真沒想到還真的有第四年。異地戀不容易,更何況是疫情期間的中美兩國。你們是真愛,我眼拙了。

  謊話都編出花了,還是沒抵過我的第六感。我這個從不查崗的人,出手就有,也是天賦。現在說出來,是不想再六七八九十次的給彼此留餘地,別難為你們再偷偷摸摸的過第五六七八九十年……… 老頭挺好的,姑娘,祝你們幸福。

  我會盡量把你們的照片P好看一點。在貴州和老頭好好玩,雖然他讓助理訂的去義務的飛機。飛機都能拐彎,你們一定也能天長地久。

   網站內容來源:中國娛樂網訊www.yule.com.cn

※那些年被包養的回憶實錄

超過35700名單身男女正在這裡找約會對象。Meeting-Girl讓你(妳)實現想像…

德信地產3.5億元競得南京江寧區1宗商住用地_桃園室內設計

※讓身體告訴你,怎麼選出好床墊!

超舒適腰枕,使腰部更服貼、坐感更舒適 菱格紋扶手造型設計,更顯現代沙拉質感

中國網地產訊 9月17日,南京9宗地塊集中出讓,最終德信地產集團有限公司以3.5億元競得NO.2020G49號地塊,樓麵價10083.12元/平。

地塊編號NO.2020G49,地塊名稱江寧區谷里街道安康路以北、經四路以東地塊,地塊位於南京江寧區,出讓面積2.96萬平,用途為商住用地,出讓年限為住宅七十年,商業四十年,容積率1.17,建築面積3.47萬平,起始價3.5億元。

※推薦十家桃園室內設計首選

室內設計是指為滿足一定的建造目的而進行的準備工作,對現有的建築物內部空間進行深加工的增值準備工作。目的是為了讓具體的物質材料在技術、經濟等方面,在可行性的有限條件下形成能夠成為合格產品的準備工作。

(責任編輯:楊昊岳)
相關閱讀:

中國網地產是中國互聯網新聞中心·中國網旗下地產頻道,是國內官方、權威、專業的國家重點新聞網站。以引導正確的行業輿論導向為己任,為行業上下游關聯企業、相關產業提供一個高效溝通與互動的優質平台。

※找到適合的床墊;每晚都能好眠!

底部採用高檔沙發施工法、S彈簧打底設計、比黑皮帶施工法更堅固耐用、坐感更棒

南京地產1.45億元競得南京2宗地塊_新古典家具

新古典家具價格?

技藝超群:我們的老師傅手工精緻雕刻經驗40餘年,為「職人」也。

中國網地產訊 9月17日,南京9宗地塊集中出讓,最終南京地產資源開發有限責任公司以總價1.45億元競得2宗。

地塊編號NO.2020G46,地塊名稱雨花台區賽虹橋街道小行材料庫地塊,地塊位於南京雨花台區,出讓面積1.56萬平,用途為商服用地,出讓年限四十年,容積率小於等於3,建築面積4.69萬平,起始價1.1億元,成交價1.1億元,成交樓麵價2340.61元/平。

※尋找客製化家具設計工廠?

工法多樣:貼箔(金箔、銀箔、皺褶香檳金/銀…)、烤漆(象牙白、鏡黑、祖母藍…),還有須歷經二十幾道複雜工序的優美裂紋漆以及精美彩繪。

地塊編號NO.2020G47,地塊名稱秦淮區晨光路以東(地鐵雨花門站南側)地塊,地塊位於南京秦淮區,出讓面積5476.68平,用途為商服用地,出讓年限四十年,容積率小於等於1.6,建築面積8762.69平,起始價3500萬元,成交價3500萬元,樓麵價3994.21元/平。

(責任編輯:楊昊岳)
相關閱讀:

中國網地產是中國互聯網新聞中心·中國網旗下地產頻道,是國內官方、權威、專業的國家重點新聞網站。以引導正確的行業輿論導向為己任,為行業上下游關聯企業、相關產業提供一個高效溝通與互動的優質平台。

※找尋優質家具工廠?

經驗豐富:從現代家具→新古典家具→特殊家具皆能生產製作。

大樹置業5.1億元競得南京江寧區1宗商住用地 溢價率2%_家具批發

※北部家具批發工廠特惠中

購買鑫沅家具均可保固一年,有著完整的售後服務。

中國網地產訊 9月17日,南京9宗地塊集中出讓,最終浙江大樹置業集團股份有限公司以5.1億元競得NO.2020G53號地塊,溢價率2%,樓麵價9390.26元/平。

地塊編號NO.2020G53,地塊名稱為江寧區湯山溫泉旅遊度假區泉都大街以南、經十路以東地塊,用地性質為商住混合用地,出讓面積2.71萬平,起始價5億元。

※找尋台北復刻家具廠商?

購買鑫沅家可享有特殊優惠的驚喜方案

(責任編輯:楊昊岳)
相關閱讀:

中國網地產是中國互聯網新聞中心·中國網旗下地產頻道,是國內官方、權威、專業的國家重點新聞網站。以引導正確的行業輿論導向為己任,為行業上下游關聯企業、相關產業提供一個高效溝通與互動的優質平台。

古典家具特價出清!

有口皆碑:主要外銷中東、歐美各國,台灣則承接批發、建商及設計案件並可零售。

德基廣場9800萬元競得南京棲霞區1宗藝術傳媒用地_復刻版家具

3{icon} {views}

家具訂製工廠在哪裡?

鑫沅家具專業製作客製化家具,是桃園市的家具工廠。

中國網地產訊 9月17日,南京9宗地塊集中出讓,最終德基廣場有限公司以9800萬元競得NO.2020G48號地塊,樓麵價2330.63元/平。

地塊編號NO.2020G48,地塊名稱為棲霞區仙林街道仙境路以東、羊山湖路以北地塊,用地性質為藝術傳媒用地,出讓年限四十年,容積率小於等於1,出讓面積4.2萬平,起始價9800萬元。

復刻版家具訂製首選

新古典家具不僅是一件家具,更是一種精緻的視覺藝術

(責任編輯:楊昊岳)
相關閱讀:

中國網地產是中國互聯網新聞中心·中國網旗下地產頻道,是國內官方、權威、專業的國家重點新聞網站。以引導正確的行業輿論導向為己任,為行業上下游關聯企業、相關產業提供一個高效溝通與互動的優質平台。

※哪裡有歐洲款家具訂製工廠?

“新古典家具” 跟 “古典家具” 不一樣,並非追求一味的復古呈現,而是物如其名『新』古典家具,在懷舊復古的款式中添加了現代化元素

亞東建設7.3億元競得南京江寧區1宗商住用地_空間規劃

※推薦現代家具設計工廠

鑫沅的老師傅已有40餘年精良的雕刻經驗,對於雕刻美感有較高要求的 “新古典家具” 而言,是一種不可多得的技藝

中國網地產訊 9月17日,南京9宗地塊集中出讓,最終江蘇亞東建設發展集團有限公司以7.3億元競得NO.2020G51號地塊,樓麵價6112.86元/平。

地塊編號NO.2020G51,地塊名稱為江寧區麒麟街道富瑞路以南、光華路以東地塊,用地性質為商辦混合用地、居住用地,出讓年限為住宅七十年,商業四十年,出讓面積4.06萬平,規劃面積4.17萬平,起始價7.3億元,最高限價8.8億元。

空間設計達人在哪裡?

鑫沅只有獨一無二的訂製手法,才能讓家具兼具舒適度與機能性和美學

(責任編輯:楊昊岳)
相關閱讀:

中國網地產是中國互聯網新聞中心·中國網旗下地產頻道,是國內官方、權威、專業的國家重點新聞網站。以引導正確的行業輿論導向為己任,為行業上下游關聯企業、相關產業提供一個高效溝通與互動的優質平台。

※找尋實用空間規劃大師

鑫沅總是不怕繁複工法等等困難,獨具匠心,創造出令人著迷的氛圍……。

南京18.33億元出讓6宗地塊 德信地產3.5億元競得1宗_新古典家具推薦

新古典家具推薦比價站

鑫沅家具工廠轉型設計新古典家具、復刻家具訂製、家具設計

中國網地產訊 9月17日,南京9宗地塊集中出讓,最終成交6宗地塊,3宗地塊競價中止,總成交價18.33億元。

最終德信地產集團有限公司以3.5億元競得NO.2020G49號地塊,樓麵價10083.12元/平。

地塊編號NO.2020G49,地塊名稱江寧區谷里街道安康路以北、經四路以東地塊,地塊位於南京江寧區,出讓面積2.96萬平,用途為商住用地,出讓年限為住宅七十年,商業四十年,容積率1.17,建築面積3.47萬平,起始價3.5億元。

最終南京地產資源開發有限責任公司以總價1.45億元競得2宗。

地塊編號NO.2020G46,地塊名稱雨花台區賽虹橋街道小行材料庫地塊,地塊位於南京雨花台區,出讓面積1.56萬平,用途為商服用地,出讓年限四十年,容積率小於等於3,建築面積4.69萬平,起始價1.1億元,成交價1.1億元,成交樓麵價2340.61元/平。

地塊編號NO.2020G47,地塊名稱秦淮區晨光路以東(地鐵雨花門站南側)地塊,地塊位於南京秦淮區,出讓面積5476.68平,用途為商服用地,出讓年限四十年,容積率小於等於1.6,建築面積8762.69平,起始價3500萬元,成交價3500萬元,樓麵價3994.21元/平。

※NO.1復刻家具推薦

鑫沅桃園第一家具設計

最終浙江大樹置業集團股份有限公司以5.1億元競得NO.2020G53號地塊,溢價率2%,樓麵價9390.26元/平。

地塊編號NO.2020G53,地塊名稱為江寧區湯山溫泉旅遊度假區泉都大街以南、經十路以東地塊,用地性質為商住混合用地,出讓面積2.71萬平,起始價5億元。

最終德基廣場有限公司以9800萬元競得NO.2020G48號地塊,樓麵價2330.63元/平。

地塊編號NO.2020G48,地塊名稱為棲霞區仙林街道仙境路以東、羊山湖路以北地塊,用地性質為藝術傳媒用地,出讓年限四十年,容積率小於等於1,出讓面積4.2萬平,起始價9800萬元。

最終江蘇亞東建設發展集團有限公司以7.3億元競得NO.2020G51號地塊,樓麵價6112.86元/平。

地塊編號NO.2020G51,地塊名稱為江寧區麒麟街道富瑞路以南、光華路以東地塊,用地性質為商辦混合用地、居住用地,出讓年限為住宅七十年,商業四十年,出讓面積4.06萬平,規劃面積4.17萬平,起始價7.3億元,最高限價8.8億元。

(責任編輯:楊昊岳)
相關閱讀:

中國網地產是中國互聯網新聞中心·中國網旗下地產頻道,是國內官方、權威、專業的國家重點新聞網站。以引導正確的行業輿論導向為己任,為行業上下游關聯企業、相關產業提供一個高效溝通與互動的優質平台。

家具批發推薦NO.1

鑫沅系列的家具產品,從沙發、面料、色彩和功能的無數種組合幻變,完美適應各種空間需求