Java Web系列文章彙總貼: Java Web知識總結匯總
Tomcat
Tomcat的頂層架構
Tomcat的兩個核心組件:Connector & Container。
多個Connector和一個Container就形成了Service,而Service包括整個Tomcat的生命週期由Server控制。
Connector負責接受請求,Container負責處理這些請求,Service主要負責關聯兩者,同時會初始化它下面的其他組件。所有組件的聲明週期在一個Lifecycle的接口中控制。
Server提供一個接口讓其他程序能夠訪問到這個Service集合,同時要維護它包含的所有Service的生命週期,包括如何初始化、如何結束服務、如何找到別人要訪問的Service。
Connector架構分析
Connector就是使用ProtocolHandler來處理請求的,不同的ProtocolHandler代表不同的連接類型,比如:Http11Protocol使用的是普通Socket來連接的,Http11NioProtocol使用的是NioSocket來連接的。
其中ProtocolHandler由包含了三個部件:Endpoint、Processor、Adapter。
(1)Endpoint用來處理底層Socket的網絡連接,Processor用於將Endpoint接收到的Socket封裝成Request,Adapter用於將Request交給Container進行具體的處理。
(2)Endpoint由於是處理底層的Socket網絡連接,因此Endpoint是用來實現TCP/IP協議的,而Processor用來實現HTTP協議的,Adapter將請求適配到Servlet容器進行具體的處理。
(3)Endpoint的抽象實現AbstractEndpoint裏面定義的Acceptor和AsyncTimeout兩個內部類和一個Handler接口。Acceptor用於監聽請求,AsyncTimeout用於檢查異步Request的超時,Handler用於處理接收到的Socket,在內部調用Processor進行處理。
Container架構分析
4個子容器的作用分別是:
(1)Engine:引擎,用來管理多個站點,一個Service最多只能有一個Engine;
(2)Host:代表一個站點,也可以叫虛擬主機,通過配置Host就可以添加站點;
(3)Context:代表一個應用程序,對應着平時開發的一套程序,或者一個WEB-INF目錄以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封裝着一個Servlet;
參考:
四張圖帶你瞭解Tomcat系統架構
Tomcat的系統架構與工作流程簡介
Servlet的工作原理
Nginx
什麼是C10K問題
C10K問題由來
隨着互聯網的普及,應用的用戶羣體幾何倍增長,此時服務器性能問題就出現。最初的服務器是基於進程/線程模型。新到來一個TCP連接,就需要分配一個進程。假如有C10K,就需要創建1W個進程,可想而知單機是無法承受的。那麼如何突破單機性能是高性能網絡編程必須要面對的問題,進而這些侷限和問題就統稱爲C10K問題,最早是由Dan Kegel進行歸納和總結的,並且他也系統的分析和提出解決方案。
C10K問題的本質
C10K問題的本質上是操作系統的問題。對於Web 1.0/2.0時代的操作系統,傳統的同步阻塞I/O模型處理方式都是requests per second。當創建的進程或線程多了,數據拷貝頻繁(緩存I/O、內核將數據拷貝到用戶進程空間、阻塞,進程/線程上下文切換消耗大, 導致操作系統崩潰,這就是C10K問題的本質。
可見, 解決C10K問題的關鍵就是儘可能減少這些CPU資源消耗。
C10K問題的解決方案
從網絡編程技術的角度來說,主要思路:
- 每個連接分配一個獨立的線程/進程
- 同一個線程/進程同時處理多個連接
摘自:
C10K問題
正向代理和反向代理
正向代理:
正向代理通過下面的圖理解其實就是用戶想從服務器拿資源數據,但是隻能通過proxy服務器才能拿到,所以用戶A只能去訪問proxy服務器然後通過proxy服務器去服務器B拿數據,這種情況用戶是明確知道你要訪問的是誰,在我們生活中最典型的案例就是“翻牆“了,也是通過訪問代理服務器最後訪問外網的。
反向代理:
反向代理其實就是客戶端去訪問服務器時,他並不知道會訪問哪一臺,感覺就是客戶端訪問了Proxy一樣,而實則就是當proxy關口拿到用戶請求的時候會轉發到代理服務器中的隨機(算法)某一臺。而在用戶看來,他只是訪問了Proxy服務器而已,典型的例子就是負載均衡了。
圖示:
參考:
談一談正向代理和反向代理
Nginx中常用的幾種負載均衡策略
策略 | 釋義 |
---|---|
輪詢 | 默認方式 |
weight | 權重方式 |
ip_hash | 根據ip分配方式 |
least_conn | 最少連接方式 |
fair(第三方) | 響應時間方式 |
url_hash(第三方) | 根據URL分配方式 |
擴展:Web的負載均衡策略
幾種負載均衡方式
- HTTP重定向實現負載均衡
- DNS負載均衡
- 反向代理負載均衡
負載均衡組件
- apache
- nginx
- lvs
- HAProxy
- keepalived
常見的幾種負載均衡算法
- 1、輪詢
- 2、加權輪詢
- 3、隨機
- 4、加權隨機
- 5、Hash法:根據客戶端的IP,或者請求的“Key”,計算出一個hash值,然後對節點數目取模
- 6、最少連接
更多:
高併發解決方案之一 ——負載均衡
Web應用的負載均衡、集羣、高可用(HA)解決方案整理總結
關於負載均衡的一切:總結與思考
Nginx架構及工作原理
Nginx架構
大致上Nginx的架構就是這樣:
1.Nginx啓動後,會產生一個主進程,主進程執行一系列的工作後會產生一個或者多個工作進程;
2.在客戶端請求動態站點的過程中,Nginx服務器還涉及和後端服務器的通信。Nginx將接收到的Web請求通過代理轉發到後端服務器,由後端服務器進行數據處理和組織;
3.Nginx爲了提高對請求的響應效率,降低網絡壓力,採用了緩存機制,將歷史應答數據緩存到本地。保障對緩存文件的快速訪問;
工作進程
工作進程的主要工作有以下幾項:
- 接收客戶端請求;
- 將請求一次送入各個功能模塊進行過濾處理;
- IO調用,獲取響應數據;
- 與後端服務器通信,接收後端服務器處理結果;
- 數據緩存
- 響應客戶端請求;
進程交互
Nginx服務器在使用Master-Worker模型時,會涉及到主進程和工作進程的交互和工作進程之間的交互。這兩類交互都依賴於管道機制。
1.Master-Worker交互
這條管道與普通的管道不同,它是由主進程指向工作進程的單向管道,包含主進程向工作進程發出的指令,工作進程ID等;同時主進程與外界通過信號通信;
2.worker-worker交互
這種交互是和Master-Worker交互是基本一致的。但是會通過主進程。工作進程之間是相互隔離的,所以當工作進程W1需要向工作進程W2發指令時,首先找到W2的進程ID,然後將正確的指令寫入指向W2的通道。W2收到信號採取相應的措施。
Nginx模塊化
-
(1)核心模塊;
核心模塊是Nginx服務器正常運行必不可少的模塊,如同操作系統的內核。它提供了Nginx最基本的核心服務。像進程管理、權限控制、錯誤日誌記錄等; -
(2)標準HTTP模塊;
標準HTTP模塊支持標準的HTTP的功能; -
(3)可選HTTP模塊;
可選HTTP模塊主要用於擴展標準的HTTP功能,讓Nginx能處理一些特殊的服務; -
(4)郵件服務模塊;
郵件服務模塊主要用於支持Nginx的郵件服務; -
(5)第三方模塊;
第三方模塊是爲了擴展Nginx服務器應用,完成開發者想要的功能;
Nginx配置
#運行用戶
user nobody;
#啓動進程,通常設置成和cpu的數量相等
worker_processes 1;
#全局錯誤日誌及PID文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#工作模式及連接數上限
events {
#epoll是多路複用IO(I/O Multiplexing)中的一種方式,
#僅用於linux2.6以上內核,可以大大提高nginx的性能
use epoll;
#單個後臺worker process進程的最大併發鏈接數
worker_connections 1024;
# 併發總數是 worker_processes 和 worker_connections 的乘積
# 即 max_clients = worker_processes * worker_connections
# 在設置了反向代理的情況下,max_clients = worker_processes * worker_connections / 4 爲什麼
# 爲什麼上面反向代理要除以4,應該說是一個經驗值
# 根據以上條件,正常情況下的Nginx Server可以應付的最大連接數爲:4 * 8000 = 32000
# worker_connections 值的設置跟物理內存大小有關
# 因爲併發受IO約束,max_clients的值須小於系統可以打開的最大文件數
# 而系統可以打開的最大文件數和內存大小成正比,一般1GB內存的機器上可以打開的文件數大約是10萬左右
# 我們來看看360M內存的VPS可以打開的文件句柄數是多少:
# $ cat /proc/sys/fs/file-max
# 輸出 34336
# 32000 < 34336,即併發連接總數小於系統可以打開的文件句柄總數,這樣就在操作系統可以承受的範圍之內
# 所以,worker_connections 的值需根據 worker_processes 進程數目和系統可以打開的最大文件總數進行適當地進行設置
# 使得併發總數小於操作系統可以打開的最大文件數目
# 其實質也就是根據主機的物理CPU和內存進行配置
# 當然,理論上的併發總數可能會和實際有所偏差,因爲主機還有其他的工作進程需要消耗系統資源。
# ulimit -SHn 65535
}
http {
#設定mime類型,類型由mime.type文件定義
include mime.types;
default_type application/octet-stream;
#設定日誌格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
#sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,
#對於普通應用,必須設爲 on,
#如果用來進行下載等應用磁盤IO重負載應用,可設置爲 off,
#以平衡磁盤與網絡I/O處理速度,降低系統的uptime.
sendfile on;
#tcp_nopush on;
#連接超時時間
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
#開啓gzip壓縮
gzip on;
gzip_disable "MSIE [1-6].";
#設定請求緩衝
client_header_buffer_size 128k;
large_client_header_buffers 4 128k;
#設定虛擬主機配置
server {
#偵聽80端口
listen 80;
#定義使用 www.nginx.cn訪問
server_name www.nginx.cn;
#定義服務器的默認網站根目錄位置
root html;
#設定本虛擬主機的訪問日誌
access_log logs/nginx.access.log main;
#默認請求
location / {
#定義首頁索引文件的名稱
index index.php index.html index.htm;
}
# 定義錯誤提示頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
#靜態文件,nginx自己處理
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
#過期30天,靜態文件不怎麼更新,過期可以設大一點,
#如果頻繁更新,則可以設置得小一點。
expires 30d;
}
#PHP 腳本請求全部轉發到 FastCGI處理. 使用FastCGI默認配置.
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#禁止訪問 .htxxx 文件
location ~ /.ht {
deny all;
}
}
}