對於一次IO訪問(以read舉例),數據會先被拷貝到操做系統內核的緩衝區中,而後纔會從操做系統內核的緩衝區拷貝到應用程序的地址空間。因此說。當一個read操做發生時,它會經歷兩個階段:php
1.等待數據準備(waiting for the data to be ready) 2.將數據從內核拷貝到進程中,正是由於這兩個階段,Linux系統產生了下面的五種網絡模: - 阻塞IO(blocking IO) - 非阻塞IO(nonblocking IO) - IO多路複用(IO multplexing) - 信號驅動IO(signal driven IO) - 異步IO(asynchronous IO) 注:因爲signal driven IO在實際中並不經常使用,因此只提剩下的四種IO模型
在Linux中,默認狀況下全部的socket都是blocking,一個典型的讀操做流程大概是這樣的:html
當用戶進程調用了recvfrom這個系統調用,kernel就開始了IO的第一個階段:準備數據(對於網絡IO來講,不少時候啥數據在一開始尚未到達。好比,尚未收到一個完整的udp包。這個時候kernel就要等待足夠的數據到來)。這個過程須要等待,也就是說數據被拷貝到操做系統內核的緩衝區中是須要一個過程的。而在用戶進程這邊,整個進程都會被阻塞(固然,這個事進程本身選擇的阻塞)。當kernel一直等到數據準備好了。他就會將數據從kernel中拷貝到用戶內存,而後kernel返回結果。用戶進程才接觸blocking狀態,從新運行起來。nginx
因此,blocking IO 的特色就是在IO執行的兩個階段都被block了。git
Linux下,能夠經過設置socket使其變爲non-blocking。當對一個non-blocing socket執行讀操做時,整個流程是這個樣子的:web
當用戶進程發出read操做時,若是kernel中的數據尚未準備好,那麼它並不會block用戶進程,而是馬上返回一個error,從用戶進程角度講,它發起一個read操做後,並不須要等待,二十立刻就獲得了一個結果。用戶進程判斷結果是一個error時,他就知道啥數據尚未準備好,因而它能夠再次發送read操做。一旦kernel中的數據準備好了,而且又再次收到了用戶進程的system call,那麼它立刻就將數據拷貝到了用戶內存,而後返回。centos
因此,nonblocking IO的特色是用戶進程須要不斷的主動詢問kernel數據準備好了沒有。瀏覽器
IO multiplexing 就是咱們說的select,poll,epoll,有些地方也稱這總IO方式爲事件驅動IO(event driven IO)。select/epoll的好處就在於單個process就能夠同時處理多個網絡鏈接的IO。他的基本原理就是select,poll,epoll這個function會不斷的輪詢所負責的全部socket,當某個socket有數據到達了,就通知用戶進程。緩存
當用戶進程調用了select,那麼這個進程會被block,而同時,kernel會「監視」全部select負責的socket,當任何一個socket中的數據準備好了,select就會返回,這個會後用戶進程再調用read操做。將數據從kernel拷貝到用戶進程。安全
因此,IO多路複用的特色是經過一種機制,一個進程能同時等待多個文件描述符,而這些文件描述符(套接字描述符)其中的任意一個進入讀就緒狀態,select()函數就會返回。服務器
這個圖和blocking IO的圖其實並無太大的不一樣,事實上,還更差一些,由於這裏須要使用兩個system call (select 和recvform),而blocking IO 只調用了一個system call(recvform),可是,用select的有事在於它能夠同時處理多個connection。
因此,若是處理的連接數不是很高的話,使用select/epoll 的web server 不必定比使用multi-threading + blocking IO 的web server性能更好,可能延遲還更大。
select/epoll 的優點並非對於單個鏈接能處理的更快,而是在於能處理更多的連接
在IO multiplexing model中,實際中,對於每個socket,通常都設置成爲nonblocking,可是,如上圖所示,這個用戶的process實際上是一直被block的,只不過process是被select這個函數block,而不是被socket IO給block。
Linux下的asynchronous IO其實用得不多,先看一下它的流程:
用戶進程發起read操做以後,馬上就能夠開始作其它的事。而另外一方面,從kernel的角度,當它收到一個asynchronous以後,首先它會馬上返回,因此不會對用戶進程產生任何的block。而後,kernel會等待數據準備完成,而後將數據拷貝到用戶內存,當這一切都完成以後,kernel會給用戶進程發送一個signal,告訴它read操做完成了。
--------------------------------------------------------------------------------------------------------------------------------
能夠採用源碼安裝或者yum安裝,具體方式請百度
nginx須要依賴gcc等依賴,建議先安裝依賴
剛剛遇到一個問題,centos7安裝nginx居然報錯了。。
[root@localhost ~]# yum install nginx -y 已加載插件:fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: mirrors.tuna.tsinghua.edu.cn * extras: mirrors.cn99.com * updates: mirrors.163.com 沒有可用軟件包 nginx。 錯誤:無須任何處理 [root@localhost ~]#
這個問題比較容易解決,能夠採用epel的方式安裝nginx
[root@localhost ~]# yum install epel-rpm-macros [root@localhost ~]# yum update [root@localhost ~]# yum install nginx [root@localhost ~]#
安裝就到這裏了,遇到問題自行百度就好。
[root@localhost ~]# systemctl stop nginx # 中止服務 [root@localhost ~]# systemctl start nginx # 啓動服務 [root@localhost ~]# systemctl status nginx # 查看狀態 [root@localhost ~]# systemctl restart nginx # 從新加載 [root@localhost ~]#
[root@localhost ~]# systemctl status nginx ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: inactive (dead) 9月 18 11:36:42 localhost.localdomain systemd[1]: Unit nginx.service cannot be reloaded because it is...ve. Hint: Some lines were ellipsized, use -l to show in full. [root@localhost ~]# systemctl stop nginx [root@localhost ~]# systemctl start nginx [root@localhost ~]# systemctl status nginx ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: active (running) since 二 2018-09-18 11:38:58 CST; 2s ago Process: 66173 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Process: 66170 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS) Process: 66164 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Main PID: 66175 (nginx) Tasks: 3 CGroup: /system.slice/nginx.service ├─66175 nginx: master process /usr/sbin/nginx ├─66176 nginx: worker process └─66177 nginx: worker process 9月 18 11:38:57 localhost.localdomain systemd[1]: Starting The nginx HTTP and reverse proxy server... 9月 18 11:38:58 localhost.localdomain nginx[66170]: nginx: the configuration file /etc/nginx/nginx.co... ok 9月 18 11:38:58 localhost.localdomain nginx[66170]: nginx: configuration file /etc/nginx/nginx.conf t...ful 9月 18 11:38:58 localhost.localdomain systemd[1]: Started The nginx HTTP and reverse proxy server. Hint: Some lines were ellipsized, use -l to show in full. [root@localhost ~]#
nginx默認使用80端口,已經啓動了,能夠從瀏覽器中進行訪問了。
https://nginx.org/en/docs/ 能夠進這個裏面找你須要的看,
https://nginx.org/en/docs/http/ngx_http_core_module.html#server
反向代理 VS 正向代理
什麼是正向代理?什麼是反向代理?
正向代理:
假設在客戶機與目標主機之間,只用戶代理內部網絡對Internet的連接請求,客戶機必須指定代理服務器,並將原來要直接發送到web服務器上的HTTP請求發送到代理服務器中。 1.提升訪問速度 2.防火牆做用 3.經過代理服務器訪問不能方案文的目標站點
反向代理:
服務器架設在服務器端,經過緩衝常常被請求的頁面來環節服務器的工做量,將客戶機請求轉發給內部網絡上的目標服務器;並將從服務器上獲得的結果返回給Internet請求連接的客戶端,此時代理服務器與目標主機一塊兒對外表現爲一個服務器。 1.能夠防止外網對內網服務器的惡性攻擊 2.緩存以減小服務器的壓力 3.訪問安全控制以外 4.能夠進行負載均衡,將用戶的請求分配給多個服務器
# proxy the PHP scripts to Apache listening on 127.0.0.1c80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} location ~ \.html$ { proxy_pass http://192.168.251.102c8080; }
# proxy the PHP scripts to Apache listening on 127.0.0.1c80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} location ~ \.html$ { proxy_pass http://webserver; } upstream webserver { server 192.168.251.102:8080; }
# proxy the PHP scripts to Apache listening on 127.0.0.1c80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} location ~ \.html$ { proxy_pass http://webserver; proxy_cache my-cache; } upstream webserver { s erver 192.168.251.102c8080; }
server { listen 80; server_name xxx.xt.com; access_log /var/log/nginx/git.chjrt.access.log; error_log /var/log/nginx/git.chjrt.error.log; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://172.20.206.41:8089; } }
更多等用到了補充。目前就用了這麼點。。