天天看點

網絡面經總結-僅供參考

網絡面經總結-僅供參考

      • 1 伺服器如何判斷用戶端連接配接不上了
        • 1.1 recv
        • 1.2 伺服器一段時間内沒接收到用戶端心跳包回報
        • 1.3 struct tcp_info info
        • 1.4[保活參數](https://blog.csdn.net/chrisnotfound/article/details/80111559)
        • 1.5 TCP Keepalive HTTP Keep-Alive 的關系
      • 2 心跳包多長時間發一次,如何判斷用戶端下線了
      • 3 四次揮手 通過什麼接口來判斷?????
      • 4 epoll隻能練500-1000個連接配接,有沒有判斷是什麼原因引起的
      • 5 noSQL-redis
      • 6 消息隊列-應用場景
      • 7 [微服務容器](https://www.cnblogs.com/jsjwk/p/11169296.html)
        • 7.1微服務容器操作
          • 容器基本操作
          • 鏡像
      • 8 虛函數析構函數和普通虛函數差別,及原因,析構順序
      • 10 [Redis為什麼是單線程的](https://blog.csdn.net/wanderlustlee/article/details/81148840)
      • 11 不同機器程序間如何通信:
      • 12 伺服器如何轉發消息的
      • 14 西安發消息到上海,接收方消息延遲了,原因
      • 15用戶端發了很多消息,伺服器怎麼及時處理?
      • 16[用戶端收到大量資料會導緻用戶端卡頓,怎麼優化?](https://www.cnblogs.com/marvin/p/4227431.html)
      • 17. 十幾個日志檔案,用什麼shell指令可以篩選出自己想要的日志内容
      • 18. 用戶端連接配接不上伺服器的問題一般怎麼定位?(未解決)
      • 19. [多程序檔案怎麼共享,為什麼要用mmap。](https://blog.csdn.net/tencupofkaiwater/article/details/88897529)
      • 20. [vi打開檔案後,怎麼替換無數個想要替換的内容](https://blog.csdn.net/GorgeousChou/article/details/79809229)
      • 21. 10W個使用者怎麼連接配接伺服器
      • 22. select可以連接配接2000個用戶端嗎?
      • 23. libevent怎麼用的?
      • 24. 連結清單順序不變,如何排序
      • 25. 硬碟大小不變,伺服器隻能連接配接1000個,要連10萬個怎麼辦?
      • [26 tcp用戶端能連接配接的最大長連接配接,與幾個因素有關,可以超越65536](https://blog.csdn.net/daiyudong2020/article/details/77852049)
      • [27 ping一個域名的過程](https://blog.csdn.net/guoweimelon/article/details/50865642)
      • 28 [用戶端架構設計](https://blog.csdn.net/birthmarkqiqi/article/details/78243979)
      • [29 TCP和UDP的差別和優缺點](https://blog.csdn.net/xiaobangkuaipao/article/details/76793702)
      • 30 [一個 SQL 執行的很慢的原因](https://www.cnblogs.com/myseries/p/10719074.html)
      • 31 如何檢視SQL語句的執行狀态,知道這條指令嗎
      • 32 什麼是程序,程序包括哪些資料?程序切換的過程是怎麼樣的
      • 33 網絡建立連接配接之後是怎麼關閉的(四次揮手)。
      • 34伺服器出現大量time_wait 狀态的連接配接原因?(長連結四次揮手出現了丢包、逾時等),假如不會出現丢包、逾時等,網絡非常流暢呢?(短連接配接導緻的)那怎麼解決?
      • 35 [負載均衡](https://www.cnblogs.com/hackerer/p/10407603.html)
      • 36 端口号範圍
      • 37 [IO瓶頸](https://blog.csdn.net/datuzijean/article/details/88655210)
        • 37.1 什麼樣的服務容易出現IO瓶頸
        • 37.2 [具體排查方法](https://www.cnblogs.com/muahao/p/6438409.html)
      • 38

1 伺服器如何判斷用戶端連接配接不上了

1.1 recv

recv()傳回值小于等于0,如果errno == EINTR 則說明recv函數是由于程式接收到信号後傳回的,socket連接配接還是正常的,不應close掉socket連接配接。

1.2 伺服器一段時間内沒接收到用戶端心跳包回報

1.3 struct tcp_info info

struct tcp_info info;

int len=sizeof(info);

getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);

if((info.tcpi_state==TCP_ESTABLISHED)) 則說明未斷開 else 斷開

1.4保活參數

int keepAlive = 1; // 開啟keepalive屬性

int keepIdle = 60; // 如該連接配接在60秒内沒有任何資料往來,則進行探測

int keepInterval = 5; // 探測時發包的時間間隔為5 秒

int keepCount = 3; // 探測嘗試的次數.如果第1次探測包就收到響應了,則後2次的不再發.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void )&keepAlive, sizeof(keepAlive));

setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void)&keepIdle, sizeof(keepIdle));

setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));

setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

設定後,若斷開,則在使用該socket讀寫時立即失敗,并傳回ETIMEDOUT錯誤

Linux中預設的Keepalive的選項如下:

$sudo sysctl -a | grep keepalive

net.ipv4.tcp_keepalive_time = 7200

net.ipv4.tcp_keepalive_probes = 9

net.ipv4.tcp_keepalive_intvl = 75

tcp_keepalive_time/tcp_keepalive_probes/tcp_keepalive_intvl,分别表示連接配接閑置多久開始發keepalive的ack包、發幾個ack包不回複才當對方死了、兩個ack包之間間隔多長,

1.5 TCP Keepalive HTTP Keep-Alive 的關系

HTTP協定的Keep-Alive意圖在于TCP連接配接複用,同一個連接配接上串行方式傳遞請求-響應資料;TCP的Keepalive機制意圖在于探測連接配接的對端是否存活。

2 心跳包多長時間發一次,如何判斷用戶端下線了

–(區域網路内)3秒發一次,伺服器10秒沒收到用戶端心跳包認為下線

3 四次揮手 通過什麼接口來判斷?????

– struct tcp_info info;

int len=sizeof(info);

getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);

if((info.tcpi_state==TCP_ESTABLISHED)) 則說明未斷開 else 斷開

4 epoll隻能練500-1000個連接配接,有沒有判斷是什麼原因引起的

1)linux系統會限制檔案打開個數(ulimit -a檢視),

–臨時修改

ulimit -HSn 2048

–永久修改

vi /etc/security/limits.conf

2)伺服器硬體限制

5 noSQL-redis

6 消息隊列-應用場景

作用:異步處理,應用解耦,流量削鋒和消息通訊

7 微服務容器

它不僅打包了本地應用程式,而且還将本地環境(作業系統的一部分)也打包了,組成一個叫做「 Docker鏡像 」的檔案包。是以這個「 Docker鏡像 」就包含了應用運作所需的全部依賴,我們可以直接基于這個「 Docker鏡像 」在本地進行開發與測試,完成之後,再直接将這個「 Docker鏡像 」一鍵上傳到雲端運作即可。

Docker容器裡雖然帶有一部分作業系統(檔案系統相關),但它并沒有核心,是以多個容器之間是共用主控端的作業系統核心的。

Namespace 技術 隻能改變一下程序組的視覺範圍

Cgroup技術提供的功能就是實作對記憶體、磁盤等這些資源進行限制

7.1微服務容器操作

容器基本操作

1 檢視docker資訊

sudo docker info

2 運作容器

sudo docker run -i -t ubuntu /bin/bash

3 在容器中可以安裝軟體和我們外面的linux機器一樣,隻是不一樣的ubuntu和centos指令不一樣

4 列出容器

sudo docker ps -a

(-a 包括沒有運作的)

5 啟動容器的時候可以給容器命名

sudo docker run --name firstContainername -i -t ubuntu /bin/bash

6 停止容器

sudo docker stop firstContainername (restart)

7 附着進入容器

sudo docker attach firstContainername

8 背景運作容器

sudo docker run -d -i -t ubuntu /bin/bash

9 擷取容器日志

sudo docker logs firstContainername

10 持續跟蹤容器日志

sudo docker logs -f firstContainername

11 持續跟蹤容器日志,并列印時間

sudo docker logs -ft firstContainername

12 可以将日志重定向到主控端,也有一些日期驅動

sudo docker run --logs-driver="syslog" --name firstContainername -d

使用syslog的日志驅動,關于日志驅動百度

13 檢視容器内的程序

sudo docker to firstContainername

14 統計容器的記憶體,網絡,cpu,io等的名額

sudo docker stats firstContainername

15 在背景運作的容器内執行指令

sudo docker exec -d firstContainername touch /etc/new_config_file

16 進入容器

sudo docker exec -it firstContainername /bin/bash

17 停止容器

sudo docker stop firstContainername

18 自動重新開機

sudo docker run --restart=always --name firstContainername -d ubuntu /bin/sh --restart=always

無論什麼情況停止都會重新開機,還可以加參數 --restart=on-failure:5 退出代碼為非0時重新開機5次

19 擷取容器資訊

sudo docker inspect firstContainername

20 删除容器

sudo docker rm firstContainername

21 删除所有容器 sudo docker rm ‘sudo docker ps -a -q’ -a傳回所有容器 -q隻傳回容器的id

22 備份容器

docker commit -p 30b8f18f20b4 container-backup

1)->登入

docker login

->打包:

docker tag a25ddfec4d2a arunpyasi/container-backup:test

->上傳到注冊中心:

docker push arunpyasi/container-backup

->恢複容器:

docker pull arunpyasi/container-backup:test

2)->備份在本地:

docker save -o ~/container-backup.tar container-backup

->恢複容器:

docker load -i ~/container-backup.tar

3)->加載的鏡像去運作Docker容器:

docker run -d -p 80:80 container-backup

docker pull: 從倉庫中拖鏡像

docker run:建立容器

docker stop:停止容器運作

docker start:開始容器運作

docker commit:送出容器到鏡像

docker images: 檢視目前有的鏡像

docker ps:檢視目前啟動的容器 docker ps -a 列出目前系統所有的容器

鏡像

1 列出所有鏡像

sudo docker images

2 拉取鏡像

sudo docker pull ubuntu

可以指定版本号,不指定為預設最新的鏡像

3 查找鏡像

sudo docker search ubuntu

4 注冊docker賬号後就可以使用 docker login指令進行登入

5 可以拉取一個centos鏡像 sudo docker pull centos 然後運作 sudo docker run -it --name centosContener centos /bin/bash 進入容器安裝vim yum -y install vim 退出容器 exit 送出容器 sudo docker commit -m"資訊" -a “作者” centosContener 鏡像使用者名/倉庫名:标簽

6 檢視鏡像的資訊 sudo docker inspect 鏡像使用者名/倉庫名:标簽

7 Dockerfile

FROM centos

RUN yum -y install nginx

EXPOSE 80

sudo docker build -t=“鏡像使用者名/倉庫名:标簽”

8 建構鏡像時禁用緩存 sudo docker build --no-cache -t=“鏡像使用者名/倉庫名:标簽”

9 檢視docker鏡像的建構曆史 sudo docker history centos 執行個體 sudo docker history zhaoqinrong/centos:test

10 檢視容器端口的映射情況 sudo docker port centosContener 80 會傳回映射到主控端上的端口

11 端口綁定 sudo docker run --name firstContainername -p 80 -d zhaoqinrong/centos

sudo docker run --name firstContainername -p 8080:80 -d zhaoqinrong/centos

sudo docker run --name firstContainername -p 127.0.0.1:8080:80 -d zhaoqinrong/centos

sudo docker run --name firstContainername -p 映射ip:映射到主控端的端口:容器端口 -d zhaoqinrong/centos

sudo docker run --name firstContainername -p -d zhaoqinrong/centos 将建構鏡像中的dockerfile檔案中的EXPOSE的所有端口公開,并随機綁定到主控端的端口上

12 Dockerfile 中的CMD指令,RUN指令是在建構中,docker容器未啟動時作用,而CMD是在啟動後執行的指令

CMD["/bin/bash","-l"]

8 虛函數析構函數和普通虛函數差別,及原因,析構順序

析構函數不一定必須是虛函數,是否為虛函數取決于該類的使用,一般該類為基類産生繼承和多态時,才會是虛函數,單獨使用可以不是虛函數。之是以在繼承和多态時設計為虛函數是因為當new派生類并且用基類指針指向這個派生類,在銷毀基類指針時隻會調用基類的析構函數,不會調用派生類的析構函數,因為基類無法操作派生類中非繼承的成員,這樣就造成派生類隻new無法delete造成記憶體洩露。 2.預設不是虛析構函數是因為如果析構函數為虛函數就需要編譯器在類中增加虛函數表來實作虛函數機制,這樣所需記憶體空間就更大了,是以沒有必要預設為虛析構函數。

class B
{
}
class C : public B
{
}
class D : public B
{
}
D* pD = new D();//pD的靜态類型是它聲明的類型D*,動态類型也是D*
B* pB = pD;//pB的靜态類型是它聲明的類型B*,動态類型是pB所指向的對象pD的類型D*
C* pC = new C();
pB = pC;//pB的動态類型是可以更改的,現在它的動态類型是C*
           

構造:先基類,後派生類

析構:先派生類,後基類

class B
  {
   virtual void vfun(int i = 10)
   {
       cout << "B:vfun, i = " << i;
       cout << endl;
   };
      public:
   void modfuc()
   {
       vfun();
   }
   virtual~B()
   {
       cout << "B:~vfun" << endl;
   }
  };
  
  class D : public B
  {
   virtual void vfun(int i = 20)
   {
       cout << "D:vfun, i = " << i;
       cout << endl;
   };
  
   void modfuc()
   {
       vfun();
   }
      public:
   ~D()
   {
       cout << "D:~vfun" << endl;
   }
  };
  
  int main()
  {
      D* pD = new D();
      B* pB = pD;
  
      pB->modfuc();//調用子類vfunc,但是入參是預設參數,靜态綁定的是以輸出為10,調用基類的i=10
      delete pD;
  }
           
網絡面經總結-僅供參考

9 邊沿觸發和水準觸發差別,邊沿觸發會引發什麼問題

Level Triggered (LT) 水準觸發

.socket接收緩沖區不為空 有資料可讀 讀事件一直觸發

.socket發送緩沖區不滿 可以繼續寫入資料 寫事件一直觸發

符合思維習慣,epoll_wait傳回的事件就是socket的狀态

Edge Triggered (ET) 邊沿觸發

.socket的接收緩沖區狀态變化時觸發讀事件,即空的接收緩沖區剛接收到資料時觸發讀事件

.socket的發送緩沖區狀态變化時觸發寫事件,即滿的緩沖區剛空出空間時觸發讀事件

僅在狀态變化時觸發事件

LT的程式設計與poll/select接近,符合一直以來的習慣,不易出錯

ET的程式設計可以做到更加簡潔,某些場景下更加高效,但另一方面容易遺漏事件(隻提醒一次,需循環接收accept()),容易産生bug

10 Redis為什麼是單線程的

原因一:redis本身就是基于記憶體操作的,是以每個操作執行速度都很快。

如果使用多線程,就需要解決多線程同步的問題,就會涉及到線程的頻繁切換而消耗CPU。單線程的使用避免了不必要的上下文切換和競争條件,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導緻的性能消耗。

原因二:redis中的資料結構比較簡單,對資料的操作也就比較快。

原因三:使用多路複用IO,即非阻塞IO。這樣提高了redis的吞吐量。多路是指可以處理多個網絡連接配接産生的流,複用是指一個線程可以服務多條IO流

缺點就是在多處理器情況下,不能充分利用其他CPU。可以的解決方法是開啟多個redis服務執行個體,通過複制和修改配置檔案,可以在多個端口上開啟多個redis服務執行個體,這樣就可以利用其他CPU來處理連接配接流。

11 不同機器程序間如何通信:

socket

12 伺服器如何轉發消息的

ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);

ret = send(RecvBuf.ToFd, &RecvBuf, sizeof(RecvBuf), 0);

接收用戶端A的消息包,從包中取出A需要發送到B的位址,然後伺服器把A的消息轉發給B

伺服器如何轉發離線消息(消息隊列)

14 西安發消息到上海,接收方消息延遲了,原因

網絡原因+用戶端記憶體

15用戶端發了很多消息,伺服器怎麼及時處理?

(多線程+消息隊列/緩沖區)

億萬級用戶端:搭建伺服器叢集按業務劃分去處理,各個業務伺服器之前可以加負載均衡,使使用者均勻的分布在各個伺服器上。

優點:當某一個伺服器故障,不會影響所有使用者,隻會影響到連接配接到這個伺服器的使用者。

16用戶端收到大量資料會導緻用戶端卡頓,怎麼優化?

(多線程+緩沖區)

1 延遲加載是指用到的時候,再去進行實際的建構。

2 緩存(頁面緩存+資料緩存)

3 異步

4 歸并處理(重新整理線程->判斷目前界面是否存在->定時重新整理資料)

5 視覺欺騙 (給出提示資訊或者進度條)

用戶端資料可以分頁顯示處理,比如一共有1000頁資料,用戶端一頁可以顯示10條,那就按照每次10條顯示在用戶端,當使用者想查詢下一頁時再拉取下一頁的資料顯示,直到資料末尾。

17. 十幾個日志檔案,用什麼shell指令可以篩選出自己想要的日志内容

grep -r key 路徑

18. 用戶端連接配接不上伺服器的問題一般怎麼定位?(未解決)

ping、檢查IP/PORT、netstat xxx查詢連接配接狀态
           

19. 多程序檔案怎麼共享,為什麼要用mmap。

正常檔案操作需要從磁盤到頁緩存再到使用者主存的兩次資料拷貝。而mmap操控檔案,隻需要從磁盤到使用者主存的一次資料拷貝過程。說白了,mmap的關鍵點是實作了使用者空間和核心空間的資料直接互動而省去了空間不同資料不通的繁瑣過程。是以mmap效率更高。

mmap優點總結

由上文讨論可知,mmap優點共有一下幾點:

1、對檔案的讀取操作跨過了頁緩存,減少了資料的拷貝次數,用記憶體讀寫取代I/O讀寫,提高了檔案讀取效率。

2、實作了使用者空間和核心空間的高效互動方式。兩空間的各自修改操作可以直接反映在映射的區域内,進而被對方空間及時捕捉。

3、提供程序間共享記憶體及互相通信的方式。不管是父子程序還是無親緣關系的程序,都可以将自身使用者空間映射到同一個檔案或匿名映射到同一片區域。進而通過各自對映射區域的改動,達到程序間通信和程序間共享的目的。

20. vi打開檔案後,怎麼替換無數個想要替換的内容

:%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替換每一行中所有 vivian 為 sky

21. 10W個使用者怎麼連接配接伺服器

–每個連接配接一個fd,linux加大檔案打開數限制,加心跳包

–單伺服器隻有多線程配合強大硬體。最好用多伺服器,使用隊列協同。

–伺服器ip、伺服器端口、用戶端ip、用戶端端口4個因素形成一條唯一連接配接。記得伺服器的ip和端口總是不變的,就是監聽的那個。是以不存在端口不夠用的問題

–負載均衡和伺服器的叢集

NIO模型:

網絡面經總結-僅供參考

來源連接配接

分離:登入伺服器、通訊伺服器、消息伺服器 和 資料庫伺服器;

◎登入伺服器(有狀态):除給Client提供登入和配置設定通訊伺服器外,重點功能是提供關于使用者目前連接配接在哪台伺服器上的查詢,是以所有查詢基本基于緩存完成;考慮到單點故障問題,登入伺服器應雙機備援,但不能太多,否則雙機之間的緩存同步代價太高;緩存可使用開源元件。

◎通訊伺服器(有狀态):負責維護消息長連接配接,以及消息的收發;通訊伺服器緩存自身的所有使用者連接配接資訊,和部分(這個要時情況動态調整)非自身的熱點使用者連接配接資訊(即該使用者連在哪台通訊伺服器上);消息到達時,将消息轉發給消息伺服器進行落地;然後根據目标最終使用者先查詢本地表,查不到就去查詢登入伺服器;然後直接尋找目标通訊伺服器,發送消息到達的通知;通訊伺服器的問題是沒有Failover,但是也不重要,用戶端連接配接不上就由登入伺服器重新配置設定新的通訊伺服器來提供服務即可。

◎ 消息伺服器(無狀态):負責接收通訊伺服器所發來的消息,批量寫入資料庫中,以及供其它消息伺服器存取;另外也提供曆史消息查詢這類輔助性功能;因為是無狀态,是以叢集較為簡單,略。

◎ 資料庫伺服器:略。

22. select可以連接配接2000個用戶端嗎?

select上限1024個

23. libevent怎麼用的?

24. 連結清單順序不變,如何排序

數組存指針有序的指向連結清單節點,輸出

25. 硬碟大小不變,伺服器隻能連接配接1000個,要連10萬個怎麼辦?

linux加大檔案打開數限制

負載均衡和伺服器的叢集

26 tcp用戶端能連接配接的最大長連接配接,與幾個因素有關,可以超越65536

(1) 程序能打開的最大描述符

(2) IP_TABLE的限制

(3) 臨時端口範圍

(4) 記憶體大小

二、調整能打開的最大檔案描述符

$ echo “655350” > /proc/sys/fs/file-max

$ vi /etc/security/limits.conf

* soft nofile 655350  
* hard nofile 655350
           

三、調整臨時端口範圍與IP_TABLE限制(centos7)

$ vim /etc/sysctl.conf

#臨時端口範圍
net.ipv4.ip_local_port_range = 10000 65535

#Linux網絡核心的IP_TABLE防火牆對最大跟蹤的TCP連接配接數有限制
net.netfilter.nf_conntrack_max = 655350
net.nf_conntrack_max = 655350
           

27 ping一個域名的過程

28 用戶端架構設計

四層架構

在三層架構的基礎上多了業務規則層,通常的三層是把業務邏輯和業務規則合并為一個層,統稱為業務層.業務規則層的提出,既可以及時處理使用者輸入的不合法資訊, 又可以及時處理資料庫錯誤, 增大了業務邏輯層的結構清晰度, 讓業務邏輯人員專心緻志做邏輯。

從上至下為:

l 表示層

l 業務規則層

l 業務邏輯層或稱為領域層

l 資料通路層

29 TCP和UDP的差別和優缺點

1)、TCP與UDP差別總結:

1、TCP面向連接配接(如打電話要先撥号建立連接配接);UDP是無連接配接的,即發送資料之前不需要建立連接配接

2、TCP提供可靠的服務。也就是說,通過TCP連接配接傳送的資料,無差錯,不丢失,不重複,且按序到達;UDP盡最大努力傳遞,即不保證可靠傳遞

Tcp通過校驗和,重傳控制,序号辨別,滑動視窗、确認應答實作可靠傳輸。如丢包時的重發控制,還可以對次序亂掉的分包進行順序控制。

那麼,TCP具體是通過怎樣的方式來保證資料的順序化傳輸呢?

  1. 主機每次發送資料時,TCP就給每個資料包配置設定一個序列号并且在一個特定的時間内等待接收主機對配置設定的這個序列号進行确認,
  2. 如果發送主機在一個特定時間内沒有收到接收主機的确認,則發送主機會重傳此資料包。
  3. 接收主機利用序列号對接收的資料進行确認,以便檢測對方發送的資料是否有丢失或者亂序等,
  4. 接收主機一旦收到已經順序化的資料,它就将這些資料按正确的順序重組成資料流并傳遞到高層進行處理。

3、UDP具有較好的實時性,工作效率比TCP高,适用于對高速傳輸和實時性有較高的通信或廣播通信。

4.每一條TCP連接配接隻能是點到點的;UDP支援一對一,一對多,多對一和多對多的互動通信

5、TCP對系統資源要求較多,UDP對系統資源要求較少。

6、UDP丢包(服務端增加緩沖區),亂序( 發送端給資料設定序号,接收端對資料包根據序号做排序處理)

7、TCP有流量控制和擁塞控制

流量控制:對發送方發送速率的控制

擁塞控制:TCP引入 慢啟動 機制, 先發少量的資料, 探探路, 摸清目前的網絡擁堵狀态, 再決定按照多大的速度傳輸

網絡面經總結-僅供參考

2)、為什麼UDP有時比TCP更有優勢?

UDP以其簡單、傳輸快的優勢,在越來越多場景下取代了TCP,如實時遊戲

(1)網速的提升給UDP的穩定性提供可靠網絡保障,丢包率很低,如果使用應用層重傳,能夠確定傳輸的可靠性。

(2)TCP為了實作網絡通信的可靠性,使用了複雜的擁塞控制算法,建立了繁瑣的握手過程,由于TCP内置的系統協定棧中,極難對其進行改進。

采用TCP,一旦發生丢包,TCP會将後續的包緩存起來,等前面的包重傳并接收到後再繼續發送,延時會越來越大,基于UDP對實時性要求較為嚴格的情況下,采用自定義重傳機制,能夠把丢包産生的延遲降到最低,盡量減少網絡問題對遊戲性造成影響。

網絡面經總結-僅供參考

30 一個 SQL 執行的很慢的原因

1、大多數情況下很正常,偶爾很慢,則有如下原因

(1)、資料庫在重新整理髒頁,例如 redo log 寫滿了需要同步到磁盤。

(2)、執行的時候,遇到鎖,如表鎖、行鎖。

2、這條 SQL 語句一直執行的很慢,則有如下原因。

(1)、沒有用上索引:例如該字段沒有索引;由于對字段進行運算、函數操作導緻無法用索引。

(2)、資料庫選錯了索引。

31 如何檢視SQL語句的執行狀态,知道這條指令嗎

show processlist

32 什麼是程序,程序包括哪些資料?程序切換的過程是怎麼樣的

1、系統進行資源配置設定和排程的基本機關

2、代碼段, 資料段, 堆, 棧

3、切換頁目錄以使用新的位址空間->切換核心棧和硬體上下文

33 網絡建立連接配接之後是怎麼關閉的(四次揮手)。

網絡面經總結-僅供參考

34伺服器出現大量time_wait 狀态的連接配接原因?(長連結四次揮手出現了丢包、逾時等),假如不會出現丢包、逾時等,網絡非常流暢呢?(短連接配接導緻的)那怎麼解決?

原因:(長連結:丢包,逾時;或短連接配接導緻)

進入TIME_WAIT狀态等待2MSL主要有兩個目的:一方面是主動關閉連接配接的一方在對方沒有收到最後一個ACK包時(這時對方還會重發FIN,收到兩個FIN的時間間隔一定小于2MSL)有時間可以重發ACK包,另一方面處于TIME_WAIT的連接配接(IP和端口組合)不能重用,這樣可以保證被重新配置設定的socket不會受到之前殘留的延遲重發封包影響。

1) 由于主動關閉TCP連接配接的一方才會進入TIME_WAIT狀态,一般情況伺服器端不會出現TIME_WAIT狀态,因為大多數情況都是用戶端主動發起連接配接并主動關閉連接配接。但是某些服務如pop/smtp、ftp卻是服務端收到用戶端的QUIT指令後主動關閉連接配接,這就造成這類伺服器上容易出現大量的TIME_WAIT狀态的連接配接,而且并發量越大處于此種狀态的連接配接越多。另外,對于被動關閉連接配接的服務在主動關閉用戶端非法請求或清理長時間不活動的連接配接時(這種情況很可能是用戶端程式忘記關閉連接配接)也會出現TIME_WAIT的狀态。

2) 從根本上去優化我們的系統架構設計,減少不必要的短連接配接請求

解決辦法:

1、 看一下現在time_wait的數量

netstat -an | grep TIME_WAIT | wc -l

2、發現系統存在大量TIME_WAIT狀态的連接配接,通過調整核心參數解決,在 /etc/sysctl.conf中加入

net.ipv4.tcp_tw_recycle = 1 (表示開啟TCP連接配接中TIME-WAIT sockets的快速回收,預設為0,表示關閉)

net.ipv4.tcp_fin_timeout=30 (修改系統預設的 TIMEOUT 時間

然後執行 /sbin/sysctl -p 讓參數生效。

3、看看系統的tcp參數情況

sysctl -a|grep tcp

35 負載均衡

七層負載均衡基本都是基于http協定的,适用于web伺服器的負載均衡。(nginx)

  • 四層負載均衡主要是基于tcp協定封包,可以做任何基于tcp/ip協定的軟體的負載均衡。(haproxy、LVS)
  • 兩者主要差別在于利用的封包所在的層面是不同的,各有各的好處。
  • 七層應用負載的好處,是使得整個網絡更”智能化“。例如通路一個網站的使用者流量,可以通過七層的方式,将對圖檔類的請求轉發到特定的圖檔伺服器并可以使用緩存技術;将對文字類的請求可以轉發到特定的文字伺服器并可以使用壓縮技術。當然這隻是七層應用的一個小案例,從技術原理上,這種方式可以對用戶端的請求和伺服器的響應進行任意意義上的修改,極大的提升了應用系統在網絡層的靈活性。很多在背景,例如Nginx或者Apache上部署的功能可以前移到負載均衡裝置上,例如客戶請求中的Header重寫,伺服器響應中的關鍵字過濾或者内容插入等功能。
  • 四層負載均衡主要是較為靈活,可以作為多種軟體的負載均衡器。
  • 網絡面經總結-僅供參考

    七層應用負載優點:

    1)是使得整個網絡更"智能化"。例如通路一個網站的使用者流量,可以通過七層的方式,将對圖檔類的請求轉發到特定的圖檔伺服器并可以使用緩存技術;将對文字類的請求可以轉發到特定的文字伺服器并可以使用壓縮技術。當然這隻是七層應用的一個小案例,從技術原理上,這種方式可以對用戶端的請求和伺服器的響應進行任意意義上的修改,極大的提升了應用系統在網絡層的靈活性。很多在背景,例如Nginx或者Apache上部署的功能可以前移到負載均衡裝置上,例如客戶請求中的Header重寫,伺服器響應中的關鍵字過濾或者内容插入等功能。

2)另外一個常常被提到功能就是安全性。網絡中最常見的SYN Flood攻擊,即黑客控制衆多源用戶端,使用虛假IP位址對同一目标發送SYN攻擊,通常這種攻擊會大量發送SYN封包,耗盡伺服器上的相關資源,以達到Denial of Service(DoS)的目的。從技術原理上也可以看出,四層模式下這些SYN攻擊都會被轉發到後端的伺服器上;而七層模式下這些SYN攻擊自然在負載均衡裝置上就截止,不會影響背景伺服器的正常營運。另外負載均衡裝置可以在七層層面設定多種政策,過濾特定封包,例如SQL Injection等應用層面的特定攻擊手段,從應用層面進一步提高系統整體安全。

七層負載均衡缺點表現在如下幾個方面:

1)七層負載均衡受到其所支援的協定限制(一般隻有HTTP),這樣就限制了它應用的廣泛性。

2)七層負載均衡檢查HTTP報頭會占用大量的系統資源,勢必會影響到系統的性能,在大量連接配接請求的情況下,負載均衡裝置自身容易成為網絡整體性能的瓶頸。

4 總體對比

4.1) 智能性

七層負載均衡由于具備OIS七層的所有功能,是以在處理使用者需求上能更加靈活,從理論上講,七層模型能對使用者的所有跟服務端的請求進行修改。例如對檔案header添加資訊,根據不同的檔案類型進行分類轉發。四層模型僅支援基于網絡層的需求轉發,不能修改使用者請求的内容。

4.2) 安全性

七層負載均衡由于具有OSI模型的全部功能,能更容易抵禦來自網絡的攻擊;四層模型從原理上講,會直接将使用者的請求轉發給後端節點,無法直接抵禦網絡攻擊。

4.3) 複雜度

四層模型一般比較簡單的架構,容易管理,容易定位問題;七層模型架構比較複雜,通常也需要考慮結合四層模型的混用情況,出現問題定位比較複雜。

4.4) 效率比

四層模型基于更底層的設定,通常效率更高,但應用範圍有限;七層模型需要更多的資源損耗,在理論上講比四層模型有更強的功能,現在的實作更多是基于http應用。

軟體負載均衡與硬體負載均衡的對比:

軟體負載均衡的優點是需求環境明确,配置簡單,操作靈活,成本低廉,效率不高,能滿足普通的企業需求;缺點是依賴于系統,增加資源開銷;軟體的優劣決定環境的性能;系統的安全,軟體的穩定性均會影響到整個環境的安全。

硬體負載均衡優點是獨立于系統,整體性能大量提升,在功能、性能上優于軟體方式;智能的流量管理,多種政策可選,能達到最佳的負載均衡效果;缺點是價格昂貴。

五、負載均衡政策

負載均衡政策的優劣及其實作的難易程度有兩個關鍵因素:負載均衡算法;對網絡系統狀況的檢測方式和能力。

負載均衡算法

1)輪循均衡(Round Robin):每一次來自網絡的請求輪流配置設定給内部中的伺服器,從1至N然後重新開始。此種均衡算法适合于伺服器組中的所有伺服器都有相同的軟硬體配置并且平均服務請求相對均衡的情況。

2)權重輪循均衡(Weighted Round Robin):根據伺服器的不同處理能力,給每個伺服器配置設定不同的權值,使其能夠接受相應權值數的服務請求。例如:伺服器A的權值被設計成1,B的權值是 3,C的權值是6,則伺服器A、B、C将分别接受到10%、30%、60%的服務請求。此種均衡算法能確定高性能的伺服器得到更多的使用率,避免低性能的伺服器負載過重。

3)随機均衡(Random):把來自網絡的請求随機配置設定給内部中的多個伺服器。

4)權重随機均衡(Weighted Random):此種均衡算法類似于權重輪循算法,不過在處理請求分擔時是個随機選擇的過程。

5)響應速度均衡(Response Time):負載均衡裝置對内部各伺服器發出一個探測請求(例如Ping),然後根據内部中各伺服器對探測請求的最快響應時間來決定哪一台伺服器來響應用戶端的服務請求。此種均衡算法能較好的反映伺服器的目前運作狀态,但這最快響應時間僅僅指的是負載均衡裝置與伺服器間的最快響應時間,而不是用戶端與伺服器間的最快響應時間。

6)最少連接配接數均衡(Least Connection):用戶端的每一次請求服務在伺服器停留的時間可能會有較大的差異,随着工作時間加長,如果采用簡單的輪循或随機均衡算法,每一台伺服器上的連接配接程序可能會産生極大的不同,并沒有達到真正的負載均衡。最少連接配接數均衡算法對内部中需負載的每一台伺服器都有一個資料記錄,記錄目前該伺服器正在處理的連接配接數量,當有新的服務連接配接請求時,将把目前請求配置設定給連接配接數最少的伺服器,使均衡更加符合實際情況,負載更加均衡。此種均衡算法适合長時處理的請求服務,如FTP。

7)處理能力均衡:此種均衡算法将把服務請求配置設定給内部中處理負荷(根據伺服器CPU型号、CPU數量、記憶體大小及目前連接配接數等換算而成)最輕的伺服器,由于考慮到了内部伺服器的處理能力及目前網絡運作狀況,是以此種均衡算法相對來說更加精确,尤其适合運用到第七層(應用層)負載均衡的情況下。

8)DNS響應均衡(Flash DNS):在Internet上,無論是HTTP、FTP或是其它的服務請求,用戶端一般都是通過域名解析來找到伺服器确切的IP位址的。在此均衡算法下,分處在不同地理位置的負載均衡裝置收到同一個用戶端的域名解析請求,并在同一時間内把此域名解析成各自相對應伺服器的IP位址(即與此負載均衡裝置在同一位地理位置的伺服器的IP位址)并傳回給用戶端,則用戶端将以最先收到的域名解析IP位址來繼續請求服務,而忽略其它的IP位址響應。在種均衡政策适合應用在全局負載均衡的情況下,對本地負載均衡是沒有意義的。

36 端口号範圍

端口的取值範圍是:0-65535。

在這個取值範圍中1023以下的端口已經配置設定給了常用的一些應用程式,這個數字以後的端口部分被使用,是以網絡程式設計可用的端口一般在1024之後選取

系統端口(Well known port)

系統端口範圍:0~1023

系統端口由IANA負責配置設定。需要走申請流程,申請手續最為嚴格。

使用者端口(Registered port)

使用者端口範圍:1024~49151

使用者端口由IANA負責配置設定。需要走申請流程,申請手續相對系統端口來說不那麼嚴格。

動态端口(Private port)

動态端口範圍:49152~65535

動态端口不在IANA的配置設定範圍,應用程式可以在不用申請這些端口的情況下使用這些端口,但是,有個問題,因為這些端口可能會被其他應用程式或者作業系統使用,是以,我們不能假定這些端口在任意時間都可用,是以,不能将這些端口用于标示一個服務。

37 IO瓶頸

37.1 什麼樣的服務容易出現IO瓶頸

1.IO密集型服務(例如資料庫,檔案存儲服務dfs等)

2.含有大量讀寫的服務(服務日志寫入龐大,檔案讀取頻繁)

3.含有持久化功能的服務(Redis、MQ等)

37.2 具體排查方法

???定位IO瓶頸的方法,iowait低,IO就沒有到瓶頸?

通過分析mpstat的iowait和iostat的util%,判斷IO瓶頸

IO瓶頸往往是我們可能會忽略的地方(我們常會看top、free、netstat等等,但經常會忽略IO的負載情況),今天給大家詳細分享一下如何确認一台伺服器的IO負載是否到達了瓶頸,以及可能優化、定位的點。

1.top 看負載,負載高。

2.iostat -x 3 看IO情況 await 列IO響應時間,svctm 沒次IO操作服務時間,不應高于5ms-10ms,理想值是await 與svctm接近表示磁盤IO性能很好,如果await 大于svctm表示有IO隊列等待,IO讀寫可能存在瓶頸,util清單示統計時間内IO操作耗時百分比,值越高,IO越繁忙(要結合前兩項名額,單純的高不能斷定為IO瓶頸)。

3.iotop檢視IO高的程序,strace -p PID 或 lsof -p PID 檢視具體程序操作。

補充說明

IO密集型在産生IO瓶頸的時候,負載會高,但CPU百分比未必一定會高,是以要通過iostat、iotop等工具去确認是否是IO瓶頸。

38

close-on-exec

fork底層實作

epoll底層實作即結構

第三方工具檢視CPU占用情況

:top,vmstat,dstat

什麼是B+樹

繼續閱讀