精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊聊NAT引發的性能瓶頸

網絡 通信技術
筆者最近解決了一個非常曲折的問題,從抓包開始一路排查到不同內核版本間的細微差異,最后才完美解釋了所有的現象。在這里將整個過程寫成博文記錄下來,希望能夠對讀者有所幫助。(篇幅可能會有點長,耐心看完,絕對物有所值~)

[[351617]]

讀者最近解決了一個非常曲折的問題,從抓包開始一路排查到不同內核版本間的細微差異,最后才完美解釋了所有的現象。在這里將整個過程寫成博文記錄下來,希望能夠對讀者有所幫助。(篇幅可能會有點長,耐心看完,絕對物有所值~)

環境介紹

先來介紹一下出問題的環境吧,調用拓撲如下圖所示:

調用拓撲圖

 

合作方的多臺機器用NAT將多個源ip映射成同一個出口ip 20.1.1.1,而我們內網將多個Nginx映射成同一個目的ip 30.1.1.1。這樣,在防火墻和LVS之間,所有的請求始終是通過(20.1.1.1,30.1.1.1)這樣一個ip地址對進行訪問。

同時還固定了一個參數,那就是目的端口號始終是443。

 

短連接-HTTP1.0

由于對方是采用短連接和Nginx進行交互的,而且采用的協議是HTTP-1.0。所以我們的Nginx在每個請求完成后,會主動關閉連接,從而造成有大量的TIME_WAIT。

 

值得注意的是,TIME_WAIT取決于Server端和Client端誰先關閉這個Socket。所以Nginx作為Server端先關閉的話,也必然會產生TIME_WAIT。

 

內核參數配置

內核參數配置如下所示:

  1. cat /proc/sys/net/ipv4/tcp_tw_reuse 0 
  2. cat /proc/sys/net/ipv4/tcp_tw_recycle 0 
  3. cat /proc/sys/net/ipv4/tcp_timestamps 1 

其中tcp_tw_recycle設置為0。這樣,可以有效解決tcp_timestamps和tcp_tw_recycle在NAT情況下導致的連接失敗問題。具體見筆者之前的博客:

  1. https://my.oschina.net/alchemystar/blog/3119992 

Bug現場

好了,介紹完環境,我們就可以正式描述Bug現場了。

Client端大量創建連接異常,而Server端無法感知

表象是合作方的應用出現大量的創建連接異常,而Server端確沒有任何關于這些異常的任何異常日志,仿佛就從來沒有出現過這些請求一樣。

 

LVS監控曲線

出現問題后,筆者翻了下LVS對應的監控曲線,其中有個曲線的變現非常的詭異。如下圖所示:

 

什么情況?看上去像建立不了連接了?但是雖然業務有大量的報錯,依舊有很高的訪問量,看日志的話,每秒請求應該在550向上!和這個曲線上面每秒只有30個新建連接是矛盾的!

每天發生的時間點非常接近

觀察了幾天后。發現,每天都在10點左右開始發生報錯,同時在12點左右就慢慢恢復。

 

感覺就像每天10點在做活動,導致流量超過了系統瓶頸,進而暴露出問題。而11:40之后,流量慢慢下降,系統才慢慢恢復。難道LVS這點量都撐不住?才550TPS啊?就崩潰了?

難道是網絡問題?

難道就是傳說中的網絡問題?看了下監控,流量確實增加,不過只占了將近1/8的帶寬,離打爆網絡還遠著呢。

 

進行抓包

不管三七二十一,先抓包吧!

抓包結果

在這里筆者給出一個典型的抓包結果:

 

序號 時間 源地址 目的地址 源端口號 目的端口號 信息
1 09:57:30.60 30.1.1.1 20.1.1.1 443 33735 [FIN,ACK]Seq=507,Ack=2195,TSval=1164446830
2 09:57:30.64 20.1.1.1 30.1.1.1 33735 443 [FIN,ACK]Seq=2195,Ack=508,TSval=2149756058
3 09:57:30.64 30.1.1.1 20.1.1.1 443 33735 [ACK]Seq=508,Ack=2196,TSval=1164446863
4 09:59:22.06 20.1.1.1 30.1.1.1 33735 443 [SYN]Seq=0,TSVal=21495149222
5 09:59:22.06 30.1.1.1 20.1.1.1 443 33735 [ACK]Seq=1,Ack=1487349876,TSval=1164558280
6 09:59:22.08 20.1.1.1 30.1.1.1 33735 443 [RST]Seq=1487349876

上面抓包結果如下圖所示,一開始33735->443這個Socket四次揮手。在將近兩分鐘后又使用了同一個33735端口和443建立連接,443給33735回了一個莫名其妙的Ack,導致33735發了RST!

 

現象是怎么產生的?

首先最可疑的是為什么發送了一個莫名其妙的Ack回來?筆者想到,這個Ack是WireShark給我計算出來的。為了我們方便,WireShark會根據Seq=0而調整Ack的值。事實上,真正的Seq是個隨機數!有沒有可能是WireShark在某些情況下計算錯誤?

還是看看最原始的未經過加工的數據吧,于是筆者將wireshark的

  1. Relative sequence numbers 

給取消了。取消后的抓包結果立馬就有意思了!調整過后抓包結果如下所示:

 

序號 時間 源地址 目的地址 源端口號 目的端口號 信息
1 09:57:30.60 30.1.1.1 20.1.1.1 443 33735 [FIN,ACK]Seq=909296387,Ack=1556577962,TSval=1164446830
2 09:57:30.64 20.1.1.1 30.1.1.1 33735 443 [FIN,ACK]Seq=1556577962,Ack=909296388,TSval=2149756058
3 09:57:30.64 30.1.1.1 20.1.1.1 443 33735 [ACK]Seq=909296388,Ack=1556577963,TSval=1164446863
4 09:59:22.06 20.1.1.1 30.1.1.1 33735 443 [SYN]Seq=69228087,TSVal=21495149222
5 09:59:22.06 30.1.1.1 20.1.1.1 443 33735 [ACK]Seq=909296388,Ack=1556577963,TSval=1164558280
6 09:59:22.08 20.1.1.1 30.1.1.1 33735 443 [RST]Seq=1556577963

看表中,四次揮手里面的Seq和Ack對應的值和三次回收中那個錯誤的ACK完全一致!也就是說,四次回收后,五元組并沒有消失,而是在111.5s內還存活著!按照TCPIP狀態轉移圖,只有TIME_WAIT狀態才會如此。

 

我們可以看看Linux關于TIME_WAIT處理的內核源碼:

  1. switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { 
  2. // 如果是TCP_TW_SYN,那么允許此SYN分節重建連接 
  3. // 即允許TIM_WAIT狀態躍遷到SYN_RECV 
  4. case TCP_TW_SYN: { 
  5.  struct sock *sk2 = inet_lookup_listener(dev_net(skb->dev), 
  6.       &tcp_hashinfo, 
  7.       iph->saddr, th->source, 
  8.       iph->daddr, th->dest, 
  9.       inet_iif(skb)); 
  10.  if (sk2) { 
  11.   inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); 
  12.   inet_twsk_put(inet_twsk(sk)); 
  13.   sk = sk2; 
  14.   goto process; 
  15.  } 
  16.  /* Fall through to ACK */ 
  17. // 如果是TCP_TW_ACK,那么,返回記憶中的ACK,這和我們的現象一致 
  18. case TCP_TW_ACK: 
  19.  tcp_v4_timewait_ack(sk, skb); 
  20.  break; 
  21. // 如果是TCP_TW_RST直接發送RESET包 
  22. case TCP_TW_RST: 
  23.  tcp_v4_send_reset(sk, skb); 
  24.  inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); 
  25.  inet_twsk_put(inet_twsk(sk)); 
  26.  goto discard_it; 
  27. // 如果是TCP_TW_SUCCESS則直接丟棄此包,不做任何響應 
  28. case TCP_TW_SUCCESS:; 
  29. goto discard_it; 

上面的代碼有兩個分支,值得我們注意,一個是TCP_TW_ACK,在這個分支下,返回TIME_WAIT記憶中的ACK和我們的抓包現象一模一樣。還有一個TCP_TW_SYN,它表明了在 TIME_WAIT狀態下,可以立馬重用此五元組,跳過2MSL而達到SYN_RECV狀態!

 

狀態的遷移就在于tcp_timewait_state_process這個函數,我們著重看下想要觀察的分支:

  1. enum tcp_tw_status 
  2. tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, 
  3.       const struct tcphdr *th) 
  4.  bool paws_reject = false
  5.  ...... 
  6.  paws_reject = tcp_paws_reject(&tmp_opt, th->rst); 
  7.  if (!paws_reject && 
  8.      (TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt && 
  9.       (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq || th->rst))) { 
  10.   ...... 
  11.   // 重復的ACK,discard此包 
  12.   return TCP_TW_SUCCESS; 
  13.  } 
  14.  // 如果是SYN分節,而且通過了paws校驗 
  15.  if (th->syn && !th->rst && !th->ack && !paws_reject && 
  16.      (after(TCP_SKB_CB(skb)->seq, tcptw->tw_rcv_nxt) || 
  17.       (tmp_opt.saw_tstamp && 
  18.        (s32)(tcptw->tw_ts_recent - tmp_opt.rcv_tsval) < 0))) { 
  19.   ...... 
  20.   // 返回TCP_TW_SYN,允許重用TIME_WAIT五元組重新建立連接 
  21.   return TCP_TW_SYN; 
  22.  } 
  23.  // 如果沒有通過paws校驗,則增加統計參數 
  24.  if (paws_reject) 
  25.   NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_PAWSESTABREJECTED); 
  26.  if (!th->rst) { 
  27.   // 如果沒有通過paws校驗,而且這個分節包含ack,則將TIMEWAIT持續時間重新延長 
  28.   // 我們抓包結果的結果沒有ACK,只有SYN,所以并不會延長 
  29.   if (paws_reject || th->ack) 
  30.    inet_twsk_schedule(tw, &tcp_death_row, TCP_TIMEWAIT_LEN, 
  31.         TCP_TIMEWAIT_LEN); 
  32.   // 返回TCP_TW_ACK,也即TCP重傳ACK到對面 
  33.   return TCP_TW_ACK; 
  34.  } 

根據上面源碼,PAWS(Protect Againest Wrapped Sequence numbers防止回繞)校驗機制如果生效而拒絕此分節的話,LINUX_MIB_PAWSESTABREJECTED這個統計參數會增加,對應于Linux中的命令即是:

  1. netstat -s | grep reject 
  2. 216576 packets rejects in established connections because of timestamp 

這么上去后端的Nginx一統計,果然有大量的報錯。而且根據筆者的觀察,這個統計參數急速增加的時間段就是出問題的時間段,也就是每天早上10:00-12:00左右。每次大概會增加1W多個統計參數。那么什么時候PAWS會不通過呢,我們直接看下tcp_paws_reject的源碼吧:

  1. static inline int tcp_paws_reject(const struct tcp_options_received *rx_opt, 
  2.       int rst) 
  3.  if (tcp_paws_check(rx_opt, 0)) 
  4.   return 0; 
  5.  // 如果是rst,則放松要求,60s沒有收到對端報文,認為PAWS檢測通過  
  6.  if (rst && get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_MSL) 
  7.   return 0; 
  8.  return 1; 
  9.  
  10. static inline int tcp_paws_check(const struct tcp_options_received *rx_opt, 
  11.      int paws_win) 
  12.  
  13.  // 如果ts_recent中記錄的上次報文(SYN)的時間戳,小于當前報文的時間戳(TSval),表明paws檢測通過 
  14.  // paws_win = 0 
  15.  if ((s32)(rx_opt->ts_recent - rx_opt->rcv_tsval) <= paws_win) 
  16.   return 1; 
  17.  // 否則,上一次獲得ts_recent時間戳的時刻的24天之后,為真表明已經有超過24天沒有接收到對端的報文了,認為PAWS檢測通過 
  18.  if (unlikely(get_seconds() >= rx_opt->ts_recent_stamp + TCP_PAWS_24DAYS)) 
  19.   return 1; 
  20.  
  21.  return 0; 

在抓包的過程中,我們明顯發現,在四次揮手時候,記錄的tsval是2149756058,而下一次syn三次握手的時候是21495149222,反而比之前的小了!

序號 時間 源地址 目的地址 源端口號 目的端口號 信息
2 09:57:30.64 20.1.1.1 30.1.1.1 33735 443 [FIN,ACK]TSval=2149756058
4 09:59:22.06 20.1.1.1 30.1.1.1 33735 443 [SYN]TSVal=21495149222

所以PAWS校驗不過。那么為什么會這個SYN時間戳比之前揮手的時間戳還小呢?那當然是NAT的鍋嘍,NAT把多臺機器的ip虛擬成同一個ip。但是多臺機器的時間戳(也即從啟動開始到現在的時間,非墻上時間),如下圖所示:

 

但是還有一個疑問,筆者記得TIME_WAIT也即2MSL在Linux的代碼里面是定義為了60s。為何抓包的結果卻存活了將近2分鐘之久呢?

TIME_WAIT的持續時間

于是筆者開始閱讀器關于TIME_WAIT定時器的源碼,具體可見筆者的另一篇博客:

  1. 從Linux源碼看TIME_WAIT狀態的持續時間 
  2. https://my.oschina.net/alchemystar/blog/4690516 

結論如下

在TIME_WAIT很多的狀態下,TIME_WAIT能夠存活112.5s,將近兩分鐘的時間,和我們的抓包結果一致。當然了,這個計算只是針對Linux 2.6和3.10內核而言,而對紅帽維護的3.10.1127內核版本則會有另外的變化,這個變化導致了一個令筆者感到非常奇異的現象,這個在后面會提到。

 

問題發生條件

如上面所解釋,只有在Server端TIME_WAIT還沒有消失時候,重用這個Socket的時候,遇上了反序的時間戳SYN,就會發生這種問題。由于NAT前面的所有機器時間戳都不相同,所以有很大概率會導致時間戳反序!

那么什么時候重用TIME_WAIT狀態的Socket呢

筆者知道,防火墻的端口號選擇邏輯是RoundRobin的,也即從2048開始一直增長到65535,再回繞到2048,如下圖所示:

 

為什么壓測的時候不出現問題

但我們在線下壓測的時候,明顯速率遠超560tps,那為何確沒有這樣的問題出現呢。很簡單,是因為 TCP_SYN_SUCCESS這個分支,由于我們的壓測機沒有過NAT,那么時間戳始終保持單IP下的單調遞增,即便>560TPS之后,走的也是TCP_SYN_SUCCESS,將TIME_WAIT Socket重用為SYN_RECV,自然不會出現這樣的問題,如下圖所示:

 

如何解釋LVS的監控曲線?

等等,564TPS?這個和LVS陡然下跌的TPS基本相同!難道在端口號復用之后LVS就不會新建連接(其實是LVS中的session表項)?從而導致統計參數并不增加?

于是筆者直接去擼了一下LVS的源碼:

  1. tcp_conn_schedule 
  2.   |->ip_vs_schedule 
  3.    /* 如果新建conn表項成功,則對已有連接數++ */ 
  4.    |->ip_vs_conn_stats 
  5. 而在我們的入口函數ip\_vs\_in中 
  6. static unsigned int 
  7. ip_vs_in(unsigned int hooknum, struct sk_buff *skb, 
  8.   const struct net_device *in, const struct net_device *out
  9.   int (*okfn) (struct sk_buff *)) 
  10.  ...... 
  11.  // 如果能找到對應的五元組 
  12.  cp = pp->conn_in_get(af, skb, pp, &iph, iph.len, 0, &res_dir); 
  13.  
  14.  if (likely(cp)) { 
  15.   /* For full-nat/local-client packets, it could be a response */ 
  16.   if (res_dir == IP_VS_CIDX_F_IN2OUT) { 
  17.    return handle_response(af, skb, pp, cp, iph.len); 
  18.   } 
  19.  } else { 
  20.   /* create a new connection */ 
  21.   int v; 
  22.   // 找不到對應的五元組,則新建連接,同時conn++ 
  23.   if (!pp->conn_schedule(af, skb, pp, &v, &cp)) 
  24.    return v; 
  25.  } 
  26.  ...... 

很明顯的,如果當前五元組表項存在,則直接復用表項,而不存在,才創建新的表項,同時conn++。而表項需要在LVS的Fintimeout時間超過后才消失(在筆者的環境里面是120s)。這樣,在端口號復用的時候,因為<112.5s,所以LVS會直接復用表項,而統計參數不會有任何變化,從而導致了下面這個曲線。

 

當流量慢慢變小,無法達到重用端口號的條件的時候,曲線又會垂直上升。和筆者的推測一致。也就是說在五元組固定四元的情況下>529tps(63487/120)的時候,在此固定業務下的新建連接數不會增加。

而圖中僅存的560-529=>21+個連接創建,是由另一個業務的vip引起,在這個vip上,由于量很小,沒有端口復用。但是LVS統計的是總數量,所以在端口號開始復用之后,始終會有少量的新建連接存在。

值得注意的是,端口號復用之后,LVS轉發的時候就會直接使用這個映射表項,所以相同的五元組到LVS后會轉發給相同的Nginx,而不會進行WRR(Weight Round Robin)負載均衡,表現出了一定的"親和性"。如下圖所示:

 

NAT下固定ip地址對的性能瓶頸

好了,現在可以下結論了。在ip源和目的地址固定,目的端口號也固定的情況下,五元組的可變量只有ip源端口號了。而源端口號最多是65535個,如果計算保留端口號(0-2048)的話(假設防火墻保留2048個),那么最多可使用63487個端口。

由于每使用一個端口號,在高負載的情況下,都會產生一個112.5s才消失的TIME_WAIT。那么在63487/112.5也就是564TPS(使用短連接)的情況下,就會復用TIME_WAIT下的Socket。再加上PAWS校驗,就會造成大量的連接創建異常!

 

這個論斷和筆者觀察到的應用報錯以及LVS監控曲線一致。

LVS曲線異常事件和報錯時間接近

因為LVS是在529TPS時候開始垂直下降,而端口號復用是在564TPS的時候開始,兩者所需TPS非常接近,所以一般LVS出現曲線異常的時候,基本就是開始報錯的時候!但是LVS曲線異常只能表明復用表項,并不能表明一定有問題,因為可以通過調節某些內核參數使得在端口號復用的時候不報錯!

 

在端口號復用情況下,lvs本身的新建連接數無法代表真實TPS。

嘗試修復

設置tcp_tw_max_bucket

首先,筆者嘗試限制Nginx所在Linux中最大TIME_WAIT數量

  1. echo '5000'  > /proc/sys/net/ipv4/tcp_tw_max_bucket 

這基于一個很簡單的想法,TIME_WAIT狀態越少,那么命中TIME_WAIT狀態Socket的概率肯定越小。設置了之后,確實報錯量確實減少了好多。但由于TPS超越極限之后端口號不停的回繞,導致還是一直在報錯,不會有根本性好轉。

 

如果將tcp_tw_max_bucket設置為0,那么按理論上來說不會出問題了。但是無疑將TCP精心設計的TIME_WAIT這個狀態給廢棄了,筆者覺得這樣做過于冒險,于是沒有進行嘗試。

嘗試擴展源地址

這個問題本質是由于五元組在限定了4元,只有源端口號可變的情況下,端口號只有 2048-65535可用。那么我們放開源地址的限定,例如將源IP增加到3個,無疑可以將TPS擴大三倍。

 

同理,將目的地址給擴容,也能達到類似的效果。

但據網工反映,合作方通過他們的防火墻出來之后就只有一個IP,而一個IP在我們的防火墻上并不能映射成多個IP,多以在不變更它們網絡設置的情況下無法擴展源地址。而擴容目的地址,也需要對合作方網絡設置進行修改。本著不讓合作方改動的服務精神,筆者開始嘗試其它方案。

擴容Nginx?沒效果

在一開始筆者沒有搞明白LVS那個詭異的曲線的時候,筆者并不知道在端口復用的情況下,LVS會表現出"親和性"。于是想著,如果擴容Nginx后,根據負載均衡原則,正好落到有這個TIME_WAIT五元組的概率會降低,所以嘗試著另擴容了一倍的Nginx。但由于之前所說的LVS在端口號復用下的親和性,反而加大了TIME_WAIT段!

 

擴容Nginx的奇異現象

在筆者想明白LVS的"親和性"之后,對擴容Nginx會導致更多的報錯已經有了心理預期,不過被現實啪啪啪打臉!報錯量和之前基本一樣。更奇怪的是,筆者發現非活躍連接數監控(即非ESTABLISHED)狀態,會在端口號復用之后,呈現出一種負載不均衡的現象,如下圖所示。

 

筆者上去新擴容的Nginx看了一下,發現新Nginx只有很少量的由于PAWS引起的報錯,增長速率很慢,基本1個小時只有100多。而舊Nginx一個小時就有1W多!

那么按照這個錯誤比例分布,就很好理解為什么形成這樣的曲線了。因為LVS的親和性,在端口號復用時刻,落到舊Nginx上會大概率失敗,從而在Fintimeout到期后,重新選擇一個負載均衡的時候,如果落到新Nginx上,按照統計參數來看基本都會成功,但如果還是落到舊Nginx上則基本還會失敗,如此往復。就天然的形成了一個優先選擇的過程,從而造成了這個曲線。

 

當然實際的過程會比這個復雜一點,多一些步驟,但大體是這個思路。

而在端口復用結束后,不管落到哪個Nginx上都會成功,所以負載均衡又會慢慢趨于均衡。

為什么新擴容的Nginx表現異常優異呢?

新擴容的Nginx表現異常優異,在這個TPS下沒有問題,那到底是為什么呢?筆者想了一天都沒想明白。睡了一覺之后,對比了兩者的內核參數,突然豁然開朗。原來新擴容的Nginx所在的內核版本變了,變成了3.10!

筆者連忙對比起了原來的2.6內核和3.10的內核版本變化,但毫無所得。。。思維有陷入了停滯

Linux官方3.10和紅帽的3.10.1127分支差異

等等,我們線上的內核版本是3.10.1127,并不是官方的內核,難道代碼有所不同?于是筆者立馬下載了3.10.1127的源碼。這一比對,終于讓筆者找到了原因所在,看如下代碼!

  1. void inet_twdr_twkill_work(struct work_struct *work
  2.  struct inet_timewait_death_row *twdr = 
  3.   container_of(work, struct inet_timewait_death_row, twkill_work); 
  4.  bool rearm_timer = false
  5.  int i; 
  6.  
  7.  BUILD_BUG_ON((INET_TWDR_TWKILL_SLOTS - 1) > 
  8.    (sizeof(twdr->thread_slots) * 8)); 
  9.  
  10.  while (twdr->thread_slots) { 
  11.   spin_lock_bh(&twdr->death_lock); 
  12.   for (i = 0; i < INET_TWDR_TWKILL_SLOTS; i++) { 
  13.    if (!(twdr->thread_slots & (1 << i))) 
  14.     continue
  15.  
  16.    while (inet_twdr_do_twkill_work(twdr, i) != 0) { 
  17.     // 如果這次沒處理完,將rearm_timer設置為true 
  18.     rearm_timer = true
  19.     if (need_resched()) { 
  20.      spin_unlock_bh(&twdr->death_lock); 
  21.      schedule(); 
  22.      spin_lock_bh(&twdr->death_lock); 
  23.     } 
  24.    } 
  25.  
  26.    twdr->thread_slots &= ~(1 << i); 
  27.   } 
  28.   spin_unlock_bh(&twdr->death_lock); 
  29.  } 
  30.  // 在這邊多了一個rearm_timer,并將定時器設置為1s之后 
  31.  // 這樣,原來需要額外等待的7.5s現在收斂為額外等待1s 
  32.  if (rearm_timer) 
  33.   mod_timer(&twdr->tw_timer, jiffies + HZ); 

如代碼所示,3.10.1127對TIME_WAIT的時間輪處理做了加速,讓原來需要額外等待的7.5s收斂為額外等待的1s。經過校正后的時間輪如下所示:

 

那么TIME_WAIT的存活時間就從112.5s下降到60.5s(計算公式8.5*7+1)。

那么,在這個狀態下,我們的端口復用臨界TPS就達到了(65535-2048)/60.5=1049tps,由于線上業務量并沒有達到這一tps。所以對于新擴容的Nginx,并不會造成TIME_WAIT下的端口復用。所以錯誤量并沒有變多!當然,由于舊Nginx的存在,錯誤量也沒有變少。

但是,由于那個神奇的選擇性負載均衡的存在,在端口復用時間越長,每秒鐘的報錯量會越少!直到LVS的表項全部指到新Nginx集群,就不會再有報錯了!

TPS漲到1049tps依舊會報錯

當然了,根據上面的計算,在TPS繼續上漲到1049后,依舊會產生錯誤。新版本內核只不過拉高了臨界值,所以筆者還是要尋求更加徹底的解決方案。

順便吐槽一句

Linux TCP的實現對TIME_WAIT的處理用時間輪在筆者看來并不是什么高明的處理方式。

Linux本身對于Timer的處理本身就提供了紅黑樹這樣的方案。放著這樣好的方案不用,偏偏去實現一個精度不高還很復雜的時間輪。

所幸在Linux 4.x版本中,擯棄了時間輪,直接使用Linux本身的紅黑樹方案。感覺自然多了!

本文轉載自微信公眾號「解Bug之路」,可以通過以下二維碼關注。轉載本文請聯系解Bug之路公眾號。

 

責任編輯:武曉燕 來源: 解Bug之路
相關推薦

2009-06-22 08:38:33

Windows 7微軟操作系統

2021-12-02 07:02:16

API性能設計

2013-02-22 18:28:18

容錯服務器、

2009-01-17 15:26:05

2024-02-29 18:06:39

HTTP性能優化

2022-02-23 08:41:58

NATIPv4IPv6

2019-10-31 11:50:19

MySQL數據庫Windows

2021-06-07 14:57:46

開源開源工具Linux

2011-11-03 10:45:09

京東性能瓶頸

2020-06-10 08:28:51

Kata容器I

2023-05-06 18:37:43

2022-04-29 15:24:53

Redis存儲慢查詢

2021-06-02 10:00:30

云網絡性能測試

2020-12-31 05:33:34

軟件性能優化

2021-01-20 10:16:26

高并發數據服務

2010-07-12 09:27:17

SQL Server性

2017-01-16 18:11:23

存儲

2019-09-11 10:23:58

Redis性能存儲

2021-04-30 15:45:42

存儲人工智能數據

2025-07-04 09:38:02

點贊
收藏

51CTO技術棧公眾號

欧美日本在线看| 黄色网一区二区| 亚洲国产欧美在线观看| 国产精品丝袜在线| 国产日本欧美一区二区三区| 天天干天天干天天干天天干天天干| 精品无码一区二区三区的天堂| 成人va天堂| 国产日韩一级二级三级| 国产欧美日韩中文字幕在线| jizz亚洲少妇| 久久视频在线观看| 欧美精品在线一区二区三区| 国产高清自拍一区| 四虎成人永久免费视频| 三级小说欧洲区亚洲区| 日本一区二区免费在线观看视频| 欧美成人免费小视频| 这里只有精品在线观看视频 | 任你弄在线视频免费观看| 成人久久视频在线观看| 国产99视频在线观看| 亚洲 欧美 国产 另类| 中文在线字幕免费观看| 99久久久免费精品国产一区二区| 中国人与牲禽动交精品| 91大神免费观看| 男人av在线| 精品久久国产| 欧美日韩激情小视频| 日韩精品久久久毛片一区二区| 国产精品一区二区人人爽| 在线精品福利| 日韩在线观看视频免费| 超碰网在线观看| av毛片在线免费| 91在线一区二区| 亚洲精品欧美日韩专区| 日韩欧美黄色网址| 成人中文字幕视频| 亚洲三级免费电影| 久久av一区二区三区亚洲| 久久免费小视频| 永久免费精品视频| 欧美日韩美少妇| 国产a视频免费观看| 精品日韩av| 亚洲欧美日韩国产中文在线| 视频一区二区精品| 免费黄色片在线观看| 成人亚洲精品久久久久软件| 国产日韩在线看片| 黄色av一级片| av成人毛片| 亚洲二区中文字幕| 黄色av网址在线播放| 无码国产伦一区二区三区视频| 精品影院一区二区久久久| 国产成人精品一区| 欧美性猛交bbbbb精品| 1024手机在线视频| 亚洲一区二区三区四区电影| 欧美三级在线视频| 妓院一钑片免看黄大片| 91吃瓜在线观看| 亚洲激情图片小说视频| 中日韩在线视频| 亚洲av综合一区| 亚洲黄色成人| 亚洲欧美日韩中文在线制服| 亚洲天堂av网站| 超碰成人在线免费| 精品国产电影一区二区| 日韩成人三级视频| 欧美寡妇性猛交xxx免费| 亚洲精品你懂的| 日产精品高清视频免费| 国产黄色在线| 欧美韩国日本一区| 亚洲欧美在线网| 免费在线你懂的| 国产乱子伦视频一区二区三区| 成人a视频在线观看| 一区二区三区精彩视频| 久久狠狠亚洲综合| 1区1区3区4区产品乱码芒果精品| 国产精品视频在线观看免费| 国产剧情一区在线| 成人黄色片视频网站| 无码人妻一区二区三区免费| 久久久一二三| 久久亚洲国产精品成人av秋霞| 精品视频第一页| 午夜国产精品视频| 久久久久免费精品国产| 国产又大又黄又粗| 老色鬼精品视频在线观看播放| 91在线国产电影| 蜜桃视频久久一区免费观看入口| 99久久国产综合精品麻豆| 久久综合婷婷综合| 成人在线视频成人| 成人精品视频一区二区三区尤物| 精品1区2区| 免费观看黄色av| 久久一二三国产| 91精品国产高清久久久久久91裸体 | 日韩三级av在线| 丝瓜av网站精品一区二区| 国产欧美va欧美va香蕉在线| 丰满人妻一区二区三区免费| 91亚洲精品久久久蜜桃| 亚洲国产午夜伦理片大全在线观看网站 | 极品少妇一区二区三区| 日本精品免费观看| 91精品国产乱码久久久久| 成人精品鲁一区一区二区| 麻豆精品传媒视频| 精品麻豆一区二区三区| 亚洲自拍另类综合| 男女污污的视频| 精品国产三级| 国产香蕉一区二区三区在线视频 | 国产成人免费av在线| 国产亚洲欧美一区二区| 97超碰人人在线| 午夜精彩视频在线观看不卡| 激情黄色小视频| h片在线观看视频免费| 欧美三级视频在线观看| 怡红院一区二区| 久久亚洲影视| 日韩免费在线免费观看| 欧美一区二区在线观看视频| 国产精品麻豆视频| www.四虎成人| 国产精品视屏| 久久99久久99精品中文字幕| 亚洲精品一区二区二区| 99精品视频一区| 免费国产成人看片在线| 成人软件在线观看| 狠狠做深爱婷婷久久综合一区| 日本一区二区三区在线免费观看| 99免费精品| 91夜夜未满十八勿入爽爽影院| 网友自拍视频在线| 欧美日韩国产一级二级| 亚洲一二三四五六区| 毛片av一区二区三区| 亚洲黄色成人久久久| 国产91在线播放精品| 色综合伊人色综合网| 11024精品一区二区三区日韩| 国产精品欧美一区喷水| 日韩高清第一页| 天天综合精品| 国产精品 日韩| 捆绑调教日本一区二区三区| 亚洲国产日韩欧美综合久久| 午夜毛片在线观看| 久久综合色鬼综合色| 91av俱乐部| 四季av在线一区二区三区| 成人中文字幕+乱码+中文字幕| 国产区在线观看| 精品久久久久一区| 国产一级片毛片| 欧美高清在线视频| 国产福利精品一区二区三区| 欧美精品99| 老司机精品福利在线观看| 国产伦精品一区二区三区视频金莲| 亚洲欧美精品在线| 一级片在线观看视频| 一区二区国产盗摄色噜噜| 黄色工厂在线观看| 六月丁香综合在线视频| 免费看日本黄色| 免费成人av| 91麻豆桃色免费看| 国产美女高潮在线观看| 欧美在线|欧美| 国产精品国产精品88| 成人一级片网址| 欧美精品无码一区二区三区| 91tv精品福利国产在线观看| 国产免费高清一区| 国产a亚洲精品| 69av在线视频| 男人的天堂在线视频免费观看 | 99久久综合| 久久99精品久久久久久三级| 国产精品久久久久久妇女| 欧美一区二区三区日韩| 粉嫩aⅴ一区二区三区| 欧美国产禁国产网站cc| 国产十八熟妇av成人一区| 男女性色大片免费观看一区二区| 日本男女交配视频| 日韩中文在线电影| 国内精品久久久久久久果冻传媒| 色综合天天色| 97免费中文视频在线观看| 在线观看二区| 精品无人国产偷自产在线| 国产乱码精品一区二三区蜜臂| 狠狠躁夜夜躁人人躁婷婷91| xxxx日本少妇| 国产欧美日产一区| 欧亚乱熟女一区二区在线| 国产一区在线精品| 欧美精品性生活| 久久亚洲综合| www.av毛片| 婷婷精品进入| 日本一区二区精品视频| 国产精品久久久久久久久久白浆| 91精品久久久久久久久| 日韩欧美另类一区二区| 韩国一区二区电影| 特级毛片在线| 欧美哺乳videos| 国产精品美女一区| 欧美亚洲国产怡红院影院| 欧美一区二区激情视频| 亚洲综合成人在线| 欧美成人精品欧美一级| 亚洲欧洲日韩女同| 日本欧美一区二区三区不卡视频| 99久久综合狠狠综合久久| 国产精品日日摸夜夜爽| 国产精品99久久久久| 亚洲男人天堂2021| 久久av资源网| 天天操狠狠操夜夜操| 日本午夜精品一区二区三区电影| 国产91对白刺激露脸在线观看| 国内精品视频在线观看| 久久久婷婷一区二区三区不卡| 成人看片黄a免费看视频| 91久久精品国产91久久性色tv | www.黄色在线| 国内一区二区在线| 亚洲欧美视频二区| 久国产精品韩国三级视频| 午夜激情av在线| 奇米影视在线99精品| 色哟哟精品视频| 秋霞国产午夜精品免费视频| 亚洲少妇久久久| 久久成人免费日本黄色| 91福利免费观看| 国产一区二区在线观看视频| 日本一区二区三区在线免费观看| 国产激情一区二区三区四区| 人妻av一区二区三区| 不卡视频免费播放| 亚洲精品视频大全| 国产目拍亚洲精品99久久精品| 中文字幕伦理片| 亚洲九九爱视频| 日本学生初尝黑人巨免费视频| 天天综合天天做天天综合| 51国产偷自视频区视频| 在线观看不卡视频| 在线观看黄色网| 91精品国产麻豆国产自产在线| 国产区精品在线| 亚洲第一精品电影| 欧美色视频免费| 中文字幕欧美国内| 中文av资源在线| 亚洲18私人小影院| 91国内外精品自在线播放| 91在线精品播放| 希岛爱理av免费一区二区| 日韩欧美精品在线不卡| 欧美精品18| 蜜臀av午夜一区二区三区| 精品一区二区三区在线观看| 欧美一区二区三区影院| 成人av在线播放网址| 亚洲第一综合网| 一区二区三区四区视频精品免费 | 亚洲国产日本| 免费一级特黄录像| 国产精品99久久久久久似苏梦涵| 天堂久久久久久| 中文字幕一区三区| 青青国产在线观看| 欧美日韩aaaaaa| 天天操天天操天天| 日韩一级黄色av| 三妻四妾的电影电视剧在线观看| 国产女精品视频网站免费| 欧美巨大xxxx| 红桃一区二区三区| 久久资源在线| 高清中文字幕mv的电影| 中文字幕色av一区二区三区| 久久不卡免费视频| 欧美一区国产二区| 国产在线视频资源| 亚洲精品久久视频| 日韩在线视频免费| www.久久色.com| 欧美成人影院| 高清国产一区| 亚洲女同另类| 亚洲成色www.777999| 99久久精品国产麻豆演员表| 顶臀精品视频www| 欧美色爱综合网| 青青草视频在线免费观看| 欧美日韩爱爱视频| 91国产精品| 亚洲伊人久久综合| 欧美老女人另类| 中文字幕无码精品亚洲35| 国产精品中文字幕日韩精品 | 国产精品手机在线播放 | 日韩美女视频一区二区在线观看| 成人在线免费公开观看视频| 欧洲成人午夜免费大片| 国产一区丝袜| 日韩国产成人无码av毛片| 国产一区二区免费视频| 日本免费网站视频| 欧洲国产伦久久久久久久| 欧美拍拍视频| 91大神在线播放精品| 福利在线一区| 人妻互换免费中文字幕| 国产精品一区一区三区| 91 在线视频| 91精品国产入口在线| 精品176二区| 91欧美精品午夜性色福利在线| 色135综合网| 老司机久久精品| 亚洲色欲色欲www在线观看| 国产精品一区二区免费视频| 久久久国产成人精品| 手机av免费在线| 91精品国自产在线观看| 欧美日韩精品| 在线看黄色的网站| 欧美日韩美女在线| 日韩午夜影院| 国产成人综合亚洲| 成人羞羞动漫| 男人的天堂最新网址| 亚洲欧美一区二区三区久本道91| 国产精品国产一区二区三区四区| 日韩在线精品视频| 国产高清精品二区| 欧美大片免费播放| 成人在线一区二区三区| 日本三级2019| 亚洲色图17p| 欧美激情啪啪| 国产一级大片免费看| 99综合电影在线视频| 中文字幕在线欧美| 中文字幕免费国产精品| 看亚洲a级一级毛片| 婷婷五月综合缴情在线视频| 久久一区二区三区四区| 亚洲天堂网在线观看视频| 久久久精品久久| 澳门成人av| 国产免费人做人爱午夜视频| 国产精品乱码一区二区三区软件 | 亚洲奶大毛多的老太婆| 99久久精品一区二区成人| 最近免费观看高清韩国日本大全| 成人免费毛片app| 精品久久久久久久久久久国产字幕| 日韩在线观看你懂的| jizz久久精品永久免费| 黄色高清无遮挡| 亚洲人成电影网站色mp4| 天天操天天操天天干| 国产精品一区二区在线| 国产精品vip| 男女做爰猛烈刺激| 日韩欧美一卡二卡| 日韩成人av电影| 欧美xxxx吸乳| 久久精品亚洲一区二区三区浴池| 91久久国语露脸精品国产高跟| 91精品国产高清久久久久久| 成人av国产| 一边摸一边做爽的视频17国产| 欧洲国内综合视频| 欧美调教sm| 麻豆视频传媒入口| 国产三级三级三级精品8ⅰ区| 丰满少妇被猛烈进入|