一般解決服務器負載問題,都會經過多服務器分載來解決。常見的解決方案有:javascript
那咱們看看Nginx是如何實現負載均衡的,Nginx的upstream目前支持如下幾種方式的分配 一、輪詢(默認) 每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。 二、weight 指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。 二、ip_hash 每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。 三、fair(第三方) 按後端服務器的響應時間來分配請求,響應時間短的優先分配。 四、url_hash(第三方) 按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。php
Upstream配置如何實現負載 css
http { upstream www.test1.com { ip_hash; server 172.16.125.76:8066 weight=10; server 172.16.125.76:8077 down; server 172.16.0.18:8066 max_fails=3 fail_timeout=30s; server 172.16.0.18:8077 backup; } upstream www.test2.com { server 172.16.0.21:8066; server 192.168.76.98:8066; } server { listen 80; server_name www.test1.com; location /{ proxy_pass http://www.test1.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } server { listen 80; server_name www.test2.com; location /{ proxy_pass http://www.test2.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
當有請求到www.test1.com/www.test2.com 時請求會被分發到對應的upstream設置的服務器列表上。test2的每一次請求分發的服務器都是隨機的,就是第一種狀況列舉的。而test1剛是根據來訪問ip的hashid來分發到指定的服務器,也就是說該IP的請求都是轉到這個指定的服務器上。html
根據服務器的自己的性能差異及職能,能夠設置不一樣的參數控制。前端
down 表示負載太重或者不參與負載java
weight 權重過大表明承擔的負載就越大node
backup 其它服務器時或down時纔會請求backup服務器linux
max_fails 失敗超過指定次數會暫停或請求轉往其它服務器nginx
fail_timeout 失敗超過指定次數後暫停時間git
以上就Nginx的負載均衡的簡單配置。那繼續咱們的本節討論內容:
1、Session問題
當咱們肯定一系列負載的服務器後,那咱們的WEB站點會分佈到這些服務器上。這個時候若是採用Test2 每一次請求隨機訪問任何一臺服務器上,這樣致使你訪問A服務器後,下一次請求又忽然轉到B服務器上。這個時候與A服務器創建的Session,傳到B站點服務器確定是沒法正常響應的。咱們看一下經常使用的解決方案:
第一種緩存的方式比較理想,緩存的效率也比較高。可是每一臺請求服務器都去訪問Session會話服務器,那不是加載重了這臺Session服務器的負擔嗎?
第二種保存到數據庫中,除了要控制Session的有效期,同時加劇了數據庫的負擔,因此最終的轉變爲SQL Server 負載均衡,涉及讀,寫,過時,同步。
第三種經過nginx ip_hash負載保持對同一服務器的會話,這種看起來最方便,最輕量。
正常狀況下架構簡單的話, ip_hash能夠解決Session問題,可是咱們來看看下面這種狀況
這個時候ip_hash 收到的請求都是來自固定IP代理的請求,若是代理IP的負載太高就會致使ip_hash對應的服務器負載壓力過大,這樣ip_hash就失去了負載均衡的做用了。
若是緩存能夠實現同步共享的話,咱們能夠經過多session服務器來解決單一負載太重的問題。那Memcached是否能夠作Session緩存服務器呢?MemcachedProvider提供了Session的功能,即將Session保存到數據庫中。那爲何不直接保存到數據庫中,而要經過Memcached保存到數據庫中呢?很簡單,若是直接保存到數據庫中,每一次請求Session有效性都要回數據庫驗證一下。其次,即便咱們爲數據庫創建一層緩存,那這個緩存也沒法實現分佈式共享,仍是針對同一臺緩存服務器負載太重。網上也看到有用Memcached實現Session緩存的成功案例,固然數據庫方式實現的仍是比較經常使用的,好比開源Disuz.net論壇。緩存實現的小範圍分佈式也是比較經常使用的,好比單點登陸也是一種特殊狀況。
2、文件上傳下載
若是實現了負載均衡,除了Session問題,咱們還會碰到文件的上傳下載問題。文件不可能上傳不一樣的服務器上,這樣會致使下載不到對應文件的問題。咱們看一下下面的方案
兩種方案都是經常使用的,咱們來講一下文件壓縮數據庫,之前的方式都是將文件二進制壓縮相當系型數據庫,而如今NOSQL的流行,加上MongoDB處理文件又比較方便,因此文件壓庫又多了一種選擇。畢竟文件服務器的效率和管理以及安全都不及數據庫。
隨便聊聊這點事,其實也就是一些應用的趨勢和多一種解決方案的實現。
Nginx ("engine x") 是一個高性能的 HTTP 和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 代理服務器。 Nginx 是由 Igor Sysoev 爲俄羅斯訪問量第二的 Rambler.ru 站點開發的,它已經在該站點運行超過兩年半了。 Igor 將源代碼以類 BSD 許可證的形式發佈。儘管仍是測試版,可是,Nginx 已經由於它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名了。
根據最新一期(08 年 6 月份)的 NetCraft 調查報告顯示,已經有超過兩百萬的主機使用了 Nginx,這個數字超過了另一個輕量級的 HTTP 服務器 lighttpd, 排名第四,而且發展迅速。下面是這份報告的前幾名的報表:
產品 | 網站數 |
Apache | 84,309,103 |
IIS | 60,987,087 |
Google GFE | 10,465,178 |
Unknown | 4,903,174 |
nginx | 2,125,160 |
Oversee | 1,953,848 |
lighttpd | 1,532,952 |
關於這期調查報告的更詳細信息請看下面連接:
http://survey.netcraft.com/Reports/200806/
下圖是最近幾個月使用 Nginx 和 lighttpd 的網站數比較
圖 1. 最近幾個月使用 Nginx 和 lighttpd 的網站數比較
爲了確保能在 Nginx 中使用正則表達式進行更靈活的配置,安裝以前須要肯定系統是否安裝有 PCRE(Perl Compatible Regular Expressions)包。您能夠到 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ 下載最新的 PCRE 源碼包,使用下面命令下載編譯和安裝 PCRE 包:
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.7.tar.gz # tar zxvf pcre-7.7.tar.gz # cd pcre-7.7 # ./configure # make # make install |
接下來安裝 Nginx,Nginx 通常有兩個版本,分別是穩定版和開發版,您能夠根據您的目的來選擇這兩個版本的其中一個,下面是把 Nginx 安裝到 /opt/nginx 目錄下的詳細步驟:
# wget http://sysoev.ru/nginx/nginx-0.6.31.tar.gz # tar zxvf nginx-0.6.31.tar.gz # cd nginx-0.6.31 # ./configure --with-http_stub_status_module –prefix=/opt/nginx # make # make install |
其中參數 --with-http_stub_status_module
是爲了啓用 nginx 的 NginxStatus 功能,用來監控 Nginx 的當前狀態。
安裝成功後 /opt/nginx 目錄下有四個子目錄分別是:conf、html、logs、sbin 。其中 Nginx 的配置文件存放於 conf/nginx.conf,Nginx 只有一個程序文件位於 sbin 目錄下的 nginx 文件。確保系統的 80 端口沒被其餘程序佔用,運行 sbin/nginx 命令來啓動 Nginx,打開瀏覽器訪問此機器的 IP,若是瀏覽器出現 Welcome to nginx! 則表示 Nginx 已經安裝並運行成功。
Nginx 安裝後只有一個程序文件,自己並不提供各類管理程序,它是使用參數和系統信號機制對 Nginx 進程自己進行控制的。 Nginx 的參數包括有以下幾個:
-c <path_to_config>:使用指定的配置文件而不是 conf 目錄下的 nginx.conf 。
-t:測試配置文件是否正確,在運行時須要從新加載配置的時候,此命令很是重要,用來檢測所修改的配置文件是否有語法錯誤。
-v:顯示 nginx 版本號。
-V:顯示 nginx 的版本號以及編譯環境信息以及編譯時的參數。
例如咱們要測試某個配置文件是否書寫正確,咱們能夠使用如下命令
sbin/nginx – t – c conf/nginx2.conf |
Nginx 支持下表中的信號:
信號名 | 做用描述 |
TERM, INT | 快速關閉程序,停止當前正在處理的請求 |
QUIT | 處理完當前請求後,關閉程序 |
HUP | 從新加載配置,並開啓新的工做進程,關閉就的進程,此操做不會中斷請求 |
USR1 | 從新打開日誌文件,用於切換日誌,例如天天生成一個新的日誌文件 |
USR2 | 平滑升級可執行程序 |
WINCH | 從容關閉工做進程 |
有兩種方式來經過這些信號去控制 Nginx,第一是經過 logs 目錄下的 nginx.pid 查看當前運行的 Nginx 的進程 ID,經過 kill – XXX <pid>
來控制 Nginx,其中 XXX 就是上表中列出的信號名。若是您的系統中只有一個 Nginx 進程,那您也能夠經過 killall
命令來完成,例如運行 killall – s HUP nginx
來讓 Nginx 從新加載配置。
先來看一個實際的配置文件:
user nobody;# 工做進程的屬主 worker_processes 4;# 工做進程數,通常與 CPU 核數等同 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { use epoll;#Linux 下性能最好的 event 模式 worker_connections 2048;# 每一個工做進程容許最大的同時鏈接數 } http { 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 off; access_log logs/access.log;# 日誌文件名 sendfile on; #tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; include gzip.conf; # 集羣中的全部後臺服務器的配置信息 upstream tomcats { server 192.168.0.11:8080 weight=10; server 192.168.0.11:8081 weight=10; server 192.168.0.12:8080 weight=10; server 192.168.0.12:8081 weight=10; server 192.168.0.13:8080 weight=10; server 192.168.0.13:8081 weight=10; } server { listen 80;#HTTP 的端口 server_name localhost; charset utf-8; #access_log logs/host.access.log main; location ~ ^/NginxStatus/ { stub_status on; #Nginx 狀態監控配置 access_log off; } location ~ ^/(WEB-INF)/ { deny all; } location ~ \.(htm|html|asp|php|gif|jpg|jpeg|png|bmp|ico|rar|css|js| zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ { root /opt/webapp; expires 24h; } location / { proxy_pass http://tomcats;# 反向代理 include proxy.conf; } error_page 404 /html/404.html; # redirect server error pages to the static page /50x.html # error_page 502 503 /html/502.html; error_page 500 504 /50x.html; location = /50x.html { root html; } } } |
上面是一個實際網站的配置實例,其中灰色文字爲配置說明。上述配置中,首先咱們定義了一個 location ~ ^/NginxStatus/,這樣經過 http://localhost/NginxStatus/ 就能夠監控到 Nginx 的運行信息,顯示的內容以下:
Active connections: 70 server accepts handled requests 14553819 14553819 19239266 Reading: 0 Writing: 3 Waiting: 67 |
NginxStatus 顯示的內容意思以下:
經過正則表達式,咱們可以讓 Nginx 識別出各類靜態文件,例如 images 路徑下的全部請求能夠寫爲:
location ~ ^/images/ { root /opt/webapp/images; } |
而下面的配置則定義了幾種文件類型的請求處理方式。
location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|ico|css|js|txt)$ { root /opt/webapp; expires 24h; } |
對於例如圖片、靜態 HTML 文件、js 腳本文件和 css 樣式文件等,咱們但願 Nginx 直接處理並返回給瀏覽器,這樣能夠大大的加快網頁瀏覽時的速度。所以對於這類文件咱們須要經過 root 指令來指定文件的存放路徑,同時由於這類文件並不常修改,經過 expires
指令來控制其在瀏覽器的緩存,以減小沒必要要的請求。 expires
指令能夠控制 HTTP 應答中的「 Expires 」和「 Cache-Control 」的頭標(起到控制頁面緩存的做用)。您能夠使用例如如下的格式來書寫 Expires:
expires 1 January, 1970, 00:00:01 GMT; expires 60s; expires 30m; expires 24h; expires 1d; expires max; expires off; |
Nginx 自己並不支持如今流行的 JSP、ASP、PHP、PERL 等動態頁面,可是它能夠經過反向代理將請求發送到後端的服務器,例如 Tomcat、Apache、IIS 等來完成動態頁面的請求處理。前面的配置示例中,咱們首先定義了由 Nginx 直接處理的一些靜態文件請求後,其餘全部的請求經過 proxy_pass 指令傳送給後端的服務器(在上述例子中是 Tomcat)。最簡單的 proxy_pass
用法以下:
location / { proxy_pass http://localhost:8080; proxy_set_header X-Real-IP $remote_addr; } |
這裏咱們沒有使用到集羣,而是將請求直接送到運行在 8080 端口的 Tomcat 服務上來完成相似 JSP 和 Servlet 的請求處理。
當頁面的訪問量很是大的時候,每每須要多個應用服務器來共同承擔動態頁面的執行操做,這時咱們就須要使用集羣的架構。 Nginx 經過 upstream
指令來定義一個服務器的集羣,最前面那個完整的例子中咱們定義了一個名爲 tomcats 的集羣,這個集羣中包括了三臺服務器共 6 個 Tomcat 服務。而 proxy_pass 指令的寫法變成了:
location / { proxy_pass http://tomcats; proxy_set_header X-Real-IP $remote_addr; } |
在 Nginx 的集羣配置中,Nginx 使用最簡單的平均分配規則給集羣中的每一個節點分配請求。一旦某個節點失效時,或者從新起效時,Nginx 都會很是及時的處理狀態的變化,以保證不會影響到用戶的訪問。
儘管整個程序包只有五百多 K,但麻雀雖小、五臟俱全。 Nginx 官方提供的各類功能模塊應有盡有,結合這些模塊能夠完整各類各樣的配置要求,例如:壓縮、防盜鏈、集羣、FastCGI、流媒體服務器、Memcached 支持、URL 重寫等等,更關鍵的是 Nginx 擁有 Apache 和其餘 HTTP 服務器沒法比擬的高性能。您甚至能夠在不改變原有網站的架構上,經過在前端引入 Nginx 來提高網站的訪問速度。
本文只是簡單介紹了 Nginx 的安裝以及常見的基本的配置和使用,更多關於 Nginx 的信息請閱讀文章後面的參考資源。在這裏要很是感謝個人朋友——陳磊(chanix@msn.com),他一直在作 Nginx 的中文 WIKI(http://wiki.codemongers.com/NginxChs),同時也是他介紹給我這麼好的一款軟件。
若是您的網站是運行在 Linux 下,若是您並無使用一些很是複雜的並且肯定 Nginx 沒法完成的功能,那您應該試試 Nginx 。
ginx的upstream目前支持4種方式的分配 一、輪詢(默認) 每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。 二、weight 指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。 二、ip_hash 每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。 三、fair(第三方) 按後端服務器的響應時間來分配請求,響應時間短的優先分配。 四、url_hash(第三方) 按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。
負載均衡: 只須要在http中增長 upstream tgcluster {#定義負載均衡設備的Ip及設備狀態 ip_hash; server 127.0.0.1:9090 down; server 127.0.0.1:8080 weight=2; server 127.0.0.1:6060; server 127.0.0.1:7070 backup; } 在須要使用負載均衡的server中增長 proxy_pass http://tgcluster/; 每一個設備的狀態設置爲: 1.down 表示單前的server暫時不參與負載 2.weight 默認爲1.weight越大,負載的權重就越大。 3.max_fails :容許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤 4.fail_timeout:max_fails次失敗後,暫停的時間。 5.backup: 其它全部的非backup機器down或者忙的時候,請求backup機器。因此這臺機器壓力會最輕。
研究這個東西好多天了...沒人教,難啊...什麼都得一個一個搜索。Fuck
來源 v
http://blog.s135.com/tags/nginx/
中文文檔:http://wiki.nginx.org/NginxChs
#用戶 用戶組 user www www; #工做進程,根據硬件調整,有人說幾核cpu,就配幾個,我以爲能夠多一點 worker_processes 5; #錯誤日誌 error_log logs/error.log; #pid文件位置 pid logs/nginx.pid; worker_rlimit_nofile 8192;
events { #工做進程的最大鏈接數量,根據硬件調整,和前面工做進程配合起來用,儘可能大,可是別把cpu跑到100%就行 worker_connections 4096; }
http { include conf/mime.types; #反向代理配置,能夠打開proxy.conf看看 include /etc/nginx/proxy.conf; #fastcgi配置,能夠打開fastcgi.conf看看 include /etc/nginx/fastcgi.conf;
default_type application/octet-stream; #日誌的格式 log_format main ‘$remote_addr – $remote_user [$time_local] $status ‘ ‘」$request」 $body_bytes_sent 「$http_referer」 ‘ ‘」$http_user_agent」 「$http_x_forwarded_for」’; #訪問日誌 access_log logs/access.log main; sendfile on; tcp_nopush on; #根據實際狀況調整,若是server不少,就調大一點 server_names_hash_bucket_size 128; # this seems to be required for some vhosts
#這個例子是fastcgi的例子,若是用fastcgi就要仔細看 server { # php/fastcgi listen 80; #域名,能夠有多個 server_name domain1.com www.domain1.com; #訪問日誌,和上面的級別不同,應該是下級的覆蓋上級的 access_log logs/domain1.access.log main; root html;
location / { index index.html index.htm index.php; }
#全部php後綴的,都經過fastcgi發送到1025端口上 #上面include的fastcgi.conf在此應該是有做用,若是你不include,那麼就把fastcgi.conf的配置項放在這個下面。 location ~ .php$ { fastcgi_pass 127.0.0.1:1025; } }
#這個是反向代理的例子 server { # simple reverse-proxy listen 80; server_name domain2.com www.domain2.com; access_log logs/domain2.access.log main;
#靜態文件,nginx本身處理 location ~ ^/(images|javascript|js|css|flash|media|static)/ { root /var/www/virtual/big.server.com/htdocs; #過時30天,靜態文件不怎麼更新,過時能夠設大一點,若是頻繁更新,則能夠設置得小一點。 expires 30d; }
#把請求轉發給後臺web服務器,反向代理和fastcgi的區別是,反向代理後面是web服務器,fastcgi後臺是fasstcgi監聽進程,固然,協議也不同。 location / { proxy_pass http://127.0.0.1:8080; } }
#upstream的負載均衡,weight是權重,能夠根據機器配置定義權重。聽說nginx能夠根據後臺響應時間調整。後臺須要多個web服務器。
01 |
upstream big_server_com { |
02 |
server 127.0.0.3:8000 weight=5; |
03 |
server 127.0.0.3:8001 weight=5; |
04 |
server 192.168.0.1:8000; |
05 |
server 192.168.0.1:8001; |
06 |
} |
07 |
08 |
server { |
09 |
listen 80; |
10 |
server_name big.server.com; |
11 |
access_log logs/big.server.access.log main; |
12 |
13 |
location / { |
14 |
proxy_pass http: //big_server_com; |
15 |
} |
16 |
} |
17 |
} |
—————————————–
Nginx 安置後只有一個法式文件,本身並不供給各種辦理法式,它是利用參數和體系旌旗燈號機制對 Nginx 歷程本身舉行節制的。 Nginx 的參數包羅有以下幾個:
-c :利用指定的設置裝備擺設文件而不是 conf 目次下的 nginx.conf 。
-t:測試設置裝備擺設文件是否準確,在運行時必要從頭加載設置裝備擺設的時辰,此號令非常主要,用來檢測所點竄的設置裝備擺設文件是否有語法錯誤。
-v:表現 nginx 版本號。
-V:表現 nginx 的版本號以及編譯狀況信息以及編譯時的參數。
比方咱們要測試某個設置裝備擺設文件是否謄寫準確,咱們能夠利用如下號令
Nginx 撐持下表中的旌旗燈號:
旌旗燈號名
感化形貌
TERM, INT
快速封閉法式,中斷當前正在處置的懇求
QUIT
處置完當前懇求後,封閉法式
HUP
從頭加載設置裝備擺設,並開啓新的事情歷程,封閉就的歷程,此操縱不會間斷懇求
USR1
從頭打開日記文件,用於切換日記,比方每天天生一個新的日記文件
USR2
光滑進級可實行法式
WINCH
自在封閉事情歷程
有兩種體例來經由過程這些旌旗燈號去節制 Nginx,第一是經由過程 logs 目次下的 nginx.pid 檢察當前運行的 Nginx 的歷程 ID,經由過程 kill – XXX
來節制 Nginx,此中 XXX 即是上表中列出的旌旗燈號名。如果您的體系中只有一個 Nginx 歷程,那您也能夠經由過程 killall
號令來完成,比方運行 killall – s HUP nginx
來讓 Nginx 從頭加載設置裝備擺設。
先來看一個現實的設置裝備擺設文件:
上 面是一個現實網站的設置裝備擺設實例,此中灰色筆墨爲設置裝備擺設申明。上述設置裝備擺設中,起首咱們界說了一個 location ~ ^/NginxStatus/,如許經由過程 http://localhost/NginxStatus/ 就能夠監控到 Nginx 的運行信息,表現的內容以下:
NginxStatus 表現的內容意思以下:
經由過程正則表達式,咱們可以讓 Nginx 辨認出各種靜態文件,比方 images 路徑下的所有懇求能夠寫爲:
而下面的設置裝備擺設則界說了幾種文件範例的懇求處置體例。
對付比方圖片、靜態 HTML 文件、js 劇本文件和 css 樣式文件等,咱們希望 Nginx 直接處置並返回給欣賞器,如許能夠大大的加速網頁欣賞時的速率。是以對付這類文件咱們必要經由過程 root 指令來指定文件的存放路徑,同時因爲這類文件並不常點竄,經由過程 expires
指令來節制其在欣賞器的緩存,以削減不須要的懇求。 expires
指令能夠節制 HTTP 應答中的「 Expires 」和「 Cache-Control 」的頭標(起到節制頁面緩存的感化)。您能夠利用比方如下的格局來謄寫 Expires:
Nginx 本身並不撐持此刻風行的 JSP、ASP、PHP、PERL 等動態頁面,但是它能夠經由過程反向代辦署理將懇求發送到後真個辦事器,比方 Tomcat、Apache、IIS 等來完成動態頁面的懇求處置。前面的設置裝備擺設示例中,咱們起首界說了由 Nginx 直接處置的一些靜態文件懇求後,其餘所有的懇求經由過程 proxy_pass 指令傳送給後真個辦事器(在上述例子中是 Tomcat)。最簡略的 proxy_pass
用法以下:
這裏咱們沒有利用到集羣,而是將懇求直接送到運行在 8080 端口的 Tomcat 辦事上來完成近似 JSP 和 Servlet 的懇求處置。
當頁面的拜候量非常大的時辰,往往必要多個應用辦事器來配合負擔動態頁面的實行操縱,這時咱們就必要利用集羣的架構。 Nginx 經由過程 upstream
指令來界說一個辦事器的集羣,最前面阿誰完備的例子中咱們界說了一個名爲 tomcats 的集羣,這個集羣中包羅了三臺辦事器共 6 個 Tomcat 辦事。而 proxy_pass 指令的寫法釀成了:
在 Nginx 的集羣設置裝備擺設中,Nginx 利用最簡略的均勻分派法則給集羣中的每一個節點分派懇求。一旦某個節點失效時,大概從頭起效時,Nginx 城市非常實時的處置情況的轉變,以包管不會影響到用戶的拜候。
盡 管整個法式包只有五百多 K,但麻雀雖小、五臟俱全。 Nginx 官方供給的各種功效模塊一應俱全,連繫這些模塊能夠完備各種百般的設置裝備擺設要求,比方:壓縮、防盜鏈、集羣、FastCGI、流媒體辦事器、 Memcached 撐持、URL 重寫等等,更關頭的是 Nginx 擁有 Apache 和其餘 HTTP 辦事器沒法對比的高機能。您乃至能夠在不轉變原有網站的架構上,經由過程在前端引入 Nginx 來晉升網站的拜候速率。
本文只是簡略先容了 Nginx 的安置以及常見的根基的設置裝備擺設和利用,更多關於 Nginx 的信息請閱讀文章背面的參考資本。在這裏要非常感激個人伴侶——陳磊(chanix@msn.com),他一貫在作 Nginx 的中文 WIKI(http://wiki.codemongers.com/NginxChs),同時也是他先容給我這麼好的一款軟件。
如果您的網站是運行在 Linux 下,如果您並無利用一些非常龐大的而且肯定 Nginx 沒法完成的功效,那您應該嚐嚐 Nginx 。
若是你關注過nginx,一定知道nginx這個軟件有什麼用的,若是你的網站訪問量愈來愈高,一臺服務器已經沒有辦法承受流量壓力,那就增多幾臺 服務器來作負載吧。作網站負載能夠買硬件設備來實現,好比F5,不過價格就幾十萬到上百萬,夠貴,本文介紹作網站負載的軟件是免費的,nginx目前好多 門戶網站與大訪問量的網站都在使用作爲HTTP服務器,因此nginx是很是優秀的,下面介紹作負載測試吧。 環境: (2臺服務器) 第一臺: CPU:Inter(R) Pentium(R) 4 CPU 2.8G 內存:1G 系統:windows 7 IIS: IIS 7 nginx:nginx/Windows-0.8.22 IP:172.10.1.97 環境:本地 第二臺: CPU:Inter(R) Pentium(R) 4 CPU 3.0G 內存:2G 系統:windows Server 2003 IIS: IIS 6 IP:172.10.1.236 環境:遠程
說明: 本次測試,軟件nginx放在本地(172.10.1.97),也就是說放在域名綁定的那臺服務器,這臺服務器的IIS不能使用80端口,由於等下nginx軟件要使用80這個端口。 下載nginx的地址以下: nginx下載:http://nginx.net/ 本次測試使用的版本下載:nginx/Windows-0.8.22
下載解壓到C:,把目錄名改爲nginx
好,下面進入實踐:
第一:
在本地(172.10.1.97)這臺服務器IIS建立一個網站,使用端口爲808,以下圖:
IIS 網站綁定設置圖
第二:
在遠程172.10.1.236的IIS建立一個網站,使用端口爲80,以下圖:
遠程IIS綁定設置圖
第三:
好了,以上已經設置好兩臺服務器的IIS了,下面配置nginx軟件來實現網站負載均衡,打開以下文件:
C:\nginx\conf\nginx.conf
一、找到內容server {
在這上面加入以下內容:
upstream xueit.com { server 172.10.1.97:808; server 172.10.1.236:80; }
(這是負載切換使用的服務器網站IP)
二、找到location / { root html; index index.html index.htm; }
把內容更改以下:
location / { proxy_pass http://xueit.com/; proxy_redirect default; }
三、找到server { listen 80; server_name localhost;
把內容改爲以下:
server { listen 80; server_name 172.10.1.97;
(這是監聽訪問域名綁定那臺服務器80端口的請求)
好,在這裏就這麼簡單配置好了,下面看下以上3步配置的圖:
負載配置圖
第四:
都配置好了,下面啓動nginx這軟件
進入命令提示符CMD,進入c:\nginx>,輸入nginx命令,以下圖:
啓動nginx
這時候,系統進程有兩個nginx.exe進程,以下圖:
系統nginx進程
中止nginx運行輸入nginx -s stop 便可
第五:
通過以上的配置,如今咱們看下負載效果:
在本地(172.10.1.97)這服務器打開IE,輸入:http://172.10.1.97/
第一次打開網站的結果圖:
第一次運行網站圖
再刷新一下網頁,出現的結果圖:
很好,網站已經負載成功。
通過此次測試,實現網站負載不再是難事了。也不用購買很是貴的硬件設備了。網上介紹說nginx軟件能夠處理併發上萬,因此絕對是個很是不錯的選擇。
若是網站訪問量很是大,能夠專門用一臺服務器跑nginx,其它服務器跑網站程序(幾臺服務器的程序都是同樣的),這樣負載就沒有太大問題,若是再不行,把網站一些欄目作一個2級域名,2級域名一樣作負載,這樣更厲害了吧。
nginx軟件在linux上跑性能比在windows上跑要好,因此作負載能夠用linux跑nginx,.net開發的網站放到windows服務器IIS上。
在linux下配置nginx能夠看下這篇文章http://www.xueit.com/html/2009-11-04/29-964604915343.html
轉自學IT網:http://www.xueit.com/nginx/show-4866-3.aspx
nginx的upstream目前支持5種方式的分配
一、輪詢(默認)
每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。
二、weight
指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。
例如:
1
2
3
4
|
upstream bakend {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
|
三、ip_hash
每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。
例如:
1
2
3
4
5
|
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
|
四、fair(第三方)
按後端服務器的響應時間來分配請求,響應時間短的優先分配。
1
2
3
4
5
|
upstream backend {
server server1;
server server2;
fair;
}
|
五、url_hash(第三方)
按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。
例:在upstream中加入hash語句,server語句中不能寫入weight等其餘的參數,hash_method是使用的hash算法
1
2
3
4
5
6
|
upstream backend {
server squid1:3128;
server squid2:3128;
hash
$request_uri
;
hash_method crc32;
}
|
tips:
upstream bakend{#定義負載均衡設備的Ip及設備 狀態
1
2
3
4
5
6
|
ip_hash;
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
|
在須要使用負載均衡的server中增長
proxy_pass http://bakend/;
每一個設備的狀態設置爲:
1.down 表示單前的server暫時不參與負載
2.weight 默認爲1.weight越大,負載的權重就越大。
3.max_fails :容許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤
4.fail_timeout:max_fails次失敗後,暫停的時間。
5.backup: 其它全部的非backup機器down或者忙的時候,請求backup機器。因此這臺機器壓力會最輕。
nginx支持同時設置多組的負載均衡,用來給不用的server來使用。
client_body_in_file_only 設置爲On 能夠講client post過來的數據記錄到文件中用來作debug
client_body_temp_path 設置記錄文件的目錄 能夠設置最多3層目錄
location 對URL進行匹配.能夠進行重定向或者進行新的代理 負載均衡
在應用程序運行的過程當中總會有一些常常須要訪問而且變化不頻繁的數據,若是每次獲取這些數據都須要從數據庫或者外部文件系統中去讀取,性能確定會受到影響,因此一般的作法就是將這部分數據緩存起來,只要數據沒有發生變化每次獲取這些數據的時候直接從內存中區獲取性能確定會大大地提升。在.NET中提供了一個Cache類能夠實現這些功能。在ASP.NET中能夠經過HttpContext 對象的 Cache 屬性或 Page 對象的 Cache 屬性來獲取這個類的實例。 在大部分狀況下咱們均可以使用Cache類來提升ASP.NET的性能,可是使用Cache類也有一些不足,好比咱們不能指定Cache類所佔用的內存的大小,此外在Cache中緩存的數據沒有辦法被另外一臺機器上的應用程序直接訪問,所以在本文中提出另外一種數據緩存方案,那就是使用分佈式緩存。分佈式緩存的特色是緩存的數據沒必要和應用程序在同一臺機器上,從而大大加強了緩存數據的複用性。在本文介紹如何在.NET應用中使用Memcache做爲分佈式緩存。 Memcached介紹 Memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 爲首開發的一款軟件。在一般的應用中咱們都會將數據保存到數據庫中,每次須要的時候都會從數據庫去查詢這些數據,若是應用程序的用戶不少就會出現大量併發訪問數據庫的狀況,這樣就會增長應用程序的響應時間,使用Memcached就能夠有效解決這個問題。memcached是高性能的分佈式內存緩存服務器。通常的使用目的是,經過緩存數據庫查詢結果,減小數據庫訪問次數,以提升動態Web應用的速度、提升可擴展性。像大名鼎鼎的Facebook網站就使用了Memcached。周公稍後會提供Windows平臺上32位和64位的Memcached程序。 爲了提升性能,Memcached中的數據都保存在Memcached內置的存儲空間中。由於當Memcached重啓會致使其中的數據所有丟失,因此通常的方案是將數據保存在數據庫中,每次請求數據的時候先查看在Memcached有沒有緩存,若是有就直接從緩存中取出數據;若是沒有,就從數據庫中取出數據返回給應用程序並將請求的數據緩存到Memcached中,這樣一來下次請求相同的數據就能夠直接從Memcached中讀取而不用再去查數據庫了;一旦對數據有更新,同時更新數據庫和Memcached。 Memcached是一個命令行窗口程序,能夠在命令行窗口中啓動也能夠封裝在系統服務中啓動。在啓動Memcached時須要提供一些必須的參數,指定Memcached運行時監聽的端口和最大使用的內存大小等。若是緩存的數據大小超過指定內存,那麼Memcached就會按照LRU(Least Recently Used)算法自動「刪除」不使用的緩存(標記爲失效),新增的緩存數據就能夠使用這些標記爲失效的數據所佔用的內存,這樣就不用擔憂Memcached超出所指定內存的問題。此外,爲了提升性能,在緩存數據過時後Memcached並非從物理內存中刪除緩存的數據,僅僅在取出改數據的時候檢查它是否已通過了有效期。 目前有多種平臺的Memcached版本,好比Linux、FreeBSD、Solaris (memcached 1.2.5以上版本)、Mac OS X及Windows平臺,在Windows平臺上還有32位和64位版本。 Memcached有一套協議,利用這套協議能夠對Memcached進行數據存取和查看Memcached的狀態,不少程序語言都依據這套協議來操做Memcached,好比PHP、Java、C、C++及C#等。 獲取了對應平臺的Memcached版本就能夠運行Memcached了。在這裏僅以Windows平臺上的32位Memcached爲例。 運行Memcached: memcached.exe -p 11121 -m 64 上面的命令是運行Memcached,指定它的監聽端口是11121(這是它的默認端口,能夠指定爲其它大於1024的端口,由於小於1024的端口已經有了默認指定),最大使用內存爲64m,若是啓用了Windows防火牆,切記要在防火牆上打開這個端口。 在調試程序時能夠使用下面的命令行來運行: memcached.exe -p 11121 -m 64 -vv 這樣就會看到以下的結果: slab class 1: chunk size 88 perslab 11915 slab class 2: chunk size 112 perslab 9362 slab class 3: chunk size 144 perslab 7281 slab class 4: chunk size 184 perslab 5698 slab class 5: chunk size 232 perslab 4519 slab class 6: chunk size 296 perslab 3542 slab class 7: chunk size 376 perslab 2788 slab class 8: chunk size 472 perslab 2221 slab class 9: chunk size 592 perslab 1771 slab class 10: chunk size 744 perslab 1409 slab class 11: chunk size 936 perslab 1120 slab class 12: chunk size 1176 perslab 891 slab class 13: chunk size 1472 perslab 712 slab class 14: chunk size 1840 perslab 569 slab class 15: chunk size 2304 perslab 455 slab class 16: chunk size 2880 perslab 364 slab class 17: chunk size 3600 perslab 291 slab class 18: chunk size 4504 perslab 232 slab class 19: chunk size 5632 perslab 186 slab class 20: chunk size 7040 perslab 148 slab class 21: chunk size 8800 perslab 119 slab class 22: chunk size 11000 perslab 95 slab class 23: chunk size 13752 perslab 76 slab class 24: chunk size 17192 perslab 60 slab class 25: chunk size 21496 perslab 48 slab class 26: chunk size 26872 perslab 39 slab class 27: chunk size 33592 perslab 31 slab class 28: chunk size 41992 perslab 24 slab class 29: chunk size 52496 perslab 19 slab class 30: chunk size 65624 perslab 15 slab class 31: chunk size 82032 perslab 12 slab class 32: chunk size 102544 perslab 10 slab class 33: chunk size 128184 perslab 8 slab class 34: chunk size 160232 perslab 6 slab class 35: chunk size 200296 perslab 5 slab class 36: chunk size 250376 perslab 4 slab class 37: chunk size 312976 perslab 3 slab class 38: chunk size 391224 perslab 2 slab class 39: chunk size 489032 perslab 2 <96 server listening <112 server listening <116 send buffer was 8192, now 268435456 <116 server listening (udp) 在客戶端還能夠經過telnet來查看和操做Memcached,前提是服務器端和客戶端都支持Telnet協議,在Windows7和Windows2008中默認都不支持,須要在控制面板中安裝和啓用。 首先打開控制面板,而後點擊「打開或關閉Windows功能」,以下圖所示:
點擊「打開或關閉Windows功能」以後會看到當前系統啓用的功能的狀態,根據當前機器選擇打開Telnet服務器端或者客戶端功能,以下圖所示: 通過上面的操做以後就能夠在客服端遠程查看Memcached的狀態或者操做Memcached了。下面的命令就是鏈接到Memcached: telnet localhost 11121 鏈接以後會出現一個命令行窗口,在這個命令行窗口中輸入"stats"就能夠看到當前Memcached的狀態,以下就是剛剛啓動的Memcached的狀態數據: STAT pid 852 STAT uptime 1399 STAT time 1300979378 STAT version 1.2.5 STAT pointer_size 32 STAT curr_items 0 STAT total_items 0 STAT bytes 0 STAT curr_connections 3 STAT total_connections 5 STAT connection_structures 4 STAT cmd_get 0 STAT cmd_set 0 STAT get_hits 0 STAT get_misses 0 STAT evictions 0 STAT bytes_read 23 STAT bytes_written 415 STAT limit_maxbytes 67108864 STAT threads 1 END 經過這個數據咱們就能夠了解Memcached的狀態了。 這些數據所表明的意義以下: pid:32u,服務器進程ID。 uptime:32u, 服務器運行時間,單位秒。 time :32u, 服務器當前的UNIX時間。 version :string, 服務器的版本號。 curr_items :32u, 服務器當前存儲的內容數量 Current number of items stored by the server total_items :32u, 服務器啓動以來存儲過的內容總數。 bytes :64u, 服務器當前存儲內容所佔用的字節數。 curr_connections :32u, 鏈接數量。 total_connections :32u, 服務器運行以來接受的鏈接總數。 connection_structures:32u, 服務器分配的鏈接結構的數量。 cmd_get :32u, 取回請求總數。 cmd_set :32u, 存儲請求總數。 get_hits :32u, 請求成功的總次數。 get_misses :32u, 請求失敗的總次數。 bytes_read :64u, 服務器從網絡讀取到的總字節數。 bytes_written :64u, 服務器向網絡發送的總字節數。 limit_maxbytes :32u, 服務器在存儲時被容許使用的字節總數。 上面的描述中32u和64u表示32位和64位無符號整數,string表示是string類型數據。
在.NET中應用Memcached 有不少.NET版本的Memcached客戶端程序,在這裏周公使用的Enyim Memcached,能夠到https://github.com/enyim/EnyimMemcached/下載最新的版本。 要想在項目中使用Memcached,須要添加對Enyim.Caching.dll的應用。除此以外,咱們可能還須要在config文件中配置Memcached的信息(也能夠在程序代碼中指定,但那樣不靈活),以下就是一個config文件配置的例子:
<?xmlversion="1.0"encoding="utf-8"?> <configuration> <configSections> <sectionGroupname="enyim.com"> <sectionname="memcached"type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/> </sectionGroup> </configSections> <enyim.comprotocol="Binary"> <memcached> <servers> <addaddress="localhost"port="11121"/> <!--<addaddress="localhost"port="11131"/> <addaddress="localhost"port="11141"/> <addaddress="localhost"port="11151"/>--> </servers> <socketPoolminPoolSize="10"maxPoolSize="100"connectionTimeout="00:00:10"deadTimeout="00:02:00"/> </memcached> </enyim.com> </configuration>
若是咱們配置了多個Memcached的實例,能夠想上面的註釋部分那樣在<servers>節點下添加多個Memcached的實例配置。 這裏須要說明的是若是咱們須要向Memcached中添加自定義數據類型時,咱們須要將該數據類型添加上[Serializable]標記。 下面是一個Enyim Memcached的例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Enyim.Caching; using Enyim.Caching.Memcached; /* * 做者:周公(zhoufoxcn) * 日期:2011-03-24 * 原文出處:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com * 版權說明:本文能夠在保留原文出處的狀況下使用於非商業用途,周公對此不做任何擔保或承諾。 * */ namespace MemcachedMonitor { [Serializable] publicclass Person { publicint UserId { get; set; } publicstring UserName { get; set; } } publicclass MemcachedDemo { privatestatic MemcachedClient client = new MemcachedClient("enyim.com/memcached"); publicvoid SetDemo() { Person person = new Person { UserId = 1, UserName = "李剛" }; //不帶過時時間的存儲,Memcached將根據LRU來決定過時策略 bool success=client.Store(StoreMode.Add, person.UserName, person); //帶過時時間的緩存 //bool success = client.Store(StoreMode.Add, person.UserName, person, DateTime.Now.AddMinutes(10)); Console.WriteLine("存儲[{0}]的結果:{1}", person.UserName, success); } publicvoid GetDemo() { Person person = client.Get<Person>("李剛"); if (person != null) { Console.WriteLine("取回[{0}]的結果——UserId:{1},UserName:{2}", "李剛", person.UserId, person.UserName); } else { Console.WriteLine("取回[{0}]失敗!", "李剛"); } } publicvoid MultiGetDemo() { List<string> personNameList = new List<string>(); for (int i = 0; i < 10; i++) { personNameList.Add("李剛00" + i); } //批量獲取,只經過一次網絡通信就取回全部personNameList中的指定的全部數據 IDictionary<string, object> resultList = client.Get(personNameList); Person person; foreach (KeyValuePair<string, object> item in resultList) { person = item.Value as Person; if (person != null) { Console.WriteLine("取回[{0}]的結果——UserId:{1},UserName:{2}", "李剛", person.UserId, person.UserName); } else { Console.WriteLine("取回[{0}]失敗!", "李剛"); } } } } }
說明:若是須要一次從Memcached中取回多個緩存的數據,能夠參考MultiGetDemo()方法,這樣一來只須要一次網絡通信就能夠取回所有數據,減小網絡鏈接時間。此外,在Memcached客戶端能夠使用Text或者Binary協議,通過周公千萬次測試比較,使用Binary協議性能略高於使用Text協議。在上面的config文件中周公就配置使用了Binary協議。 總結,使用Memcached這樣的分佈式緩存能夠大大提升應用程序的性能,通過周公測試,正確使用Memcached能夠將單臺服務器的併發訪問數從20提升到1000左右,也就是提升了50倍,這是一個至關客觀的提高!限於篇幅,關於Memcached的更深更詳細的用法沒有在本篇介紹,此文算做拋磚引玉,讀者能夠自行參考其它相關資料。
周公
這兩天和一朋友討論這樣一個問題:你認爲公司的架構怎樣,有哪些缺點? 其實在回答這個問題以前,有一些概念須要搞清楚,那就是什麼是架構? 目前對於架構還並未有一個統一的標準及定義,因此架構的概念就會由於每一個人不一樣而不一樣,若是嘗試問一百人關於架構的理解,可能有一百個答案。 我開始作基礎架構到如今已經有兩年時間了,但對架構的理解也並不深,有時感受無從提及,總覺的是一個無形的東西。下面我就總結下我我的對架構的理解,下面純屬我的理解。 第一:架構分層,這裏我將架構分爲如下兩層: 1:基礎架構,這也是因爲架構自己的一大特色,具有基礎性,它的基礎性能夠這樣理解:一般涉及解決各類關鍵問題的通用方案,即重用性概念,以及涉及系統設計中影響深遠的各類方案決策,影響深遠說明一旦肯定再次修改的代碼每每過大。 示例1:各類中間件,中間件就是對某些組件的一種包裝,好比咱們的系統在訪問數據庫是須要同時支持多種類型的數據庫,好比SQL SERVER,MYSQL ,ORCAL,等等,爲了在各類系統訪問數據時造成統一的管理,咱們能夠編寫一個通用化的組件來解決此種問題,達到管理容易,編寫簡單的目的。 示例2:各類通用服務,例如爲全部項目提供分佈式緩存系統,全部的項目數據均可以經過它來完成數據的緩存,以增強系統性能。 示例3:面向服務概念SOA的實現,經過SOA能夠使複雜的業務系統獲得解耦。 示例4:項目的分層,好比分幾層,每層的功能,想到之間的關係等。 2:對於全局的組織,全局的結構控制,爲特定需求提供特殊解決方案,這類重在設計思惟。 示例1:如何將複雜系統化分紅N個子系統; 示例2:如何實現系統的非功能性需求,好比並發性,穩定性,可擴展性等等; 示例3:設計方案的選擇,評估等。
下面是我對於架構的分層結構圖:
的。 1:全局組織和全局結構 2:數據存取協議 3:各類組件的功能定義 4:軟件的物理部署 5:設計方案的選擇 6:架構評估與實現 第三:架構都有哪些重要做用 1:它是項目干係人進行交流的手段。它表明了系統公共的最高層次抽象,系統相關的很大部分人員都可將它做爲互相理解的基礎,以此達成共識; 2:上面說到架構具有基礎性,因此具有可傳遞性與可重性的特色,架構層次上的重用性與代碼級的重用性有本質區別,它意味着架構的決策能在類似的需求中出如今多個系統中,體如今決策,而不是實現細節; 3:它是早期設計決策的體現,這些決策比之後的開發,設計以及編碼之後期的維護工做重要的多。 第四:須要注意的幾個觀點,爲了更加正確的認識架構,須要正確對待相似下面的觀點 1:框架(Framework),框架在必定程度上容易讓人理解爲架構,其實框架只是架構內容中的一種,代碼級別的組件,不能認爲搞搞框架就是架構的所有了。好比咱們寫的各類是間件,爲某種特定需求開發的某種具有特殊功能的組件。
2:寫大量的中間件是架構嗎?是,但它也只屬於架構的一小部分,說的準確點是框架的一部分;
3:SOA算架構嗎,固然算,它就是上面我理解的基礎架構一部分,但這些均只是架構的冰山一角;
4:某公司成功的架構模式能直接移置到另一家公司的項目中嗎?這個問題不能武斷,我認爲若是項目類型大體相同,移置的可能性會比較大,不然就須要慎重,好比咱們不能將一個C/S架構上的思想直接移到到B/S架構的項目上,它們之間的差距是很是大的,即便勉強移置,也須要很是明確之後須要改進的地方,好比說性能問題,原來的架構所應用的環境對性能要求不高,因此運行良好,但若是不變的移置到互聯網項目了,鬱悶的事就會出來了。 第五:如何表示軟件架構,能夠經過很是經典的4+1視圖模型來從5個不一樣的視角來反映系統的總體架構: 1:邏輯視圖,主要體現的是系統需求,在邏輯視圖中,系統會被抽象成一堆的功能抽象,這些抽象主要是來自需求。功能分解有兩個功能,第一:進行功能分析;第二:能夠提取不一樣功能模塊中可重用點。 2:進程視圖,它主要體現系統中的一些非功能性需求,側重於系統運行時的特徵,例如:系統的性能,穩定性,申縮性,併發性,容錯能力,分佈式等等。 3:物理視圖,它主要考慮的是系統的部署問題,好比部署在什麼樣的硬件上,解決系統的拓撲結構,通訊等問題,好比數據庫的備份容災方案等。 4:開發視圖,主要解決系統的組織以及管理,好比如何劃分子系統,如何編寫要重用性組件等。 5:場景視圖,它聯繫以上四個視圖,是系統活動的重要抽象,它用來解決在特定場景上分析一個特定的視圖。
下面是它們的關係圖
總結:架構是一個大概念,不會有統一的定義,每一個公司每一個項目都會對架構產生影響,只有根據實際狀況出發,纔有可能開發出最適合本身公司項目的架構模式。
2011-10-23 C#類特性和屬性特性 using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Reflection; namespace ConsoleApplication6 { /// <summary> /// AttributeTargets.Class能夠對類應用屬性 /// Inherited可否由派生類或重寫成員繼承 /// AllowMultiple可否爲一個程序元素指定多個指示屬性實例 /// 也就是說AllowMultiple=false 對於一個類型,該特性只能用一次 /// 若一個Class類型前面出現多個TableAttribute,則會出現編譯錯誤 /// </summary> [AttributeUsage(AttributeTargets.Class,Inherited=true,AllowMultiple=false)] public class TableAttribute : Attribute { private string _tableName; public TableAttribute() { } public TableAttribute(string tableName) { this._tableName = tableName; } public string TableName { get { return this._tableName; } set { this._tableName = value; } } } /// <summary> /// 列特性 /// AttributeTargets.Property能夠對屬性應用特性 /// </summary> [AttributeUsage(AttributeTargets.Property,Inherited=false,AllowMultiple=false)] public class ColumAttribute : Attribute { private string _columName; private DbType _dbType; public ColumAttribute() { } public ColumAttribute(string columName) { this._columName = columName; } public ColumAttribute(string columName, DbType dbType) { this._columName = columName; this._dbType = dbType; } public string ColumName { get { return this._columName; } set { this._columName = value; } } public DbType DbTypeAttr { get { return this._dbType; } set { _dbType = value; } } } [Table("User")] public class User { [Colum("userId",DbType.Int32)] public int UserId { get; set; } [Colum("userName", DbType.String)] public string UserName { get; set; } } class Program { static void Main(string[] args) { User u = new User(); u.UserId = 6; u.UserName = "allen"; Type myObjType = u.GetType(); Dictionary<string,string> columName = new Dictionary<string,string>(); //獲取自定義特性 object temp = myObjType.GetCustomAttributes(typeof(TableAttribute),false).First(); TableAttribute myAttr = temp as TableAttribute; Console.WriteLine("表名:{0}", myAttr.TableName); Console.WriteLine("列的名稱和值:"); foreach (PropertyInfo pi in myObjType.GetProperties()) { object attr = pi.GetCustomAttributes(false).First(); ColumAttribute cattr = attr as ColumAttribute; Console.WriteLine("{0}:{1}",cattr.ColumName,pi.GetValue(u,null)); } Console.ReadKey(); } } }
轉載自:http://www.cnblogs.com/ITangle/archive/2011/12/11/2283901.html