linux高併發伺服器案例演示
在網路通訊中,我們常常的伺服器經常會受到成千上萬的請求提示,而電腦會根據請求建立相對應的socket鏈結,但是接觸過linux網路程式設計的人都知道,linux鏈結和客戶端建立連線,會經過四步(這裡以tcp說明)
第一步,建立socket對應的描述符,這裡設定好socket的協議型別以及通訊型別(tcp/udp)
#include /* see notes */
#include
int socket(int domain, int type, int protocol);
具體的使用方法可以使用man手冊檢視socket函式
第二步,繫結埠,以及相應的ip位址(伺服器不用設定)
#include /* see notes */
#include
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
具體的使用方法可以使用man手冊檢視bind函式
第三步,監聽socket,並且設定最大監聽數
#include
int listen(int sockfd, int backlog);
具體的使用方法可以使用man手冊檢視listen函式
第四步,接受客戶端的連線
#include
int accept(int sockfd, struct sockaddr *addr, socklen_t*addrlen);
具體的使用方法可以使用man手冊檢視accept函式
注意:由於上述四步socket建立鏈結中,accept是阻塞的,意味著如果有很多人同時發出socket請求的時候,伺服器只會接收到一少部分的連線,其他都在阻塞佇列排隊,甚至丟失!甚至建立鏈結後一旦涉及伺服器讀寫操作時候,涉及到讀寫,也是會遇到阻塞的!(假設每個使用者連線伺服器需要0.1秒,那麼10000人連線的話則需要1000秒)這樣會讓伺服器浪費大量時間在阻塞過程,所以我們要做的,就是盡可能的讓系統發揮出他的效能,讓更多的人能夠連線系統,卻不用花那麼長時間。
具體實現方法:
使用epoll分路技術,讓accept不陷入阻塞,當那個客戶端發出請求,則處理發出請求的客戶端資訊,這時候因為客戶端發出請求,則必定有讀寫操作,所以讀寫操作不用去掉阻塞。
伺服器**:
//模擬接收每個客戶端發來的請求後並往dbg.txt檔案寫入乙個位元組
#include #include #include #include #include #include #include #include #include #include #include #include #include void sig_handle(int sig)
int main(int argc, char * argv)
unlink("dbg.txt");
int count = atoi(argv[1]);
int fd = socket(af_inet,sock_stream,0);
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family = af_inet;
addr.sin_port = htons(9988);
int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
if (ret ==-1)
listen(fd,250);
int is_child_process = 0;//判斷在哪個程序中,父程序0,子程序1
for (int i = 0 ; i < count ; i++)
}struct epoll_event ev;
ev.events = epollin|epollet;
ev.data.fd = fd;
int epfd = epoll_create(1024);//建立epfd的描述符
int flags = fcntl(fd,f_getfl);
flags |= o_nonblock;
fcntl(fd,f_setfl,flags);
epoll_ctl(epfd,epoll_ctl_add,fd,&ev);
while (1)
ev.data.fd = ret;
epoll_ctl(epfd,epoll_ctl_add,ret,&ev);
}else
else if (ret == 0)
//printf("recv data %s from pid:%d\n",buf,getpid());
write(dbg,"1",1);}}
}if (!is_child_process)
}return 0;
}
測試客戶端向伺服器發請求**:
//模擬有20000個客戶端同時向伺服器發請求
#include #include #include #include #include #include #define process_count 20000
void func(int argc,char * argv)
int main(int argc,char *argv)
{ for (int i = 0 ; i 結果分析:不同的電腦測試結果略有不同,我的客戶端定義有20000個同時向伺服器發請求,結果處理的請求大概有15500左右,不同的電腦最高併發數略有不同。成功的解決了多使用者同時向乙個伺服器發請求的問題
高併發解決方案
時常看到高併發的問題,但高併發其實是最不需要考慮的東西。為何,他虛無縹緲,很少有 真的需要這些東西,而且其中很多技術,其實你已經在用了。有這個意識就夠了,不需要時刻盯著這個問題。只有很少的 真的能達到高併發。簡單做乙個歸納,從低成本 高效能和高擴張性的角度來說有如下處理方案 1 html靜態化 2 ...
高併發解決方案
將靜態資源分離到靜態站,對靜態資源的請求打到靜態站,增加動態站的請求處理量 頁面靜態化是將程式生成的頁面儲存起來,使用模板技術如freemarker和velocity生成靜態頁面 nginx快取頁面資訊,再次請求時直接從快取中獲取,不需要重新生成,頁面快取記憶體中,提高訪問速度 具有相同處理功能的伺...
高併發解決方案
秒殺場景一般會在電商 舉行一些活動或者節假日在12306 上搶票時遇到。對於電商 中一些稀缺或者 商品,電商 一般會在約定時間點對其進行限量銷售,因為這些商品的特殊性,會吸引大量使用者前來搶購,並且會在約定的時間點同時在秒殺頁面進行搶購。限流 鑑於只有少部分使用者能夠秒殺成功,所以要限制大部分流量,...