web service

 

Web Service

Introduction

Nginx: web server(static contents), web reverse proxy(http,mail)php

varnish, squid, 作緩存服務器css

​ nginx: cache(disk)html

​ httpd: cache(memory, disk)前端

haproxy: tcp reverse proxy, http reverse proxyjava

ats: apache traffic servernode

MogileFS, 圖片存儲分佈式文件系統mysql

NoSQL(MongoDB) 文檔存儲數據庫linux

DMA: 直接內存訪問, 找一段連續的內存地址. DMA控制芯片. 講數據從磁盤上加載至內存中. DMA芯片具備總線的控制權android

HTTP Protocal

request ---> response

請求報文:

<method> <URL> <version>
<hearders>
...
<body>

響應報文:

<version> <status code> <reason phrase>
<headers>
...
<body>

響應碼:

	1xx: 狀態信息碼
	2xx: 成功響應碼
		200
	3xx: 重定向
		301
		302
		304
	4xx: 客戶端錯誤
	5xx: 服務器端錯誤

html, css(cascading style sheet)級聯樣式表,實現豐富的頁面元素展現 js,jpg,png,gif

響應效率: 靜態 > 動態 > database

note: LNMP中,php與nginx一塊兒使用,必須工做在FPM模式下,fast cgi

stateless: 無狀態

​ web page: web object 組成

​ http: 80/tcp

​ tcp 三次握手,四次斷開

​ keepalive: 保持鏈接狀態

​ 時間: timeout

​ 數量:

​ cookie: 服務器端返回給客戶端惟一的標示 set-cookie. 用戶信息的追蹤,讓用戶的訪問狀態被服務器追蹤

​ session保持:session綁定,反均衡,session無高可用

​ session複製:服務器資源消耗過大,網絡資源受限

​ session服務器:服務器自身的單點故障,因此要使用高可用

​ lvs session綁定:

​ sh算法: 基於源IP作綁定

​ presistent connection: 持久鏈接,一樣是基於源IP作綁定

​ cookie均衡:Tengine

IO模型:

內核將數據從硬盤調度到內核內存,數據從內核內存到用戶空間的進程內存。第二階段纔是真正的I/O調用執行的階段。第一階段是磁盤IO

一般所說的同步

​ 同步阻塞 : 數據從磁盤到內核內存,再從內核內存到用戶進程內存都是阻塞的狀態 ​ 同步非阻塞: 用戶進程發起I/O請求,數據從磁盤到內核內存,用戶進程處於忙等狀態,數據從內核內存到進程內存是阻塞狀態 ​ IO複用: select; poll. 內核空間用來檢測內核空間的調用是否完成的機制。阻塞在select和poll上。用戶空間經過調用select(),poll()函數來返回內核空間的IO調用狀態(包括已經完成的和未完成的) ​ 事件通知:無需輪尋。內核通知用戶空間數據準備階段完成。經過call back,回調機制知道是哪一個進程發起的調度 ​ 異步:用戶空間發起調度之後,全部工做都由內核來完成。只能磁盤I/O作異步,網絡I/O沒法作到

若是連第二個階段數據複製也不用作固然最好,內核內存空間直接共享給用戶空間的機制,稱爲內存共享。

若是連數據到內核內存也不須要了,則能夠使用MMAP,內存映射機制。直接在磁盤上將數據劃分爲頁面格式,直接把一個文件直接映射到內核內存中,內核再將映射內容內存共享給用戶進程

mmap: 數據由磁盤直接以頁面形式映射進入到內存中

Prefork使用select(), 最大鏈接數不能超過1024個

Direct IO: 將緩存和緩衝機制關閉,則能夠省去數據從磁盤copy到內核內存的過程。使用進程直接訪問磁盤的過程

MPM:

​ prefork: 一個進程響應一個請求, 1024

​ worker: 一個線程響應一個請求, 多進程,一個進程生成多個線程(性能並無改進,併發鏈接數並無改進)

​ event: 基於事件驅動來實現, epoll()

 

併發編程:處理併發用戶請求

單進程模型:串行方式響應, 阻塞

多進程模型:prefork, 一個進程響應一個用戶請求,金成亮大, 進程間切換次數過多, 併發使用多個進程實現;一個master,多個worker. 每一個進程的地址空間是獨立的, 不少空間是重複的數據, 因此內存的使用效率較低.

多線程模型:worker, 一個進程生成多個線程,一個線程響應一個用戶請求,併發使用多個線程實現.

線程依然須要切換, 輕量級切換.

​ 同一個進程的線程能夠共享進程的諸多資源, 好比打開的文件,傳入的信號等等

​ 對內存的需求較之進程略有降低.

​ 快速切換時, 會帶來線程抖動

多進程多線程模型: 使用多進程生成多線程,n進程,n*m個線程

多線程, N個請求: 一個線程響應多個請求.

事件模型:event, 一個線程直接響應多個用戶請求。基於事件驅動機制來維持多個用戶請求. epoll())

​ 多路IO, IO複用

 

Nginx

Nginx: engine x

Apache: MPM

​ prefork: 一個進場相應一個請求

​ event(2.4之後):

c10k問題,併發超過10k. 問題

Nginx特性

​ 基本功能:

​ 靜態資源的web服務器,自動緩存打開的文件描述符

​ 反向代理服務器,緩存、負載均衡

​ 支持FastCGI協議,能更跟php的FPM服務器結合

​ 模塊化機制,非DSO機制,過濾器gzip,SSI和圖像大小調整等

​ 支持SSL

​ 擴展功能:

​ 基於名稱和IP作虛擬主機

​ 支持keepalive

​ 支持平滑配置更新活程序版本升級

​ 定製訪問日誌,支持使用日誌緩存以提升性能

​ 支持URL rewrite,url地址重寫

​ 支持路徑別名

​ 文件基於IP及用戶的認證

​ 支持速率限制,併發限制等

Tengine, 淘寶發行版. 整合了不少功能

Nginx架構

一、master--worker

​ 一個master,生成一個或多個worker

​ 通常而言worker的個數小於CPU的物理核心數,爲了下降CPU的上下文切換

二、事件驅動:kqueue, epoll, /dev/poll

​ 消息通知:select, poll, rt signals

三、支持sendfile,從內核直接產生響應,而無需用戶空間的參與。sendfile64,支持的單個文件大小

四、支持AIO,支持純異步IO

五、支持mmap

nginx: 非阻塞模型、事件驅動、一個master多個worker,一個workder響應多個用戶請求

Nginx的模塊類別

  • 核心模塊
  • 標準http模塊
  • 可選http模塊
  • 郵件模塊
  • 第三方擴展模塊

Nginx安裝

Nginx的配置文件:

​ main配置段

​ http {}

​ events{}

配置參數須要以分號結尾,語法格式:參數名 value1 [value2 ...];

​ 還支持使用變量:一、模塊內置變量 二、用戶自定義變量 set var_name value

Nginx基本配置的類別:

​ 用於調試、定位問題

​ 正常運行的必備配置

​ 優化性能的配置

​ 事件類的配置

worker進程應該以普通用戶身份運行:nginx用戶、nginx組

​ HTTP的方法:GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE

準備工做:

須要安裝pcre-devel,重寫引擎. Perl-compatible regular expressions

編譯安裝

添加用戶

groupadd -r nginx
useradd -r -g nginx nginx

編譯並安裝

 
 
 
 
 
AخA
 
 
 
./configure \
  --prefix=/usr \
  --sbin-path=/usr/sbin/nginx \
  --conf-path=/etc/nginx/nginx.conf \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx/nginx.pid  \
  --lock-path=/var/lock/nginx.lock \
  --user=nginx \
  --group=nginx \
  --with-http_ssl_module \
  --with-http_flv_module \
  --with-http_stub_status_module \
  --with-http_gzip_static_module \
  --http-client-body-temp-path=/var/tmp/nginx/client/ \
  --http-proxy-temp-path=/var/tmp/nginx/proxy/ \
  --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
  --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
  --http-scgi-temp-path=/var/tmp/nginx/scgi \
  --with-debug \
  --with-pcre|tee ~/nginx.out
 

--http_flv_module: flash流媒體

--temp-path: 臨時緩存目錄

--uwsgi: 爲Python開發的CGI接口

Configuration Summary

  + using system PCRE library
  + using system OpenSSL library
  + md5: using OpenSSL library
  + sha1: using OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr"
  nginx binary file: "/usr/sbin/nginx"
  nginx modules path: "/usr/modules"
  nginx configuration prefix: "/etc/nginx"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/var/run/nginx/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/tmp/nginx/client/"
  nginx http proxy temporary files: "/var/tmp/nginx/proxy/"
  nginx http fastcgi temporary files: "/var/tmp/nginx/fcgi/"
  nginx http uwsgi temporary files: "/var/tmp/nginx/uwsgi"
  nginx http scgi temporary files: "/var/tmp/nginx/scgi"

note:nginx.vim 能夠高亮nginx語法

Install details:

[[ -d ~/.vim/syntax ]] || mkdir  -p ~/.vim/syntax
cd ~/.vim/syntax
wget http://www.vim.org/scripts/download_script.php?src_id=14376 -O nginx.vim
echo "au BufRead,BufNewFile /usr/local/nginx/* set ft=nginx" >> ~/.vim/filetype.vim

Nignx的core配置

http://nginx.org/en/docs/

正常運行的必須配置

​ user username [groupname];

​ 指定運行worker進程的用戶和組

​ pid /path/to/pidfile_name;

​ 指定nginx的pid文件

​ worker_rlimit_nofile #;

​ 指定每一個worker process能夠打開的最大文件句柄數

​ woker_rlimit_sigpending #;

​ 設定每一個用戶可以發往worker進程的信號的數量

優化性能相關的配置

​ worker_processes #;

​ woker進程的個數:每一個worker進程都是單線程,一般其數值應該爲CPU的物理核心數減1;

​ worker_cpu_affinity cpumask ...;

​ CPU掩碼假設有4顆CPU: 0000 0001(第一顆) 0010 0100 1000

eg.
worker_process 6;
worker_cpu_affinity 00000001 00000010 00000100 00001000 0010000 00100000; 	

​ ssl_engine device;

​ 在存在ssl硬件加速器的服務器上,指定所使用的ssl硬件加速設備;

​ timer_resolution ;

​ 每次內核事件調用返回時,都會使用gettimeofday()系統調用來得到系統調用事件,來更新nginx中的緩存時 鍾.早期gettimeofday()的調用成本很是大. timer_resolution 表示不論調用多少次,只在固定的時間間隔才返回系統時間. 目前而言x86-64系統上,gettimeofday()代價已經很小,能夠忽略此配置

​ worker_priority ;

​ nice值範圍-20,19之間的值

事件相關的配置

​ accept_mutex [on|off];

​ 是否打開nginx的負載均衡鎖;此鎖可以讓多個worker進程輪流地,序列化地與新的客戶端創建TCP鏈接; 一般當一個worker進程的負載達到其上限的7/8, master就儘量再也不將請求調度此worker;

​ lock_file /path/to/lock_file;

​ lock文件

​ accept_mutex_delay #ns;

​ 使用accept鎖模式中,一個worker進程爲取得accept鎖的等待時長;若是某worker進程在某次試圖取得鎖時失敗了,至少要等待 #ms才能再一次請求鎖.默認是爲500ms

​ multi_accept on|off;

​ 是否容許一次性地響應多個用戶請求; 默認爲off,即一個鏈接一個鏈接創建

​ use [epoll|rtsig|select|poll]

​ 定義使用的時間模型,建議讓nginx自動選擇;linux上通常選擇的是epoll

​ worker_connection #;

​ 每一個worker可以併發響應的最大請求數

用於調試,定位問題

只在調試Nginx時使用

​ daemon [on|off];

​ 是否讓nginx運行在後臺: 默認爲on,調試時能夠設置爲off, 使得全部信息直接輸出在控制檯;

​ master_process [on|off];

​ 是否以master/worker模式運行nginx,默認爲on,調試時能夠設置爲off,以方便追蹤

​ error_log /path/to/error_log ;

​ 錯誤日誌文件及其級別,調試時能夠使用debug級別,但要求在編譯時必須使用--with-debug啓用debug功能

nignx的http功能

必須使用虛擬主機來配置站點;每一個虛擬主機使用一個server{}段來配置

​ server {

​ }

非虛擬主機的配置或公共配置, 須要定義在server以外, http以內;

server{}

定義一個虛擬主機: nginx支持使用基於主機名或IP的虛擬機主機;

listen

​ listen address[:port];

​ listen port

​ listen unix:socket_file_path

​ defautl_server; 默認此server爲http中默認的server(IP訪問),若是全部的server中都沒有任何一個listen使用此參數,那麼第一個server爲默認server

​ rcvbuf=SIZE: 接受緩衝大小

​ sndbuf=SIZE: 發送緩衝大小

​ ssl: https server; 創建鏈接時必須使用ssl

server_name [...];

​ server_name能夠跟多個主機名,名稱中能夠使用通配符; 當nginx收到一個請求時,會取出其首部的server值,然後跟衆server_name進行比較,比較方式爲:

  • 先作精確匹配: www.example.com
  • 左側通配符匹配: *.example.com
  • 右側通配符匹配: www.*
  • 正則表達式匹配: 匹配前一般須要加破浪符號 ~^.*\.example\.com$

server_name_hash_bucket_size

​ server_name_hash_bucket_size 32|64|128; 爲了實現快速主機查找,nginx使用hash來保存主機名

location

​ location [ = | ~ | ~* | ^~ ] uri { ... }

​ location @name { ... }

​ 功能: 容許根據用戶請求的URI來匹配指定的各location來進行訪問配置, 匹配到時,將被location塊中的配置所處理 eg. http://www.example.com/imges/logo.gif

=: 作精確匹配;
~: 正則表達式的模式匹配,匹配時區分字符大小寫;
~*: 正則表達式模式匹配,匹配時忽略字符大小寫;
^~: URI前半部分匹配,不檢查正則表達式

匹配優先級:

​ 字符字面量(字符精確比較)-->正則表達式檢索(由第一個匹配到所處理)-->按照字符字面量

文件路徑定義:

1 . root path

​ 設置web資源路徑,用於指定請求的跟文檔目錄; root: root/URI

location / {
  	root /www/htdocs;
}
location ^~ /images/ {
   	root /web;
}

2 . alias path

​ 只能用於location中,用於路徑別名; alias: alias/

location / {
  	root /www/htdocs;
}
location ^~ /images/ {
   	alias /web;
}
以web來alias images...

3 . index file ....;

​ 定義默認頁面, 能夠跟多個值, 自左而右逐個匹配

4 . error_page code ... [=[response]] uri;

​ 當對於某個請求返回錯誤時,若是匹配上了error_page指令中設定的code,則重定向到新的URI中. 簡而言之: 錯誤頁面重定向. =response 表示使用新的狀態碼顯示

5 . try_files path1 [path2 ...] uri;

​ 自左至右嘗試去讀取由path所指定路徑,在第一次找到即中止並返回; 若是全部path均不存在, 則返回最後一個uri; $uri 變量表示用戶嘗試訪問的uri

        location ~* ^/documents/(.*)$ {
            root /www/htdocs;
            try_files $uri /docu/$1 /temp.html;
        }
        則會嘗試去匹配:
        http://192.168.48.131/documents/a.html
        http://192.168.48.131/docu/a.html
        http://192.168.48.131/temp.html

網絡鏈接相關的設置

1 . keepalive_timeout [time];

​ 默認爲75s, 保持鏈接的超時時長

2 . keepalive_requests n;

​ 在一次長鏈接上容許承載的最大請求數;

3 . keepalive_disable [msie6 | safari | none]

​ 對指定的瀏覽器禁止使用長鏈接

4 . tcp_nodelay on|off

​ 對keepalive鏈接是否使用TCP_NODELAY選項:

5 . client_header_timeout time;

​ 讀取http請求首部的超時時間, 默認爲60s

6 . client_body_timeout time;

​ 讀取http請求包體的超時時長,默認爲60s

7 . send_timeout time;

​ 發送響應的超時時長

對客戶端請求的限制

1 . limit_except method ...{...}

​ 指定對範圍以外的其餘方法的訪問控制;

limit_except GET {
  	allow 192.168.48.0/24;
  	deny all;
}

2 . client_max_body_size SIZE;

​ http請求包體的最大值; content-lengh. 經常使用於限定客戶所可以請求的最大包體; 根據請求首部中的content-length來檢測, 以免無用的傳輸

3 . limit_rate speed;

​ 限制客戶端每秒鐘可以傳輸的字節數; 默認爲0, 表示沒有限制; 默認單位爲字節, 也能夠指定單位 eg. 40k

4 . limit_rate_after time;

​ nginx向客戶端發送響應報文時, 若是時長超過此處指定的時長, 則後續的的發送過程開始限速

文件操做的優化

1 . sendfile on|off

​ 是否啓用sendfile功能;

2 . aio on|off

​ 是否啓用aio功能;

3 . open_file_cache max=N [inactive=time]|off

​ 是否打開文件緩存功能;

​ max: 用於指定緩存條目的最大值, 當緩存滿了以後將根據LRU算法進行置換;

​ inactive: 非活動時間, 緩存條目在指定時長內沒有被訪問過期, 將自動被刪除. 默認爲60s

​ 緩存的信息包括:

文件句柄 (文件描述符), 文件大小和上次修改時間

已經打開的目錄結構

沒有找到活沒有訪問權限的信息

4 . open_file_cache_errors on|off

​ 是否緩存文件找不到活沒有權限訪問等相關信息; 可能會影響更新...

5 . open_file_cache_valid time;

​ 多長時間檢查一次緩存中的條目是否超出非活動時長地, 默認爲60s

6 . open_file_cache_min_use #;

​ 在inactive指定的時長內被訪問超此處指定的次數, 纔不會被刪除. 即命中率過低就被刪除

對客戶端請求的特殊處理

1 . ignore_invalid_headers on|off

​ 是否忽略不合法的http首部; 默認爲on; off意味着請求首部中出現不合規的首部時,拒絕響應; 只能用於server和http;

2 . log_not_found on|off

​ 是否將文件找不到的信息也記錄進錯誤日誌中:

3 . resolver address;

​ 指定nginx使用的dns服務器地址;

4 . resolver_timeout time;

​ 指定DNS解析超時時長, 默認爲30s; 時間一般須要調短

5 . server_tokens on|off;

​ 是否在錯誤頁面中顯示nginx的版本號;

http核心模塊的內置變量

$uri: 當前請求的uri, 不帶參數;

$host: http請求報文中的host首部; 若是請求中沒有host首部, 則以處理此請求的虛擬機主機的主機名代替

$request_uri: 請求的uri, 帶完整參數;

$hostname: nginx服務運行所在主機的主機名

$remote_addr: 客戶端IP

$remote_port: 客戶端端口

$remote_user: 使用用戶認證時客戶端用戶輸入的用戶名

$request_filename: 用戶請求中的URI通過本地root或alias轉換後映射的本地的文件路徑

$request_method: 請求方法

$server_addr: 服務器地址

$server_name: 服務器名稱

$server_port: 服務器端口

$server_protocol: 服務器向客戶端發送響應時的協議, http/1.1, http/1.0

$scheme: 在請求中使用的scheme, eg. https://www.example.com中的https

$http_HEADER: 匹配請求報文中指定的HEADER, $http_host匹配請求報文中的host首部

$sent_http_HEADER: 匹配響應報文中指定的HEADER, eg $sent_http_content_type匹配響應報文中的content-type首部;

$document_root: 當前請求映射到的root配置項

配置使用nginx

1 . 虛擬主機

​ nginx必須配置虛擬主機

server {
  	listen
  	server_name
  	root
}

2 . 訪問控制access模塊

​ allow

​ deny

3 . 用戶認證功能

​ auth_basic

​ auth_basic_user_file

location /dmz/ {
  	root /www/b.org;
  	auth_basic "dmz zone";
  	auth_basic_user_file /etc/nginx/.htpasswd;
}
htpasswd -c -m /etc/nginx/.htpasswd esunyig
htpasswd -m /etc/nginx/.htpasswd dora

4 . 創建下載站點autoindex模塊

​ autoindex on;

​ 默認爲off

5 . 防止盜鏈

​ 定義合規的引用

​ valid_referers none | blocked | server_names | string ...;

​ 拒毫不合規的引用

if  ($invalid_referer) {
	rewrite ^/.*$ http://www.b.org/403.html 
} 
eg. 
location ~*\.(jpg|png|gif|jpeg)$ {                
    root /www/b.org/images/;                      
    valid_referers none blocked www.b.org *.b.org;
    if ($invalid_referer) {                       
        rewrite ^/ http://www.b.org/403.html;     
    }                                             
}                                       

6 . URL Rewrite

​ rewrite regex replacement [flag];

last: 一旦被當前規則匹配並重寫後當即中止檢查後續的其餘rewrite規則, 而經過重寫後的規則從新發起請求

break: 一旦被當前規則匹配並重寫後當即中止後續的其餘rewrite規則, 然後續由nginx進行後續操做

redirect: 返回302臨時重定向

permanent: 返回301永久重定向

location /download/{
  rewrite ^(/download/.*)/media/(.*)\..*$ $1/media/$2.mp3 break;
}

nginx最多循環10次, 超出以後返回500錯誤.

注意: 通常將rewrite卸載location中時都是用break標記, 或者將rewrite寫在if上下文中;

rewrite_log on|off

​ 是否把重寫過程記錄在錯誤日誌中, 默認爲notice級別, 默認爲off

return code:

​ 用於結束rewrite規則, 而且爲客戶端返回狀態碼, 能夠使用的狀態碼有204, 400, 402-406, 500-504等

gzip

http {
	gzip on;
	gzip_http_version 1.0;
	gzip_comp_level 2;
	gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/json;
	gzip_disable msie6;
}

gzip_proxied指令能夠定義對客戶端請求哪類對象啓用壓縮功能,如「expired」表示對因爲使用了expire首部定義而沒法緩存的對象啓用壓縮功能,其它可接受的值還有「no-cache」、「no-store」、「private」、「no_last_modified」、「no_etag」和「auth」等,而「off」則表示關閉壓縮功能。

note: 實際對圖片壓縮沒有意義, 自己壓縮比比較小

反向代理功能

xcache用於緩存app server的編譯結果,並在app server之間實現共享

fastcgi

location ~*\.php$ {
  	fastcgi_pass 127.0.0.1:9000;
}

fastcgi模塊的經常使用指令:

fastcgi_pass: 指定fastcgi服務監聽端口、地址;也支持使用Unix sock;
fastcgi_bind: 指定聯繫fpm服務時使用的地址;
fastcgi_param: 定義傳遞給fpm服務器的參數;
fastcgi_index: php的主頁面文件;

結果能夠緩存, 緩存空間使用fastcgi_path定義, 使用fastcgi_cache來調用:

fastcgi_cache_path
fastcgi_cache
fastcgi_cache_valid
fastcgi_connect_timeout: 鏈接fastcgi服務器的超時時長;
fastcgi_send_timeout: 向fastcgi服務傳輸數據的超時時長 ;

獲取php-fpm的狀態信息:

 location ~* /(status|ping) {
 	root           /www/a.com;
	fastcgi_pass   127.0.0.1:9000;
	fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
	include        fastcgi_params;
  }

fastcgi_params配置文件

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFWARE    nginx;
fastcgi_param QUERY_STRING      $query_string;
fastcgi_param REQUEST_METHOD    $request_method;
fastcgi_param CONTENT_YTPE      $content_type;
fastcgi_param CONTENT_LENGTH    $content_length;
fastcgi_param SCRIPT_FILENAME   $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME       $fastcgi_script_name;
fastcgi_param REQUEST_URI       $request_uri;
fastcgi_param DOCUMENT_URI      $document_uri;
fastcgi_param DOCUMENT_ROOT     $document_root;
fastcgi_param SERVER_PROTOCOL   $server_protocol;
fastcgi_param REMOTE_ADDR       $remote_addr;
fastcgi_param REMOTE_PORT       $remote_port;
fastcgi_param SERVER_ADDR       $server_addr;
fastcgi_param SERVER_PORT       $server_port;
fastcgi_param SERVER_NAME       $server_name;

php-fpm狀態參數

pool	www
	進程池的名稱;
process manager	dynamic
	進程管理器,有兩種類型static和dynamic;
start time	25/Apr/2014:15:28:07 +0800
	起動時間
start since	2150
	運行時長
accepted conn	4021
	已經接受的請求數;
listen queue	0
	等待隊列中的請求的個數;
max listen queue	90
	fpm啓動以來等待隊列中的請求的總數;
listen queue len	128
	等待隊列長度
idle processes	4
	空閒的進程數
active processes	1
	活動進程數
total processes	5
	總進程數
max active processes	8
	ftp啓動以來最大活動進程數
max children reached	0
	達到最大子進程的次數
slow requests	0
	慢速請求的個數

反向代理

proxy_pass

location [op] URI {
  
}
操做符
~	區分大小寫,元字符匹配
~*	不區分大小寫,元字符匹配
^~ 	逐個字符匹配
= 	路徑精確匹配,一般匹配文件
location /forum/ {
  	proxy_pass http://192.168.48.132/bbs/:80
}
模式匹配的狀況下, proxy server的路徑不能夠指定 eg.
location ~* ^/forum {
  	proxy_pass http://192.168.48.132:8080;
}

若是在location中使用URL重定向, 那麼nginx將使用重定向後的URI處理請求, 而再也不考慮上游服務器上定義的URI

proxy_set_header

在nginx配置中添加首部

proxy_set_header X-Real-IP $remote_addr

在httpd的log格式中修改

LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" co
mbined
其中%{X-Real-IP}表明變量值

http method:

GET, POST, HEAD, PUT, TRACE, OPTIONS, CONNECTION, DELETE

nginx支持的算法

​ round-robin

​ ip_hash

​ least_conn

配置eg.

upstream websrvs {
    #ip_hash
    server 192.168.48.132 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.48.137 weight=1 max_fails=2 fail_timeout=2;
    server 127.0.0.1:8080 backup;
}
location / {
    proxy_pass http://websrvs/;
    proxy_set_header X-Real-IP $remote_addr;
}
server {
    listen 8080;
    server_name localhost;
    root /web/errorpages;
    index index.html;
}

cache:

共享內存, 存儲鍵和緩存對象元數據

​ 磁盤空間:存儲數據

proxy_cache_path: 不能定義在server{}上下文中;

定義三級緩存目錄,以first爲緩存空間名稱

proxy_cache_path /nginx/cache/first levels=1:2:1 keys_zone=first:20m max_size=1G;

cache_manager: LRU 最近最少使用算法

WebDAV(Web-based Distributed Authoring and Versioning) 一種基於HTTP 1.1協議的通訊協議, 它擴展了HTTP1.1, 在GET, POST, HEAD等幾個HTTP標準方法之外添加了一些新的方法, 使得應用程序可直接對Web Server直接讀寫, 並支持寫文件鎖定(Locking)及解鎖(Unlock), 還能夠支持文件的版本控制

另外經常使用的三種緩存:

​ open_log_cache

​ open_file_cache

​ fastcgi_cache

Memcache

Glibc 中使用malloc()建立內存空間, free()釋放內存

TCmalloc(), 優化內存分配機制

memcache使用 slab allocator來完成內存的分配和回收, 提早對內存分頁, 並想內核申請固定大小的內存空間

grow factor: 增加因子, 能夠自定義.

Page: 內存頁面, 分配給slab用於切割的內存空間, 默認頁面大小爲1MB, 內核分配給slab以後, slab再根據應用需求進行分配

Chunk: 用戶緩存記錄的內存空間

slab class: 特定大小的chunk組

memcache協議: 文本格式, 二進制格式

Memcache的特色

  1. 簡單key/value存儲:服務器不關心數據自己的意義及結構,只要是可序列化數據便可。存儲項由「鍵、過時時間、可選的標誌及數據」四個部分組成;
  2. 功能的實現一半依賴於客戶端,一半基於服務器端:客戶負責發送存儲項至服務器端、從服務端獲取數據以及沒法鏈接至服務器時採用相應的動做;服務端負責接收、存儲數據,並負責數據項的超時過時;
  3. 各服務器間彼此無視:不在服務器間進行數據同步;
  4. O(1)的執行效率
  5. 清理超期數據:默認狀況下,Memcached是一個LRU緩存,同時,它按事先預訂的時長清理超期數據;但事實上,memcached不會刪除任何已緩存數據,只是在其過時以後再也不爲客戶所見;並且,memcached也不會真正定期限清理緩存,而僅是當get命令到達時檢查其時長;

一致性哈希算法

一致性hash算法

libevent庫:用於調用併發, epoll(), poll(), select()

每一個請求一個線程響應

安裝memcached

memcached依賴於libevent API,所以要事先安裝之

tar xf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21
./configure --prefix=/usr/local/libevent
make && make install

echo "/usr/local/libevent/lib" > /etc/ld.so.conf.d/libevent.conf
ldconfig 

安裝配置memcached

tar xf memcached-1.4.15.tar.gz 
cd memcached-1.4.15
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent
make && make install

memcached SysV startup腳本

#! /bin/sh
#
# chkconfig: - 55 45
# description:	The memcached daemon is a network memory cache service.
# processname: memcached
# config: /etc/sysconfig/memcached
# pidfile: /var/run/memcached/memcached.pid

# Standard LSB functions
#. /lib/lsb/init-functions

# Source function library.
. /etc/init.d/functions

PORT=11211
USER=memcached
MAXCONN=1024
CACHESIZE=64
OPTIONS=""

if [ -f /etc/sysconfig/memcached ];then 
	. /etc/sysconfig/memcached
fi

# Check that networking is up.
. /etc/sysconfig/network

if [ "$NETWORKING" = "no" ]
then
	exit 0
fi

RETVAL=0
prog="memcached"
pidfile=${PIDFILE-/var/run/memcached/memcached.pid}
lockfile=${LOCKFILE-/var/lock/subsys/memcached}

start () {
	echo -n $"Starting $prog: "
	# Ensure that /var/run/memcached has proper permissions
	if [ "`stat -c %U /var/run/memcached`" != "$USER" ]; then
		chown $USER /var/run/memcached
	fi

	daemon --pidfile ${pidfile} memcached -d -p $PORT -u $USER  -m $CACHESIZE -c $MAXCONN -P ${pidfile} $OPTIONS
	RETVAL=$?
	echo
	[ $RETVAL -eq 0 ] && touch ${lockfile}
}
stop () {
	echo -n $"Stopping $prog: "
	killproc -p ${pidfile} /usr/bin/memcached
	RETVAL=$?
	echo
	if [ $RETVAL -eq 0 ] ; then
		rm -f ${lockfile} ${pidfile}
	fi
}

restart () {
        stop
        start
}

# See how we were called.
case "$1" in
  start)
	start
	;;
  stop)
	stop
	;;
  status)
	status -p ${pidfile} memcached
	RETVAL=$?
	;;
  restart|reload|force-reload)
	restart
	;;
  condrestart|try-restart)
	[ -f ${lockfile} ] && restart || :
	;;
  *)
	echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart|try-restart}"
	RETVAL=2
        ;;
esac

exit $RETVAL

memached的經常使用選項

-l <ip_addr>:指定進程監聽的地址;
-d: 以服務模式運行;
-u <username>:以指定的用戶身份運行memcached進程;
-m <num>:用於緩存數據的最大內存空間,單位爲MB,默認爲64MB;
-c <num>:最大支持的併發鏈接數,默認爲1024;
-p <num>: 指定監聽的TCP端口,默認爲11211;
-U <num>:指定監聽的UDP端口,默認爲11211,0表示關閉UDP端口;
-t <threads>:用於處理入站請求的最大線程數,僅在memcached編譯時開啓了支持線程纔有效;
-f <num>:設定Slab Allocator定義預先分配內存空間大小固定的塊時使用的增加因子;
-M:當內存空間不夠使用時返回錯誤信息,而不是按LRU算法利用空間;
-n: 指定最小的slab chunk大小;單位是字節;
-S: 啓用sasl進行用戶認證;
-P: 指定pid文件

啓動服務後使用telnet登陸memcached

telnet 127.0.0.1 11211

Memcached提供了爲數很少的幾個命令來完成與服務器端的交互,這些命令基於memcached的協議實現。

存儲類命令:set, add, replace, append, prepend
獲取數據類命令:get, delete, incr/decr
統計類命令:stats, stats items, stats slabs, stats sizes
清理命令: flush_all
add命令:
add keyname flag  timeout  datasize
如:
add mykey 0 10 12
Hello world!

get命令:
get keyname
如:get mykey
VALUE mykey 0 12
Hello world!
END

程序員在開發時, 自行調用memcached的API, memcached的功能才能生效

​ Memcached: 服務器

​ memcached: php鏈接memcached服務能夠使用擴展

​ memcache: php鏈接memcached服務能夠使用的另外一個擴展

​ libmemcached: C庫

安裝memcache PHP擴展

tar xf memcache-2.2.5.tgz
cd memcache-2.2.5
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --enable-memcache
make && make install

Nginx整個memcached

server {
        listen       80;
        server_name  www.b.org;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
                set $memcached_key $uri;
                memcached_pass     192.168.48.138:11211;
                default_type       text/html;
                error_page         404 @fallback;
        }

        location @fallback {
                proxy_pass http://192.168.48.131;
        }
}

note: memory cache 若是掛掉了, 應該注意灰度發佈, 即放一部分流量先行進行緩存

Haproxy

LB:

4 layer: lvs

7 layer:

​ nginx(web, http reverse proxy, cache)

​ haproxy (http reverse proxy, tcp-based proxy)

​ ats (apache traffic server)

​ perlball

​ pound

​ squid

​ varnish

1310法則; 期待站點的等待時長爲1s, 3s能夠接受

早期HAproxy使用紅黑二叉樹研發, 後來發現若是頻繁的查詢, 紅黑樹在平衡樹結構的時候會消耗大量的資源. 後來改進了其算法, 使用彈性二叉樹數據結構

版本

HAProxy目前主要有兩個版本:

1.4——提供較好的彈性:衍生於1.2版本,並提供了額外的新特性,其中大多數是期待已久的。 客戶端側的長鏈接(client-side keep-alive) TCP加速(TCP speedups) 響應池(response buffering) RDP協議 基於源的粘性(source-based stickiness) 更好的統計數據接口(a much better stats interfaces) 更詳細的健康狀態檢測機制(more verbose health checks) 基於流量的健康評估機制(traffic-based health) 支持HTTP認證 服務器管理命令行接口(server management from the CLI) 基於ACL的持久性(ACL-based persistence) 日誌分析器

1.3——內容交換和超強負載:衍生於1.2版本,並提供了額外的新特性。 內容交換(content switching):基於任何請求標準挑選服務器池; ACL:編寫內容交換規則; 負載均衡算法(load-balancing algorithms):更多的算法支持; 內容探測(content inspection):阻止非受權協議; 透明代理(transparent proxy):在Linux系統上容許使用客戶端IP直接連入服務器; 內核TCP拼接(kernel TCP splicing):無copy方式在客戶端和服務端之間轉發數據以實現數G級別的數據速率; 分層設計(layered design):分別實現套接字、TCP、HTTP處理以提供更好的健壯性、更快的處理機制及便捷的演進能力; 快速、公平調度器(fast and fair scheduler):爲某些任務指定優先級可實現理好的QoS; 會話速率限制(session rate limiting):適用於託管環境;

配置

http://cbonte.github.io/haproxy-dconv/

配置由兩部分組成:

global settings: 對haproxy進程自身屬性的設定

proxies: 對代理的設定

​ defaults

​ frontend

​ backend

​ listen

HAProxy的配置處理3類來主要參數來源: ——最優先處理的命令行參數, ——「global」配置段,用於設定全局配置參數; ——proxy相關配置段,如「defaults」、「listen」、「frontend」和「backend」;

時間格式

一些包含了值的參數表示時間,如超時時長。這些值通常以毫秒爲單位,但也能夠使用其它的時間單位後綴。 us: 微秒(microseconds),即1/1000000秒; ms: 毫秒(milliseconds),即1/1000秒; s: 秒(seconds); m: 分鐘(minutes); h:小時(hours); d: 天(days);

全局配置

「global」配置中的參數爲進程級別的參數,且一般與其運行的OS相關。

  • 進程管理及安全相關的參數

    • chroot :修改haproxy的工做目錄至指定的目錄並在放棄權限以前執行chroot()操做,能夠提高haproxy的安全級別,不過須要注意的是要確保指定的目錄爲空目錄且任何用戶均不能有寫權限;
    • daemon:讓haproxy以守護進程的方式工做於後臺,其等同於「-D」選項的功能,固然,也能夠在命令行中以「-db」選項將其禁用;
    • gid :以指定的GID運行haproxy,建議使用專用於運行haproxy的GID,以避免因權限問題帶來風險;
    • group :同gid,不過指定的組名;
    • log
      [max level [min level]]:定義全局的syslog服務器,最多能夠定義兩個;
    • log-send-hostname []:在syslog信息的首部添加當前主機名,能夠爲「string」指定的名稱,也能夠缺省使用當前主機名;
    • nbproc :指定啓動的haproxy進程的個數,只能用於守護進程模式的haproxy;默認只啓動一個進程,鑑於調試困難等多方面的緣由,通常只在單進程僅能打開少數文件描述符的場景中才使用多進程模式;
    • pidfile:
    • uid:以指定的UID身份運行haproxy進程;
    • ulimit-n:設定每進程所可以打開的最大文件描述符數目,默認狀況下其會自動進行計算,所以不推薦修改此選項;
    • user:同uid,但使用的是用戶名;
    • stats:
    • node:定義當前節點的名稱,用於HA場景中多haproxy進程共享同一個IP地址時;
    • description:當前實例的描述信息;
  • 性能調整相關的參數

  • maxconn :設定每一個haproxy進程所接受的最大併發鏈接數,其等同於命令行選項「-n」;「ulimit -n」自動計算的結果正是參照此參數設定的;
  • maxpipes :haproxy使用pipe完成基於內核的tcp報文重組,此選項則用於設定每進程所容許使用的最大pipe個數;每一個pipe會打開兩個文件描述符,所以,「ulimit -n」自動計算時會根據須要調大此值;默認爲maxconn/4,其一般會顯得過大;

設定一個前端的最大併發鏈接數,所以,其不能用於backend區段。對於大型站點來講,能夠儘量提升此值以便讓haproxy管理鏈接隊列,從而避免沒法應答用戶請求。固然,此最大值不能超出「global」段中的定義。此外,須要留心的是,haproxy會爲每一個鏈接維持兩個緩衝,每一個緩衝的大小爲8KB,再加上其它的數據,每一個鏈接將大約佔用17KB的RAM空間。這意味着通過適當優化後,有着1GB的可用RAM空間時將能維護40000-50000併發鏈接。

若是爲指定了一個過大值,極端場景下,其最終佔據的空間可能會超出當前主機的可用內存,這可能會帶來意想不到的結果;所以,將其設定了一個可接受值方爲明智決定。其默認爲2000。

  • noepoll:在Linux系統上禁用epoll機制;
  • nokqueue:在BSE系統上禁用kqueue機制;
  • nopoll:禁用poll機制;
  • nosepoll:在Linux禁用啓發式epoll機制;
  • nosplice:禁止在Linux套接字上使用內核tcp重組,這會致使更多的recv/send系統調用;不過,在Linux 2.6.25-28系列的內核上,tcp重組功能有bug存在;
  • spread-checks <0..50, in percent>:在haproxy後端有着衆多服務器的場景中,在精確的時間間隔後統一對衆服務器進行健康情況檢查可能會帶來意外問題;此選項用於將其檢查的時間間隔長度上增長或減少必定的隨機時長;
  • tune.bufsize :設定buffer的大小,一樣的內存條件小,較小的值可讓haproxy有能力接受更多的併發鏈接,較大的值可讓某些應用程序使用較大的cookie信息;默認爲16384,其能夠在編譯時修改,不過強烈建議使用默認值;
  • tune.chksize :設定檢查緩衝區的大小,單位爲字節;更大的值有助於在較大的頁面中完成基於字符串或模式的文本查找,但也會佔用更多的系統資源;不建議修改;
  • tune.maxaccept :設定haproxy進程內核調度運行時一次性能夠接受的鏈接的個數,較大的值能夠帶來較大的吞吐率,默認在單進程模式下爲100,多進程模式下爲8,設定爲-1能夠禁止此限制;通常不建議修改;
  • tune.maxpollevents :設定一次系統調用能夠處理的事件最大數,默認值取決於OS;其值小於200時可節約帶寬,但會略微增大網絡延遲,而大於200時會下降延遲,但會稍稍增長網絡帶寬的佔用量;
  • tune.maxrewrite :設定爲首部重寫或追加而預留的緩衝空間,建議使用1024左右的大小;在須要使用更大的空間時,haproxy會自動增長其值;
  • tune.rcvbuf.client :
  • tune.rcvbuf.server :設定內核套接字中服務端或客戶端接收緩衝的大小,單位爲字節;強烈推薦使用默認值;
  • tune.sndbuf.client:
  • tune.sndbuf.server:
  • Debug相關的參數

    • debug
    • quiet

Keyword

bind [

]:<port_range> [,....]
listen http_proxy
bind :80, :443
bind 10.0.0.1:10080, 10.0.0.1:10443 
Balance及算法

balance []

調度算法

roundrobin; static-rr; leastconn; source ; uri ; uri_param ; hdr(); rdp-cookie;

roundrobin支持動態加入server,可是有有4096個後端服務器的限制

leastconn是一種wlc的鏈接

source: 基於源IP的hash, 第一次鏈接時使用wlc的機制, 此後根據source ip作會話保持. 通常只有不支持使用cookie插入又要保持會話時使用

uri: 用於後端服務器是cache server的場景, 可以提升緩存命中率. hash-type能夠指定一致性hash算法, 而且能夠支持使用截取uri, 使用len指定截取URI長度以及depth指定截取URI的深度(/分隔深度)

url-params: 差用於後端服務器須要對用戶進行認證的場景中, 也能夠指定hash-type指定一致性hash算法. 當url中缺少pararms, 則根據roundrobin進行分佈

hdr: 根據http的請求首部進行hash計算. 若是針對首部, 能夠指定附加選項 use_domain_only的選項, 來僅僅指定域名.(泛域名的場景). 實現將對同一個虛擬主機的訪問始終定向至同一個upstream server

rdp-cookie: 針對remote desktop protocol的cookie來作hash計算

算法詳解

roundrobin:基於權重進行輪叫,在服務器的處理時間保持均勻分佈時,這是最平衡、最公平的算法。此算法是動態的,這表示其權重能夠在運行時進行調整,不過,在設計上,每一個後端服務器僅能最多接受4128個鏈接; static-rr:基於權重進行輪叫,與roundrobin相似,可是爲靜態方法,在運行時調整其服務器權重不會生效;不過,其在後端服務器鏈接數上沒有限制; leastconn:新的鏈接請求被派發至具備最少鏈接數目的後端服務器;在有着較長時間會話的場景中推薦使用此算法,如LDAP、SQL等,其並不太適用於較短會話的應用層協議,如HTTP;此算法是動態的,能夠在運行時調整其權重; source:將請求的源地址進行hash運算,並由後端服務器的權重總數相除後派發至某匹配的服務器;這能夠使得同一個客戶端IP的請求始終被派發至某特定的服務器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務器,許多客戶端的請求可能會被派發至與此前請求不一樣的服務器;經常使用於負載均衡無cookie功能的基於TCP的協議;其默認爲靜態,不過也能夠使用hash-type修改此特性; uri:對URI的左半部分(「問題」標記以前的部分)或整個URI進行hash運算,並由服務器的總權重相除後派發至某匹配的服務器;這能夠使得對同一個URI的請求老是被派發至某特定的服務器,除非服務器的權重總數發生了變化;此算法經常使用於代理緩存或反病毒代理以提升緩存的命中率;須要注意的是,此算法僅應用於HTTP後端服務器場景;其默認爲靜態算法,不過也能夠使用hash-type修改此特性; url_param:經過爲URL指定的參數在每一個HTTP GET請求中將會被檢索;若是找到了指定的參數且其經過等於號「=」被賦予了一個值,那麼此值將被執行hash運算並被服務器的總權重相除後派發至某匹配的服務器;此算法能夠經過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;若是某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的,不過其也能夠使用hash-type修改此特性; hdr():對於每一個HTTP請求,經過指定的HTTP首部將會被檢索;若是相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項「use_domain_only」,可在指定檢索相似Host類的首部時僅計算域名部分(好比經過www.magedu.com來講,僅計算magedu字符串的hash值)以下降hash算法的運算量;此算法默認爲靜態的,不過其也能夠使用hash-type修改此特性; rdp-cookie rdp-cookie(name):

Cookie

cookie node insert nocache

hash-type

map-based

consistent

HAProxy工做模式

http

​ http協議模式, 對應用層數據作深度分析, 支持七層過濾,處理,轉換等機制.

tcp

​ 默認模式:

​ haproxy在客戶端和upstream server之間創建一個全雙工的鏈接,不會對應用層協議作任何檢查. SSL, MySQL, SSL等都應該使用此模式

mode

mode tcp|http|health

日誌

log global: 使用全局配置中定義的日誌服務器

log

[ []]

capture request header len

capture response header len

指定默認backend

在listen或frontend中指定使用的默認後端:

​ default_backend <backend_name>

在listen或frontend中指定使用的條件式後端:

use_backend if

use_backend unless

定義Server

爲backend或listen定義各服務器:

server

[:port][param*]

server first 10.1.1.1:1080 cookie first check inter 1000

server second 10.1.1.1:1080 cookie second check inter 1000

服務器或默認服務器參數: backup:設定爲備用服務器,僅在負載均衡場景中的其它server均不可用於啓用此server; check:啓動對此server執行健康狀態檢查,其能夠藉助於額外的其它參數完成更精細的設定,如: inter :設定健康狀態檢查的時間間隔,單位爲毫秒,默認爲2000;也能夠使用fastinter和downinter來根據服務器端狀態優化此時間延遲;` ​ rise

:設定健康狀態檢查中,某離線的server從離線狀態轉換至正常狀態須要成功檢查的次數; fall :確認server從正常狀態轉換爲不可用狀態須要檢查的次數; cookie :爲指定server設定cookie值,此處指定的值將在請求入站時被檢查,第一次爲此值挑選的server將在後續的請求中被選中,其目的在於實現持久鏈接的功能; maxconn :指定此服務器接受的最大併發鏈接數;若是發往此服務器的鏈接數目高於此處指定的值,其將被放置於請求隊列,以等待其它鏈接被釋放; maxqueue :設定請求隊列的最大長度; observe :經過觀察服務器的通訊情況來斷定其健康狀態,默認爲禁用,其支持的類型有「layer4」和「layer7」,「layer7」僅能用於http代理場景; redir :啓用重定向功能,將發往此服務器的GET和HEAD請求均以302狀態碼響應;須要注意的是,在prefix後面不能使用/,且不能使用相對地址,以避免形成循環;例如: server srv1 172.16.100.6:80 redir http://imageserver.example.com check weight :權重,默認爲1,最大值爲256,0表示不參與負載均衡;

使用backup server

server backup 127.0.0.1:8010 check backup

check檢查方法

option httpchk 指定檢測的方法, 用於指定對http協議的server的檢測方法

option httpchk /test1.html` 

Stats

stats enable

stats uri /hpadmin?stats

stats auth admin:admin

訪問url uri/haproxy?stats

stats enable
stats uri
stats realm
stats auth
stats admin

使用單獨輸出eg

listen statistics
    bind *:8009
    stats enable
    stats auth admin:admin
    stats uri /hpadmin?stats
    stats hide-version
    stats admin if TRUE				#認證經過則容許管理

錯誤頁面

errorfile

errorfile <code> <file>

errorloc

在用戶請求不存在的頁面時,返回一個頁面文件給客戶端而非由haproxy生成的錯誤代碼;可用於全部段中。

:指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有200、400、40三、40八、500、50二、503和504; :指定用於響應的頁面文件;

例如: errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http

errorloc errorloc302

請求錯誤時,返回一個HTTP重定向至某URL的信息;可用於全部配置段中。

指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有200、400、40三、40八、500、50二、503和504; Location首部中指定的頁面位置的具體路徑,能夠是在當前服務器上的頁面的相對路徑,也能夠使用絕對路徑;須要注意的是,若是URI自身錯誤時產生某特定狀態碼信息的話,有可能會致使循環定向;

須要留意的是,這兩個關鍵字都會返回302狀態嗎,這將使得客戶端使用一樣的HTTP方法獲取指定的URL,對於非GET法的場景(如POST)來講會產生問題,由於返回客戶的URL是不容許使用GET之外的其它方法的。若是的確有這種問題,能夠使用errorloc303來返回303狀態碼給客戶端。

errorloc303

請求錯誤時,返回一個HTTP重定向至某URL的信息給客戶端;可用於全部配置段中。

指定對HTTP的哪些狀態碼返回指定的頁面;這裏可用的狀態碼有400、40三、40八、500、50二、503和504; Location首部中指定的頁面位置的具體路徑,能夠是在當前服務器上的頁面的相對路徑,也能夠使用絕對路徑;須要注意的是,若是URI自身錯誤時產生某特定狀態碼信息的話,有可能會致使循環定向;

http-request

http-request {allow|deny|auth[realm ]} [{if|unless} ]

配置向upstream server發送消息時,保留原client IP

在HAproxy配置中

option forwardfor except 127.0.0.0/8

option forwardfor [ except ][ header ] [ if-none ]

容許在發往服務器的請求首部中插入「X-Forwarded-For」首部。

可選參數,當指定時,源地址爲匹配至此網絡中的請求都禁用此功能。 可選參數,可以使用一個自定義的首部,如「X-Client」來替代「X-Forwarded-For」。有些獨特的web服務器的確須要用於一個獨特的首部。 if-none:僅在此首部不存在時纔將其添加至請求報文問道中。

HAProxy工做於反向代理模式,其發往服務器的請求中的客戶端IP均爲HAProxy主機的地址而非真正客戶端的地址,這會使得服務器端的日誌信息記錄不了真正的請求來源,「X-Forwarded-For」首部則可用於解決此問題。HAProxy能夠向每一個發往服務器的請求上添加此首部,並以客戶端IP爲其value。

須要注意的是,HAProxy工做於隧道模式,其僅檢查每個鏈接的第一個請求,所以,僅第一個請求報文被附加此首部。若是想爲每個請求都附加此首部,請確保同時使用了「option httpclose」、「option forceclose」和「option http-server-close」幾個option。

在HTTP配置中添加環境變量%{X-Format-For}i

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

option httpclose: 檢測首部中是否有connection: close, 若是沒有則添加之

option redispatch: 若是後端server的cookie down則打破cookie粘性, 重新派發.

option httplog [ clf ]

啓用記錄HTTP請求、會話狀態和計時器的功能。

clf:使用CLF格式來代替HAProxy默認的HTTP格式,一般在使用僅支持CLF格式的特定日誌分析器時才須要使用此格式。

默認狀況下,日誌輸入格式很是簡陋,由於其僅包括源地址、目標地址和實例名稱,而「option httplog」參數將會使得日誌格式變得豐富許多,其一般包括但不限於HTTP請求、鏈接計時器、會話狀態、鏈接數、捕獲的首部及cookie、「frontend」、「backend」及服務器名稱,固然也包括源地址和端口號等。

option logasap no option logasap

啓用或禁用提早將HTTP請求記入日誌,不能用於「backend」區段。

默認狀況下,HTTP請求是在請求結束時進行記錄以便能將其總體傳輸時長和字節數記入日誌,由此,傳較大的對象時,其記入日誌的時長可能會略有延遲。「option logasap」參數可以在服務器發送complete首部時即時記錄日誌,只不過,此時將不記錄總體傳輸時長和字節數。此情形下,捕獲「Content-Length」響應首部來記錄傳輸的字節數是一個較好選擇。下面是一個例子。

listen http_proxy 0.0.0.0:80

  mode http
  option httplog
  option logasap
  log 172.16.100.9 local2

redirect

redirect location [code ]{if |unless} ]

acl clear dst_port 80
acl secure dst_port 8080
acl login_page url_beg /login 
acl logout url_beg /logout
acl uid_given url_reg /login?userid=[^&]+
acl cooke_set hdr_sub(cookie) SEEN=1
redirect prefix https://centos.example.com set-cookie SEEN=1 if !cookie_set
redirect prefix https://centos.example.com if login_page !secure
redirect prefix http://centos.example.com drop-query if login_page !uid_given
redirect location http://centos.example.com/ if !login_page secure
redirect location / clear-cookie USERID= if logout

reqadd

添加首部報文

reqadd [{if|unless}]

acl is-ssl dst_port 443
reqadd X-Proto:\ SSL if is-ssl

同理rspadd: 添加回復http首部

timeout

timeout http-request 指定超時時長

默認時間爲毫秒

timeout queue 隊列等待超時時間

timeout connect haporxy 跟上游服務器創建鏈接的超時時長

timeout client 客戶端非響應超時時長

timeout server 等待服務器端發數據的超時時長

timeout http-keep-alive 保持鏈接的超時時長

ACL

acl flags operator

dst: 目標地址

src: 源地址

dst_port: 目標端口

src_port: 源端口

拒絕src 172.16.100.0/24網段的請求

acl badguy src 172.16.100.0/24

tcp-request content reject if badguy

實現訪問控制:

​ http-request: 7層過濾

​ tcp-request content accept/reject: tcp層過濾

hdr(Header)

hdr(Connection) -i close

hdr_reg(Host)

​ path

​ path_beg

​ path_end

​ path_reg

​ url

​ url_beg

eg.

acl url_static path_beg /static /images /img /css
acl url_static path_end .gif .png .jpg .css .js
acl host_www hdr_beg(host) -i www
acl host_static hdr_beg(host) -i img. video. download. 
use_backend static if host_static or host_www or url_static 
use_backend www if host_www

 

 

會話保持機制

IP層: source

​ 位於某一個NAT服務器背後的多個請求都會定向至一個upstream server, 不利於均衡

應用層: cookie

​ 有更好的負載均衡效果

source: 通常只有不支持cookie插入又須要保持會話時使用

Vanish

HTTP首部緩存控制

緩存遵循二八法則. 最近最少算法

7200機械硬盤, iops只能達到80-100

固態硬盤滿寫最多能夠使用十萬次. 400-500個ipos

圖片自己就是通過高密度壓縮, 對其進行壓縮不但浪費時間還會浪費CPU時鐘週期.

緩存命中率:

​ 文檔命中率

​ 字節命中率

緩存類型:

​ 私有緩存

​ 公共緩存

內容路由:

​ 基於緩存協議彼此通訊 ICP: Internet Cache Protocol

​ 藍汛: CDN

​ HTCP: HyperText Caching Protocol

​ Cache Digest

​ Cache Pre-filling

​ CARP: Cache Array Routing Protocol

緩存處理的具體步驟:

​ 接受請求

​ 解析請求(代理)

​ 查詢緩存(檢查本地緩存中是否存在對方請求的內容的副本)

​ 副本的新鮮度檢測(檢查本地緩存的副本是否爲最新版本)

​ 構建響應(代理的功能)

​ 發送

​ 日誌記錄

保證副本的新鮮度?

​ 文檔過時機制:

​ HTTP/1.0: Expires(過時時間) 絕對時間

​ HTTP/1.1: Cache-Control(max-age=) 相對時長

​ 條件式請求:

​ 304, Not Modified

​ mtime: If-Modified-Since

​ 基於時間的條件式請求

​ ETag: 擴展標記 If-None-Match

​ 基於擴展標籤的條件式請求

原始服務器或緩存服務器控制緩存的能力:

​ 由原始服務器定義:

​ Cache-Control

​ max-age: 私有緩存

​ s-maxage: 共有緩存

​ no-store: 不能緩存

​ no-cache: 能緩存, 可是不能直接使用此緩存對象; 緩存對象在使用以前必須作新鮮度認證

​ must-revalidate: 必須進行新鮮度驗證

​ priviate: 私有數據

​ public: 公開數據

​ Expires:

​ 原始服務器不添加任何控制機制, 而由緩存服務器本身決定緩存時長

客戶端控制是否使用緩存:

​ Cache-Control

​ max-stale: 告知緩存機制能夠使用過時的文件

​ no-cache: 告知緩存機制必須進行驗證, 不然不會接受任何緩存資源

​ no-store: 告知緩存機制必須儘快刪除緩存中的文檔

​ HTTP/1.0

​ Pragma: no-cache

http協議

​ request:

​ method url version

​ HEADERS

​ BODY

​ response:

​ version status reason

​ HEADERS

​ BODY

HTTP首部

​ 通用

​ Connection: close|keep-alive 短鏈接和長鏈接 HTTP

​ Date: 日期時間, 請求產生的日期時間

​ Host: 請求的主機

​ Pragma: no-cache 緩存服務器必須到原始服務器進行新鮮度驗證

​ Via: 請求或響應消息在客戶端和服務器之間傳遞時所通過的代理

​ Transfer-Encoding: 消息主體的傳輸編碼方式, chunked表示採用塊編碼的方式

​ 請求

​ If-Modified-Since: 基於時間的條件式請求

​ If-None-Mactchd: 基於擴展標籤的條件式請求

​ Referer: 經過點擊頁面中的連接進行跳轉

​ User-Agent: 用戶的瀏覽器類型

​ Host: 請求的主機及端口號

​ Accept-Encoding: 接受的編碼方式

​ Accept-Language: 接受的天然語言

​ Accept-Charset: 接受字符集

​ Authorization: 服務端發送www-authenticate首部時, 客戶端經過此首部提供認證信息

​ 響應

​ ETag: 內容的擴展標籤

​ Location: 重定向後的新資源位置

​ Server: 服務器軟件信息, 版本號

​ WWW-Authenticate: 要求對客戶端進行認證(一般狀態碼爲401)

​ Age: 用戶所請求的內容從構建響應倒此刻爲止使用的時間

​ 實體

​ Content-Encoding: 內容編碼

​ Content-Language: 內容語言

​ Content-Lenth: 響應內容的長度

​ Content-Type: 內容的MIME格式

​ Expires: 過時時間

​ Last-Modified: 最後一次修改時間

​ Cache-Control: 緩存控制

Varnish:

​ web緩存, 代理服務器.

varnish主要運行兩個進程: Management進程和Child進程(也叫Cache進程).

Management進程主要實現應用新的配置、編譯VCL、監控varnish、初始化varnish以及提供一個命令行接口等。Management進程會每隔幾秒鐘探測一下Child進程以判斷其是否正常運行,若是在指定的時長內未獲得Child進程的迴應,Management將會重啓此Child進程。

狀態引擎

​ 子例程, 函數, 能夠使用return()函數返回狀態給varnish

​ vcl_recv, vcl_pass, vcl_hash, vcl_pipe

​ vcl_hash: vcl_hit, vcl_miss

​ vcl_pass: vcl_fetch

​ vcl_hit: vcl_deliver, vcl_pass

​ vcl_miss: vcl_fetch, vcl_pass

​ vcl_fetch: vcl_deliver

Varnish安裝

yum install readline-devel
yum install ncurses-devel
cd varnish-3.0.0
./autogen.sh
./configure --prefix=/usr/local/varnish PKG_CONFIG_PATH=/usr/lib/pkgconfig
 
make
make install

配置控制

修改配置/etc/sysconfig/varnish

VARNISH_LISTEN_PORT=80
VARNISH_STORAGE_FILE="malloc,100M"

鏈接本地管理接口

varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

查看本地配置

vcl.list

查看配置內容

vcl.show [name]

eg.

vcl.load test1 /etc/varnish/test.vcl
200 13
VCL compiled.
vcl.list
200 47
active          1 boot
available       0 test1

vcl.use test1
200 0

vcl.show test1
200 59
backend websrv1 {
  .host="172.16.100.12";
  .port="80";
}

test.vcl

backend web1 {
  .host="172.16.100.12";
  .port="80";
  .probe = {
    .url = "/index.html";
    .window = 5;
    .threshold = 2;
    .interval = 3s;
  }
}

backend web2 {
  .host = "172.16.100.13";
  .port = "80";
}

#director websrvs random {
#  {
#    .backend = web1;
#    .weight = 2;
#  }
#  {
#    .backend = web2;
#    .weight = 1;
#  }
#}


acl purgers {
  "127.0.0.1";
  "192.168.48.0"/24;
  }

sub vcl_recv {
  if (req.url ~ "\.(html|css|js)$") {
    set req.backend = web2;
  } else {
    set req.backend = web1;
  }
#  set req.backend = websrvs;
  if (req.request == "PURGE") {
    if (!client.ip ~ purgers) {
      error 405 "Method not allowed";
    }
  }

  if (req.url ~ "test.html") {
    return(pass);
  }
  return(lookup);
}
sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged OK.";
  }
}

sub vcl_miss {
  if (req.request == "PURGE") {
    purge;
    error 404 "Not in cache";
  }
}

sub vcl_pass {
  if (req.request == "PURGE") {
    error 502 "Purged on a passed object.";
  }
}

sub vcl_fetch {
  if (req.url ~ "\.(jpg|jpeg|gif|png)$") {
    set beresp.ttl = 7200s;
  }

  if (req.url ~ "\.(html|css|js)$") {
    set beresp.ttl = 1299s;
  }
}

sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT from " + server.ip;
  } else {
    set resp.http.X-Cache = "MISS";
  }
}

req.restarts: 從新啓動檢查次序

使用PURGE方法去除緩存

 curl -X PURGE http://192.168.48.131/index.htmlxxxxxxxxxx curl -X PURGE 

 

TOMCAT

動態站點:

​ 運行程序

​ 服務器端: CGI common gateway interface

​ 客戶端:

applet:應用小程序

java技術的組成部分:

​ 1 . java程序設計語言, 依賴於API開發

​ 2 . java API

​ 3 . java 虛擬機

​ 4 . java class文件格式規範

java的編譯時環境:

​ 源代碼: .java

​ a.java, b.java, c.java --> Java編譯器(javac)--> a.class, b.class, c.class(字節碼)

java的運行時環境:

​ a.class, b.class, c.class --> JVM <-- Object.class, String.class, ...

java VM的組成部分:

​ java class loader (Java類加載器) : jar 打包格式

​ java執行引擎(執行環境)

java語言的特性:

​ 面向對象: 數據+方法

​ 多線程編程: 適用於並行架構(多核心架構), 實現程序的高效執行

​ 垃圾收集: Garbage Collector

​ 動態連接: 數據被引用次數爲0則能夠被GC回收

​ 動態擴展

android: java + jvm + Linux

ios: Object-C + FreeBSD

Java的發展歷史

1995年5月23日,Java語言誕生 1996年1月,第一個JDK-JDK1.0誕生 1996年4月,10個最主要的操做系統供應商申明將在其產品中嵌入JAVA技術 1996年9月,約8.3萬個網頁應用了JAVA技術來製做 1997年2月18日,JDK1.1發佈 1997年4月2日,JavaOne會議召開,參與者逾一萬人,創當時全球同類會議規模之紀錄 1997年9月,JavaDeveloperConnection社區成員超過十萬 1998年2月,JDK1.1被下載超過2,000,000次 1998年12月8日,JAVA2企業平臺J2EE發佈 1999年6月,SUN公司發佈Java的三個版本:標準版(JavaSE,之前是J2SE)、企業版(JavaEE之前是J2EE)和微型版(JavaME,之前是J2ME) 2000年5月8日,JDK1.3發佈 2000年5月29日,JDK1.4發佈 2001年6月5日,NOKIA宣佈,到2003年將出售1億部支持Java的手機 2001年9月24日,J2EE1.3發佈 2002年2月26日,J2SE1.4發佈,自此Java的計算能力有了大幅提高 2004年9月30日18:00PM,J2SE1.5發佈,成爲Java語言發展史上的又一里程碑。爲了表示該版本的重要性,J2SE1.5改名爲Java SE 5.0 2005年6月,JavaOne大會召開,SUN公司公開Java SE 6。此時,Java的各類版本已經改名,以取消其中的數字「2」:J2EE改名爲Java EE,J2SE改名爲Java SE,J2ME改名爲Java ME 2006年12月,SUN公司發佈JRE6.0 2009年4月7日Google App Engine開始支持Java 2009年04月20日,甲骨文74億美圓收購Sun。取得java的版權。 2010年11月,因爲甲骨文對於Java社區的不友善,所以Apache揚言將退出JCP。 2011年7月28日,甲骨文發佈java7.0的正式版。 2014年3月19日,甲骨文公司發佈java8.0的正式版。

主要服務

1.JDBC(Java Database Connectivity)提供鏈接各類關係數據庫的統一接口,做爲數據源,能夠爲多種關係數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成。JDBC爲工具/數據庫開發人員提供了一個標準的API,據此能夠構建更高級的工具和接口,使數據庫開發人員可以用純Java API 編寫數據庫應用程序,同時,JDBC也是個商標名。 2.EJB(Enterprise JavaBeans)使得開發者方便地建立、部署和管理跨平臺的基於組件的企業應用。 3.Java RMI(Java Remote Method Invocation)用來開發分佈式Java應用程序。一個Java對象的方法能被遠程Java虛擬機調用。這樣,遠程方法激活能夠發生在對等的兩端,也能夠發生在客戶端和服務器之間,只要雙方的應用程序都是用Java寫的。 4.Java IDL(Java Interface Definition Language) 提供與CORBA(Common Object Request Broker Architecture)的無縫的互操做性。這使得Java能集成異構的商務信息資源。 5.JNDI(Java Naming and Directory Interface)提供從Java平臺到的統一的無縫的鏈接。這個接口屏蔽了企業網絡所使用的各類命名和目錄服務。 6.JMAPI(Java Management API)爲異構網絡上系統、網絡和服務管理的開發提供一整套豐富的對象和方法。 7.JMS(Java Message Service)提供企業消息服務,如可靠的消息隊列、發佈和訂閱通訊、以及有關推拉(Push/Pull)技術的各個方面。 8.JTS(Java transaction Service)提供存取事務處理資源的開放標準,這些事務處理資源包括事務處理應用程序、事務處理管理及監控。 9.JMF(Java Media Framework API),她能夠幫助開發者把音頻、視頻和其餘一些基於時間的媒體放到Java應用程序或applet小程序中去,爲多媒體開發者提供了捕捉、回放、編解碼等工具,是一個彈性的、跨平臺的多媒體解決方案。 10.Annotation(Java Annotation),在已經發布的JDK1.5(tiger)中增長新的特點叫Annotation。Annotation提供一種機制,將程序的元素如:類,方法,屬性,參數,本地變量,包和元數據聯繫起來。這樣編譯器能夠將元數據存儲在Class文件中。這樣虛擬機和其它對象能夠根據這些元數據來決定如何使用這些程序元素或改變它們的行爲。 在Java技術中,值得關注的還有JavaBeans,它是一個開放的標準的組件體系結構,它獨立於平臺,但使用Java語言。一個JavaBean是一個知足JavaBeans規範的Java類,一般定義了一個現實世界的事物或概念。一個JavaBean的主要特徵包括屬性、方法和事件。一般,在一個支持JavaBeans規範的開發環境(如Sun Java Studio 和IBM VisualAge for Java)中,能夠可視地操做JavaBean,也能夠使用JavaBean構造出新的JavaBean。JavaBean的優點還在於Java帶來的可移植性。EJB (Enterprise JavaBeans) 將JavaBean概念擴展到Java服務端組件體系結構,這個模型支持多層的分佈式對象應用。除了JavaBeans,典型的組件體系結構還有DCOM和CORBA,關於這些組件體系結構的深刻討論超出了本書的範圍。 11.javaFX Sun剛剛發佈了JavaFX技術的正式版,它使您能利用JavaFX 編程語言開發富互聯網應用程序(RIA)。JavaFX Script編程語言(如下稱爲JavaFX)是Sun微系統公司開發的一種declarative,staticallytyped(聲明性的、靜態類型)腳本語言。JavaFX技術有着良好的前景,包括能夠直接調用Java API的能力。由於JavaFXScript是靜態類型,它一樣具備結構化代碼、重用性和封裝性,如包、類、繼承和單獨編譯和發佈單元,這些特性使得使用Java技術建立和管理大型程序變爲可能。 JavaFX從它2007年發佈以來,表現一直差強人意。Oracle收購了Sun以後,在JavaFX中投入了大量的精力進行推廣和更新。JavaFX比較出名的應用應該是在2010年溫哥華冬奧會上,調整了JavaFX中的不少概念,以及從新設計和實現了不少重要組件以後,獲得的就是如今的JavaFX 2.0。JavaFX 2.0的beta版已經發布,正式版則定於2010年第3季度發佈。JavaFX 2.0的新特性使得開發人員應該須要從新審視它在RIA開發領域中的位置。在不少狀況下,JavaFX 2.0也會是不錯的選擇。 12.JMX(Java Management Extensions,即Java管理擴展)是一個爲應用程序、設備、系統等植入 管理功能的框架。JMX能夠跨越一系列異構操做系統平臺、系統體系結構和網絡傳輸協議,靈活的開發無縫 集成的系統、網絡和服務管理應用。 13.JPA(Java Persistence API),JPA經過JDK 5.0註解或XML(標準通用標記語言的子集)描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中。 14.JSP(Java Server Pages)是由Sun Microsystems公司倡導、許多公司參與一塊兒創建的一種動態網頁技術標準。JSP技術有點相似ASP技術,它是在傳統的網頁HTML文件(.htm,.html)中插入Java程序段(Scriptlet)和JSP標記(tag),從而造成JSP文件(*.jsp)。 用JSP開發的Web應用是跨平臺的,既能在Linux下運行,也能在其餘操做系統上運行。

Java環境

.java --> javac --> .class

JRE: Java Running Environment

​ 由JVM(Hotspot) + JavaSE API

JDK: JDK是 Java 語言的軟件開發工具包,主要用於移動設備、嵌入式設備上的java應用程序。JDK是整個java開發的核心,它包含了JAVA的運行環境,JAVA工具和JAVA基礎的類庫。

​ Java程序設計語言

​ 工具及工具API

​ JRE

Java SE: Standard Edtion, J2SE. 支持面向桌面級應用, 提供完整的Java核心API

Java EE: Enterprise Edition, J2EE 支持使用多層次架構的企業應用(如EJB, CRM等), 包含了Java SE, 並額外提供了大量企業級別的類庫.

Java ME: Micro Edition, J2ME. 輕量級Java

方法區--->堆--->棧--->PC寄存機器--->本地方法棧

堆區域: 存放對象

CGI: 在服務器端進行運行腳本

servlet container: servlet 容器

html必須硬編碼在java代碼中

jsp: java類,開發動態服務器應用程序的.依賴工具jasper, 將存在着嵌入在html文檔中的程序整個總體轉換爲servlet代碼. 直接使用<% %>直接嵌入在HTML文檔中, jasper可以用於檢測此html頁面中的標記提取

<html>
	<%
	%>
</html>

JAVA EE Application Servers

Websphere: IBM提供, 幾乎徹底兼容企業級EE環境平臺. %40. 過於重量級 Weblogic: BEA公司提供, 後被oracle收購. %30 oc4j: oracle提供 JBoss: Redhat開源 JOnAS Geronimo Glassfish

Tomcat: catalina Apache開發的前身 Jetty: 更輕量級, taobao使用 Resin: 僅供學習

JDK分類:

​ Oracle: JDK 不開源可是開放使用

​ Oracle: JRockit

​ Open: OpenJDK

穩定的JDK版本:

​ jdk-6u31

​ jdk-7u9

編譯安裝java環境

使用rpm安裝jdk包, 到java的官網下載

配置java的home路徑在/etc/profile.d/java.sh

export JAVA_HOME=/usr/java/latest
export PATH=$JAVA_HOME/bin:$PATH

查看總共運行多少個java程序

jps

Java 測試代碼

public class Test{
	public static void main(String[] args){
		System.out.println("Hello,Welcome to MageEdu Linux Learning Center!");
	}
}

tomcat 3.x 第一版

tomcat 4.0, Catelina

配置tomcat環境變量/etc/profile.d/tomcat.sh

export CATALINA_HOME=/usr/local/tomcat
export PATH=$CATALINA_HOME/bin:$PATH

查看tomcat版本

catalina.sh version

監測tomcat的配置語法

catalina.sh configtest

Tomcat配置層次

<Server
	<Service>
		<Connecter />	#簡單組件
		<engine>
			<host>
				<context>
				</context>
			</host>
		</engine>
	</Service>
</Server>

頂級組件: 位於整個配置的最外層

容器類組件: 能夠包含其餘組件的組件

鏈接器組件: 鏈接用戶請求至tomcat

被嵌套類的組件: 位於一個容器當中,不能包含其餘組件

容器類:

​ engine: 核心容器, tomcat真正提供jsp解析轉換並提供服務的組件. catalina引擎, 負責經過connector接受用戶請求, 分析請求並處理請求. 引擎內的 能夠有多個.

​ host: 相似於httpd中的虛擬主機, 通常而言支持基於FQDN的虛擬主機

​ context: 最內層的容器類組件, 一個context一般表明一個webapp; 配置context的主要目的,指定對應的webapp的根目錄, 還能爲webapp指定額外的屬性, 如部署方式等

部署: 使用類加載器, 爲webapp準備好其依賴的全部類;

服務類:

​ service: 將鏈接器關聯至engine; 一個service內部能夠有多個鏈接器,可是職能有一個engine

頂級組件: server, 表示一個運行與JVM中的tomcat實例;

嵌套類組件:

​ valve: 攔截請求並在將其轉至對應的webapp以前進行某種處理操做; 能夠用於任何容器中

​ access log valve: 訪問日誌

​ remote address filter value: 基於IP作訪問控制

​ logger: 日誌記錄器, 用於記錄組件內部的狀態信息

​ 可用於除context以外的任何容器之中

​ realm: 關聯一個用戶認證庫, 實現認證和受權, 能夠用於任何容器類的組件中.

​ UserDatabaseRealm: 使用JNDI自定義的用戶認證庫

​ MemoryRealm: tomcat-users.xml中

​ JDBCRealm: 基於JDBC鏈接至數據庫中查找用戶

apache jserv protocol: 爲一種二進制協議, 使用httpd反向代理用戶請求至tomcat時, 在httpd和tomcat之間使用.

Tomcat sysV 服務腳本

#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 2345 96 14
# description: The Apache Tomcat servlet/JSP container.
JAVA_HOME=/usr/java/latest
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
case $1 in
start)
        exec $CATALINA_HOME/bin/catalina.sh start ;;
stop)
        exec $CATALINA_HOME/bin/catalina.sh stop ;;
restart)
        $CATALINA_HOME/bin/catalina.sh stop
        sleep 2
        exec $CATALINA_HOME/bin/catalina.sh start ;;
*)
        exec $CATALINA_HOME/bin/catalina.sh $1 ;;
esac

Tomcat 常見組件

一、服務器(server):Tomcat的一個實例,一般一個JVM只能包含一個Tomcat實例;所以,一臺物理服務器上能夠在啓動多個JVM的狀況下在每個JVM中啓動一個Tomcat實例,每一個實例分屬於一個獨立的管理端口。這是一個頂級組件。 二、服務(service):一個服務組件一般包含一個引擎和與此引擎相關聯的一個或多個鏈接器。給服務命名能夠方便管理員在日誌文件中識別不一樣服務產生的日誌。一個server能夠包含多個service組件,但一般情下只爲一個service指派一個server。

鏈接器類組件: 三、鏈接器(connectors):負責鏈接客戶端(能夠是瀏覽器或Web服務器)請求至Servlet容器內的Web應用程序,一般指的是接收客戶發來請求的位置及服務器端分配的端口。默認端口一般是HTTP協議的8080,管理員也能夠根據本身的須要改變此端口。一個引擎能夠配置多個鏈接器,但這些鏈接器必須使用不一樣的端口。默認的鏈接器是基於HTTP/1.1的Coyote。同時,Tomcat也支持AJP、JServ和JK2鏈接器。

容器類組件: 四、引擎(Engine):引擎通是指處理請求的Servlet引擎組件,即Catalina Servlet引擎,它檢查每個請求的HTTP首部信息以辨別此請求應該發往哪一個host或context,並將請求處理後的結果返回的相應的客戶端。嚴格意義上來講,容器沒必要非得經過引擎來實現,它也能夠是隻是一個容器。若是Tomcat被配置成爲獨立服務器,默認引擎就是已經定義好的引擎。而若是Tomcat被配置爲Apache Web服務器的提供Servlet功能的後端,默認引擎將被忽略,由於Web服務器自身就能肯定將用戶請求發往何處。一個引擎能夠包含多個host組件。 五、主機(Host):主機組件相似於Apache中的虛擬主機,但在Tomcat中只支持基於FQDN的「虛擬主機」。一個引擎至少要包含一個主機組件。 六、上下文(Context):Context組件是最內層次的組件,它表示Web應用程序自己。配置一個Context最主要的是指定Web應用程序的根目錄,以便Servlet容器可以將用戶請求發往正確的位置。Context組件也可包含自定義的錯誤頁,以實如今用戶訪問發生錯誤時提供友好的提示信息。

被嵌套類(nested)組件: 這類組件一般包含於容器類組件中以提供具備管理功能的服務,它們不能包含其它組件,但有些卻能夠由不一樣層次的容器各自配置。 七、閥門(Valve):用來攔截請求並在將其轉至目標以前進行某種處理操做,相似於Servlet規範中定義的過濾器。Valve能夠定義在任何容器類的組件中。Valve常被用來記錄客戶端請求、客戶端IP地址和服務器等信息,這種處理技術一般被稱做請求轉儲(request dumping)。請求轉儲valve記錄請求客戶端請求數據包中的HTTP首部信息和cookie信息文件中,響應轉儲valve則記錄響應數據包首部信息和cookie信息至文件中。 八、日誌記錄器(Logger):用於記錄組件內部的狀態信息,可被用於除Context以外的任何容器中。日誌記錄的功能可被繼承,所以,一個引擎級別的Logger將會記錄引擎內部全部組件相關的信息,除非某內部組件定義了本身的Logger組件。 九、領域(Realm):用於用戶的認證和受權;在配置一個應用程序時,管理員能夠爲每一個資源或資源組定義角色及權限,而這些訪問控制功能的生效須要經過Realm來實現。Realm的認證能夠基於文本文件、數據庫表、LDAP服務等來實現。Realm的效用會遍佈整個引擎或頂級容器,所以,一個容器內的全部應用程序將共享用戶資源。同時,Realm能夠被其所在組件的子組件繼承,也能夠被子組件中定義的Realm所覆蓋。

引擎(Engine):引擎是指處理請求的Servlet引擎組件,即Catalina Servlet引擎,它從HTTPconnector接收請求並響應請求。它檢查每個請求的HTTP首部信息以辨別此請求應該發往哪一個host或context,並將請求處理後的結果返回的相應的客戶端。嚴格意義上來講,容器沒必要非得經過引擎來實現,它也能夠是隻是一個容器。若是Tomcat被配置成爲獨立服務器,默認引擎就是已經定義好的引擎。而若是Tomcat被配置爲Apache Web服務器的提供Servlet功能的後端,默認引擎將被忽略,由於Web服務器自身就能肯定將用戶請求發往何處。一個引擎能夠包含多個host組件。

鏈接器屬性

定義鏈接器能夠使用多種屬性,有些屬性也只適用於某特定的鏈接器類型。通常說來,常見於server.xml中的鏈接器類型一般有4種: 1) HTTP鏈接器 2) SSL鏈接器 3) AJP 1.3鏈接器 4) proxy鏈接器

<Connector port="8080" protocol="HTTP/1.1"
      maxThreads="150" connectionTimeout="20000"
      redirectPort="8443"/>

定義鏈接器時能夠配置的屬性很是多,但一般定義HTTP鏈接器時必須定義的屬性只有「port」,定義AJP鏈接器時必須定義的屬性只有"protocol",由於默認的協議爲HTTP。如下爲經常使用屬性的說明: 1) address:指定鏈接器監聽的地址,默認爲全部地址,即0.0.0.0; 2) maxThreads:支持的最大併發鏈接數,默認爲200; 3) port:監聽的端口,默認爲0; 4) protocol:鏈接器使用的協議,默認爲HTTP/1.1,定義AJP協議時一般爲AJP/1.3; 5) redirectPort:若是某鏈接器支持的協議是HTTP,當接收客戶端發來的HTTPS請求時,則轉發至此屬性定義的端口; 6) connectionTimeout:等待客戶端發送請求的超時時間,單位爲毫秒,默認爲60000,即1分鐘; 7) enableLookups:是否經過request.getRemoteHost()進行DNS查詢以獲取客戶端的主機名;默認爲true; 8) acceptCount:設置等待隊列的最大長度;一般在tomcat全部處理線程均處於繁忙狀態時,新發來的請求將被放置於等待隊列中;

<Connector port="8443"
    maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS" />

Engine組件

Engine是Servlet處理器的一個實例,即servlet引擎,默認爲定義在server.xml中的Catalina。Engine須要defaultHost屬性來爲其定義一個接收全部發往非明肯定義虛擬主機的請求的host組件。如前面示例中定義的:

經常使用的屬性定義: defaultHost:Tomcat支持基於FQDN的虛擬主機,這些虛擬主機能夠經過在Engine容器中定義多個不一樣的Host組件來實現;但若是此引擎的鏈接器收到一個發往非非明肯定義虛擬主機的請求時則須要將此請求發往一個默認的虛擬主機進行處理,所以,在Engine中定義的多個虛擬主機的主機名稱中至少要有一個跟defaultHost定義的主機名稱同名; name:Engine組件的名稱,用於日誌和錯誤信息記錄時區別不一樣的引擎;

Engine容器中能夠包含Realm、Host、Listener和Valve子容器。

Host組件

位於Engine容器中用於接收請求並進行相應處理的主機或虛擬主機,如前面示例中的定義:

  <Host name="localhost" appBase="webapps"
    unpackWARs="true" autoDeploy="true"
    xmlValidation="false" xmlNamespaceAware="false">
  </Host>

經常使用屬性說明: 1) appBase:此Host的webapps目錄,即存放非歸檔的web應用程序的目錄或歸檔後的WAR文件的目錄路徑;能夠使用基於$CATALINA_HOME的相對路徑; 2) autoDeploy:在Tomcat處於運行狀態時放置於appBase目錄中的應用程序文件是否自動進行deploy;默認爲true; 3) unpackWars:在啓用此webapps時是否對WAR格式的歸檔文件先進行展開;默認爲true;

<Engine name="Catalina" defaultHost="localhost">
  <Host name="localhost" appBase="webapps">
    <Context path="" docBase="ROOT"/>
    <Context path="/bbs" docBase="/web/bss"
      reloadable="true" crossContext="true"/>
  </Host>
  
  <Host name="mail.magedu.com" appBase="/web/mail">
    <Context path="" docBase="ROOT"/>
  </Host>
</Engine>

主機別名定義: 若是一個主機有兩個或兩個以上的主機名,額外的名稱都可以以別名的形式進行定義,以下:

<Host name="www.magedu.com" appBase="webapps" unpackWARs="true">
  <Alias>magedu.com</Alias>
</Host>

Context組件

Context在某些意義上相似於apache中的路徑別名,一個Context定義用於標識tomcat實例中的一個Web應用程序;以下面的定義:

<!-- Tomcat Root Context -->
<Context path="" docBase="/web/webapps"/>

<!-- buzzin webapp -->
<Context path="/bbs"
  docBase="/web/threads/bbs"
  reloadable="true">
</Context>

<!-- chat server -->
  <Context path="/chat" docBase="/web/chat"/>
  
<!-- darian web -->
<Context path="/darian" docBase="darian"/>

在Tomcat6中,每個context定義也能夠使用一個單獨的XML文件進行,其文件的目錄爲$CATALINA_HOME/conf//。能夠用於Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。

經常使用的屬性定義有: 1) docBase:相應的Web應用程序的存放位置;也能夠使用相對路徑,起始路徑爲此Context所屬Host中appBase定義的路徑;切記,docBase的路徑名不能與相應的Host中appBase中定義的路徑名有包含關係,好比,若是appBase爲deploy,而docBase毫不能爲deploy-bbs類的名字; 2) path:相對於Web服務器根路徑而言的URI;若是爲空「」,則表示爲此webapp的根路徑;若是context定義在一個單獨的xml文件中,此屬性不須要定義; 3) reloadable:是否容許從新加載此context相關的Web應用程序的類;默認爲false

Realm組件

一個Realm表示一個安全上下文,它是一個受權訪問某個給定Context的用戶列表和某用戶所容許切換的角色相關定義的列表。所以,Realm就像是一個用戶和組相關的數據庫。定義Realm時唯一必需要提供的屬性是classname,它是Realm的多個不一樣實現,用於表示此Realm認證的用戶及角色等認證信息的存放位置。 JAASRealm:基於Java Authintication and Authorization Service實現用戶認證; JDBCRealm:經過JDBC訪問某關係型數據庫表實現用戶認證; JNDIRealm:基於JNDI使用目錄服務實現認證信息的獲取; MemoryRealm:查找tomcat-user.xml文件實現用戶信息的獲取; UserDatabaseRealm:基於UserDatabase文件(一般是tomcat-user.xml)實現用戶認證,它實現是一個徹底可更新和持久有效的MemoryRealm,所以可以跟標準的MemoryRealm兼容;它經過JNDI實現;

下面是一個常見的使用UserDatabase的配置: <Realm className=」org.apache.catalina.realm.UserDatabaseRealm」

resourceName=」UserDatabase」/>

下面是一個使用JDBC方式獲取用戶認證信息的配置: <Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"

driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority"
connectionName="test" connectionPassword="test"
userTable="users" userNameCol="user_name"
userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />

Valve組件

Valve相似於過濾器,它能夠工做於Engine和Host/Context之間、Host和Context之間以及Context和Web應用程序的某資源之間。一個容器內能夠創建多個Valve,並且Valve定義的次序也決定了它們生效的次序。Tomcat6中實現了多種不一樣的Valve: AccessLogValve:訪問日誌Valve ExtendedAccessValve:擴展功能的訪問日誌Valve JDBCAccessLogValve:經過JDBC將訪問日誌信息發送到數據庫中; RequestDumperValve:請求轉儲Valve; RemoteAddrValve:基於遠程地址的訪問控制; RemoteHostValve:基於遠程主機名稱的訪問控制; SemaphoreValve:用於控制Tomcat主機上任何容器上的併發訪問數量; JvmRouteBinderValve:在配置多個Tomcat爲以Apache經過mod_proxy或mod_jk做爲前端的集羣架構中,當指望中止某節點時,能夠經過此Valve將用記請求定向至備用節點;使用此Valve,必須使用JvmRouteSessionIDBinderListener; ReplicationValve:專用於Tomcat集羣架構中,能夠在某個請求的session信息發生更改時觸發session數據在各節點間進行復制; SingleSignOn:將兩個或多個須要對用戶進行認證webapp在認證用戶時鏈接在一塊兒,即一次認證便可訪問全部鏈接在一塊兒的webapp; ClusterSingleSingOn:對SingleSignOn的擴展,專用於Tomcat集羣當中,須要結合ClusterSingleSignOnListener進行工做;

RemoteHostValve和RemoteAddrValve能夠分別用來實現基於主機名稱和基於IP地址的訪問控制,控制自己能夠經過allow或deny來進行定義,這有點相似於Apache的訪問控制功能;以下面的Valve則實現了僅容許本機訪問/probe:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.0\.0\.1"/>

 

其中相關屬性定義有: 1) className:相關的java實現的類名,相應於分別應該爲org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve; 2) allow:以逗號分開的容許訪問的IP地址列表,支持正則表達式,所以,點號「.」用於IP地址時須要轉義;僅定義allow項時,非明確allow的地址均被deny; 3) deny: 以逗號分開的禁止訪問的IP地址列表,支持正則表達式;使用方式同allow;

GlobalNamingResource

應用於整個服務器的JNDI映射,此能夠避免每一個Web應用程序都須要在各自的web.xml建立,這在web應用程序以WAR的形式存在時尤其有用。它一般能夠包含三個子元素: 1) Environment; 2) Resource; 3) ResourceEnvRef;

其餘組件

WatchedResource

WatchedResource能夠用於Context中監視指定的webapp程序文件的改變,而且可以在監視到文件內容發生改變時從新裝載此文件。

Listener

Listener用於建立和配置LifecycleListener對象,而LifecycleListener一般被開發人員用來建立和刪除容器。

Loader

Java的動態裝載功能是其語言功能強大表現之一,Servlet容器使用此功能在運行時動態裝載servlet和它們所依賴的類。Loader能夠用於Context中控制java類的加載。

Stores

PersistentManager必須包含一個Store元素以指定將會話數據存儲至何處。這一般有兩種實現方式:FileStore和JDBCStore。

Resources

常常用於實如今Context中指定須要裝載的但不在Tomcat本地磁盤上的應用資源,如Java類,HTML頁面,JSP文件等。

Cluster

專用於配置Tomcat集羣的元素,可用於Engine和Host容器中。在用於Engine容器中時,Engine中的全部Host均支持集羣功能。在Cluster元素中,須要直接定義一個Manager元素,這個Manager元素有一個其值爲org.apache.catalina.ha.session.DeltaManager或org.apache.catalina.ha.session.BackupManager的className屬性。同時,Cluster中還須要分別定義一個Channel和ClusterListener元素。

Channel

用於Cluster中給集羣中同一組中的節點定義通訊「信道」。Channel中須要至少定義Membership、Receiver和Sender三個元素,此外還有一個可選元素Interceptor

Membership

用於Channel中配置同一通訊信道上節點集羣組中的成員狀況,即監控加入當前集羣組中的節點並在各節點間傳遞心跳信息,並且能夠在接收不到某成員的心跳信息時將其從集羣節點中移除。Tomcat6中Membership的實現是org.apache.catalina.tribes.membership.McastService。

Sender

用於Channel中配置「複製信息」的發送器,實現發送須要同步給其它節點的數據至集羣中的其它節點。發送器不須要屬性的定義,但能夠在其內部定義一個Transport元素。

Transport

用於Sender內部,配置數據如何發送至集羣中的其它節點。Tomcat6有兩種Transport的實現: 1) PooledMultiSender 基於Java阻塞式IO,能夠將一次將多個信息併發發送至其它節點,但一次只能傳送給一個節點。 2)PooledParallelSener 基於Java非阻塞式IO,即NIO,能夠一次發送多個信息至一個或多個節點。

Receiver

用於Channel定義某節點如何從其它節點的Sender接收復制數據,Tomcat6中實現的接收方式有兩種BioReceiver和NioReceiver。

WEB.xml文件

web.xml基於Java Servlet規範,可被用於每個Java servlet容器,一般有兩個存放位置,$CATALINA_BASE/conf和每一個Web應用程序(一般是WEB-INF/web.xml)。Tomcat在deploy一個應用程序時(包括重啓或從新載入),它首先讀取conf/web.xml,然後讀取WEB-INF/web.xml。

tomcat自帶管理器

tomcat自帶兩個管理類的app

​ server status:

​ 獲取狀態信息

​ 部署應用程序

​ host manager

​ 管理虛擬主機

http://www.jspxcms.com/

tomcat架構實現

Tomcat: JDK + servlet, jsp 是一種Java EE不完整的實現

server.xml

​ 頂級類: server

​ 容器類: engine, host, context

​ 服務類: service

​ 鏈接器: connector

​ http, ssl, ajp (apache jserv protocol)

​ 被嵌套類: valve, logger, realm

<server>
	<service>
		<connector />
		<connector />
		<engine>
			<host>
				<context />
				<context />
			</host>
			<host>
			</host>
		</engine>
	</service>
</server>

Tomcat的配置文件

​ server.xml

​ context.xml: 爲部署於此Tomcat實例上的全部web應用程序提供的默認配置文件,每一個webapp均可以使用獨有的context.xml, 一般放置於webapp目錄中的META-INF子目錄中; 經常使用於定義會話管理器, Realm以及JDBC等

​ web.xml: 爲部署於此tomcat實例上的全部web應用程序提供默認部署描述符. 一般用於爲webapp提供基本的servlet定義和MIME映射表等;

​ tomcat-uesrs.xml: 管理權限

​ calalina.policy: 當基於 -security選項啓動tomcat實例時會讀取此配置文件, 此文件爲JAVA的安全策略配置文件, 配置訪問codebase或某些Java類的權限

​ catalina.properties: Java屬性定義文件, 設定類加載器路徑, 安全包列表和一些調整性能的參數信息

​ logging.properties: 定義日誌相關的配置信息, 如日誌級別, 文件路徑等

Tomcat 應用程序"部署"

​ 部署是指將webapp及其所依賴類庫等裝載進tomcat實例上, 以便接受用戶請求. 部署方式:

​ 靜態方式: 在tomcat啓動以前進行的webapp部署

​ 動態方式: 在不打斷tomcat運行的前提下, 經過tomcat manager或其餘命令行工具進行部署

​ TCD: Tomcat Client Deployer

​ 部署是由一類"操做"組成:

​ Deploy: 將webapp的源文件放置於目標目錄, 配置tomcat服務器可以基於context路徑訪問webapp, 並將其特有的類裝載進行裝載等;

​ Redeploy: 從新部署, 主要用於升級時;

​ Undeploy: 取消部署, 中止應用程序並移除並從tomcat實例上移除其部分文件和部署名等;

​ stop: 中止

​ start: 將中止的webapp啓動起來

​ 部署方式:

​ Tomcat Manager

​ ANT 腳本

​ TCD

​ war類歸檔程序的部署, 將歸檔文件複製到$CATALINA_BASE/webapps/目錄中, 並重啓tomcat便可. tomcat會自動展開war歸檔.

webapp體系結構:

​ webapp有特定的組織格式, 是一種層次型目錄結構:一般包含了servlet代碼文件, jsp頁面文件, 類文件, 部署描述符文件等, 通常會打包成歸檔格式

​ /: web應用程序的根目錄(documentRoot)

​ /WEB-INF: 此webapp的私有資源目錄, 一般web.xml和context.xml均放置在此處

​ /WEB-INF/classes: 此webapp自有的類

​ /WEB-INF/lib: 此webapp自有的可以被打包爲jar格式的類

​ /META-INF/: 也是私有區域

webapp的歸檔格式:

​ EJB類歸檔的擴展名爲.jar

​ web應用程序的歸檔擴展名爲.war

​ 資源適配器的擴展名resource adapters .rar

​ 企業級應用程序的擴展名.ear

​ web服務的擴展名爲.ear或.war

Tomcat分離運行方式

standalone configure:

​ request --> web server(tomcat) --> servlet container

apache與tomcat鏈接器通訊的模塊有兩個:

​ mod_jk: apache/1.3, apache /2.0

​ mod_proxy: apache/2.2+

tomcat的鏈接器協議有兩種:

​ http

​ ajp

mod_jk V.S. mod_proxy:

​ 負載均衡

​ 管理接口

​ 兼容性

​ 配置: mod_proxy比較簡單

​ 協議: mod_jk (ajp) , mod_proxy(http/https/ajp)

Tomcat的http鏈接器:

​ 類型有三種: 基於java的http/1.1鏈接器; 基於java的高性能NIO鏈接器; 基於C/C++研發的Native APR HTTP/1.1鏈接器

LNMT:

​ nginx + tomcat(http,https)

​ nginx + tomcat, ....

http{
  upstream tomcat {
  	server 192.168.48.131:8080;
  	server 192.168.48.132:8080;
	}
  server {
  	location ~* \.(jsp|do)$ {
  		proxy_pass http://tomcat;
		}
	}
}

LAMT:

​ apache能夠使用(mod_jk, ajp) + tomcat(ajp connector)

​ apache能夠使用(mod_proxy, (http,https,ajp) + tomcat(http,https,ajp)

​ mod_proxy(http,https,ajp):

mod_proxy.conf

ProxyVia on
ProxyRequests off
ProxyPreserveHost on

ProxyPass / ajp://192.168.48.131:8009/
ProxyPassReverse / ajp://192.168.48.131:8009/

<Location />
	Order Allow,Deny
	Allow from all
</Location>

使用jk_mod

LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/httpd/conf.d/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel  debug
JkMount /* TomcatA
JkMount /status/ statA

workers.properties

worker.list=TomcatA,statA
worker.TomcatA.port=8009
worker.TomcatA.type=ajp13
worker.TomcatA.host=192.168.48.131
worker.TomcatA.lbfactor=1
worker.statA.type=status
LB LAMT

mod_jk的實現方式

workers.properties

worker.list=lbcA,statA
worker.TomcatA.port=8009
worker.TomcatA.type=ajp13
worker.TomcatA.host=192.168.48.131
worker.TomcatA.lbfactor=1
worker.TomcatB.port=8009
worker.TomcatB.type=ajp13
worker.TomcatB.host=192.168.48.137
worker.TomcatB.lbfactor=1

worker.lbcA.type=lb
worker.lbcA.sticky_session=0
worker.lbcA.balance_workers=TomcatA,TomcatB

worker.statA.type=status

mod_jk

LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/httpd/conf.d/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel  notice
JkMount /* lbcA
JkMount /status/ statA

mod_proxy的實現方式

mod_proxy.conf

ProxyVia on
ProxyRequests off
ProxyPreserveHost on
<proxy balancer://lb>
    BalancerMember http://192.168.48.131:80 loadfactor=1 route=TomcatA
    BalancerMember http://192.168.48.137:80 loadfactor=1 route=TomcatB
</Proxy>

ProxyPass / balancer://lb/ stickysession=JSESSIONID
ProxyPassReverse / balancer://lb/

<Location />
    Order Allow,Deny
    Allow from all
</Location>

note: 負載均衡, 且實現會話綁定要注意給每一個tomcat實例的engine容器一個jvmRoute屬性, 此名稱要跟前段調度模塊中使用的名稱保持一致. 另外, 在mod_proxy實現負載均衡的會話綁定時, 還要使用sticksession=JESSIONID(字符必須大寫)

<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatA">

Tomcat會話管理

Manager

1) StandardManager Tomcat6的默認會話管理器,用於非集羣環境中對單個處於運行狀態的Tomcat實例會話進行管理。當Tomcat關閉時,這些會話相關的數據會被寫入磁盤上的一個名叫SESSION.ser的文件,並在Tomcat下次啓動時讀取此文件。 2) PersistentManager 當一個會話長時間處於空閒狀態時會被寫入到swap會話對象,這對於內存資源比較吃緊的應用環境來講比較有用。 3)DeltaManager 用於Tomcat集羣的會話管理器,它經過將改變了會話數據同步給集羣中的其它節點實現會話複製。這種實現會將全部會話的改變同步給集羣中的每個節點,也是在集羣環境中用得最多的一種實現方式。 4)BackupManager 用於Tomcat集羣的會話管理器,與DeltaManager不一樣的是,某節點會話的改變只會同步給集羣中的另外一個而非全部節點。 5)SimpleTcpReplicationManager Tomcat4時用到的版本,過於老舊了。

Tomcat Session集羣

構建DeltaManager集羣步驟

只適合極小規模的tomcat集羣中

1 . 在各節點的server.xml的engine或host容器添加如上內容: 注意修改MemberShip組件中的多播地址address="228.0.0.4", 建議修改Receiver中的address爲本機可以傳遞心跳信息的地址:

2 . 在各節點爲使用組播地址添加路由, 格式爲:

route add -net $MCAST_ADDRESS netmask 255.255.255.255 dev eth0

3 . 在相應應用程序的web.xml中添加<distributable/>

基於DelaManager或者BackupManager內存級別的會話同步

在server.xml配置文件的Engine組件中添加Cluster組件

        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="8">

          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="4000"
                      autoBind="100"
                      selectorTimeout="5000"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>

          <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>

memcached-session-manager

專用的會話服務器. 適合大規模集羣

實現方法...

JVM調優

線程共享內存 (可調優)

​ 方法區: 存儲jvm加載的class, 常量, 靜態變量, 即時編譯器編譯後的代碼等

​ java堆: 存儲java的全部對象實例, 數組等

線程私有內存

​ 程序計數寄存器: 每一個線程有本身的計數寄存器, 存儲當前程序執行字節碼地址

​ jvm棧: jvm會爲每一個運行線程分配一個棧區, 線程調用方法和方法返回時會進行入棧和出站操做

​ 本地方法棧區: 與jvm stack相似,只不過此區域是爲調用本地方法服務

jinfo

JVM

-Xmx: 設置最大堆大小

-xms: 定義堆內存大小

-XX: Newsize (to, from, eden)

-XX: Maxnewsize 在堆內存內部如何分配使用的空間

-XX: PermSize

-XX: MaxPermSize

-XX: SuvivorRatio : Setting New heap size ratios

經過指定變量JAVA_OPTS

Mark-compact Better throughput

Incremental GC(Train) Better Pause

Parallel GC Best Throughput

Goncurrent GC Best Pause

Java性能查看工具

jconsole, visualvm, jprofiler, janalyzer

jstat 查看垃圾回收器的管理狀態

jstat -gc 2023 1s

 

補充

if 判斷語句

在location中使用if語句能夠實現條件判斷,其一般有一個return語句,且通常與有着last或break標記的rewrite規則一同使用。但其也能夠按須要使用在多種場景下,須要注意的是,不當的使用可能會致使不可預料的後果。

syntax
if (condition){
  
}
location / {
	if ($request_method == 「PUT」) {
		proxy_pass http://upload.magedu.com:8080;
	} 

	if ($request_uri ~ "\.(jpg|gif|jpeg|png)$") {
		proxy_pass http://imageservers;
		break;
	}
}

正則表達式匹配:

==: 等值比較;
~:與指定正則表達式模式匹配時返回「真」,判斷匹配與否時區分字符大小寫;
~*:與指定正則表達式模式匹配時返回「真」,判斷匹配與否時不區分字符大小寫;
!~:與指定正則表達式模式不匹配時返回「真」,判斷匹配與否時區分字符大小寫;
!~*:與指定正則表達式模式不匹配時返回「真」,判斷匹配與否時不區分字符大小寫;

文件及目錄匹配判斷:

-f, !-f:判斷指定的路徑是否爲存在且爲文件;
-d, !-d:判斷指定的路徑是否爲存在且爲目錄;
-e, !-e:判斷指定的路徑是否存在,文件或目錄都可;
-x, !-x:判斷指定路徑的文件是否存在且可執行;

WebDAV

web-based Distributed Auhoring and versioning, 一種基於HTTP 1.1協議的通訊協議,它擴展了HTTP1.1, 在GET, POST, HEAD等幾個HTTP標準方法之外添加了一些新的方法,使得應用程序能夠直接對Web Server直接讀寫,並支持文件鎖定(Locking)及解鎖(Unlock), 還能夠支持文件的版本控制

若是想讓http web服務器容許上傳和刪除操做

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
DocumentRoot "/var/www/html"
dav on;

httpwatch

IE的分析工具

libevent

項目主頁: http://libevent.org/

算法複雜度

Big O: 評判數據結構複雜度

O(1): key value
O(logN): 彈性二叉樹
O(n): 紅黑二叉樹
O(n^2)
O(2^n)

URL

URL: http(協議)://host:port/path?queries#fragment

://:@:/;?#

HTTP首部概覽

HTTP首部概覽:

一、 Accept:告訴WEB服務器本身接受什麼介質類型,/ 表示任何類型,type/* 表示該類型下的全部子類型,type/sub-type。 二、 Accept-Charset: 瀏覽器申明本身接收的字符集 Accept-Encoding: 瀏覽器申明本身接收的編碼方法,一般指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzip,deflate) Accept-Language:瀏覽器申明本身接收的語言 語言跟字符集的區別:中文是語言,中文有多種字符集,好比big5,gb2312,gbk等等。 三、 Accept-Ranges:WEB服務器代表本身是否接受獲取其某個實體的一部分(好比文件的一部分)的請求。bytes:表示接受,none:表示不接受。 四、 Age:當代理服務器用本身緩存的實體去響應請求時,用該頭部代表該實體從產生到如今通過多長時間了。 五、 Authorization:當客戶端接收到來自WEB服務器的 WWW-Authenticate 響應時,用該頭部來回應本身的身份驗證信息給WEB服務器。 六、 Cache-Control:請求:no-cache(不要緩存的實體,要求如今從WEB服務器去取) max-age:(只接受 Age 值小於 max-age 值,而且沒有過時的對象) max-stale:(能夠接受過去的對象,可是過時時間必須小於 max-stale 值) min-fresh:(接受其新鮮生命期大於其當前 Age 跟 min-fresh 值之和的緩存對象) 響應:public(能夠用 Cached 內容迴應任何用戶) private(只能用緩存內容迴應先前請求該內容的那個用戶) no-cache(能夠緩存,可是隻有在跟WEB服務器驗證了其有效後,才能返回給客戶端) max-age:(本響應包含的對象的過時時間) ALL: no-store(不容許緩存) 七、 Connection:請求:close(告訴WEB服務器或者代理服務器,在完成本次請求的響應後,斷開鏈接,不要等待本次鏈接的後續請求了)。 keepalive(告訴WEB服務器或者代理服務器,在完成本次請求的響應後,保持鏈接,等待本次鏈接的後續請求)。 響應:close(鏈接已經關閉)。 keepalive(鏈接保持着,在等待本次鏈接的後續請求)。 Keep-Alive:若是瀏覽器請求保持鏈接,則該頭部代表但願 WEB 服務器保持鏈接多長時間(秒)。例如:Keep-Alive:300 八、 Content-Encoding:WEB服務器代表本身使用了什麼壓縮方法(gzip,deflate)壓縮響應中的對象。例如:Content-Encoding:gzip 九、Content-Language:WEB 服務器告訴瀏覽器本身響應的對象的語言。 十、Content-Length: WEB 服務器告訴瀏覽器本身響應的對象的長度。例如:Content-Length: 26012 十一、Content-Range: WEB 服務器代表該響應包含的部分對象爲整個對象的哪一個部分。例如:Content-Range: bytes 21010-47021/47022 十二、Content-Type: WEB 服務器告訴瀏覽器本身響應的對象的類型。例如:Content-Type:application/xml 1三、ETag:就是一個對象(好比URL)的標誌值,就一個對象而言,好比一個 html 文件,若是被修改了,其 Etag 也會別修改,因此ETag 的做用跟 Last-Modified 的做用差很少,主要供 WEB 服務器判斷一個對象是否改變了。好比前一次請求某個 html 文件時,得到了其 ETag,當此次又請求這個文件時,瀏覽器就會把先前得到的 ETag 值發送給WEB 服務器,而後 WEB 服務器會把這個 ETag 跟該文件的當前 ETag 進行對比,而後就知道這個文件有沒有改變了。 1四、 Expired:WEB服務器代表該實體將在何時過時,對於過時了的對象,只有在跟WEB服務器驗證了其有效性後,才能用來響應客戶請求。是 HTTP/1.0 的頭部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT 1五、 Host:客戶端指定本身想訪問的WEB服務器的域名/IP 地址和端口號。例如:Host:rss.sina.com.cn 1六、 If-Match:若是對象的 ETag 沒有改變,其實也就意味著對象沒有改變,才執行請求的動做。 1七、 If-None-Match:若是對象的 ETag 改變了,其實也就意味著對象也改變了,才執行請求的動做。 1八、 If-Modified-Since:若是請求的對象在該頭部指定的時間以後修改了,才執行請求的動做(好比返回對象),不然返回代碼304,告訴瀏覽器 該對象沒有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT 1九、 If-Unmodified-Since:若是請求的對象在該頭部指定的時間以後沒修改過,才執行請求的動做(好比返回對象)。 20、 If-Range:瀏覽器告訴 WEB 服務器,若是我請求的對象沒有改變,就把我缺乏的部分給我,若是對象改變了,就把整個對象給我。瀏覽器經過發送請求對象的 ETag 或者 本身所知道的最後修改時間給 WEB 服務器,讓其判斷對象是否改變了。老是跟 Range 頭部一塊兒使用。 2一、 Last-Modified:WEB 服務器認爲對象的最後修改時間,好比文件的最後修改時間,動態頁面的最後產生時間等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT 2二、 Location:WEB 服務器告訴瀏覽器,試圖訪問的對象已經被移到別的位置了,到該頭部指定的位置去取。例如:Location:http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif 2三、 Pramga:主要使用 Pramga: no-cache,至關於 Cache-Control: no-cache。例如:Pragma:no-cache 2四、 Proxy-Authenticate: 代理服務器響應瀏覽器,要求其提供代理身份驗證信息。Proxy-Authorization:瀏覽器響應代理服務器的身份驗證請求,提供本身的身份信息。 2五、 Range:瀏覽器(好比 Flashget 多線程下載時)告訴 WEB 服務器本身想取對象的哪部分。例如:Range: bytes=1173546- 2六、 Referer:瀏覽器向 WEB 服務器代表本身是從哪一個 網頁/URL 得到/點擊 當前請求中的網址/URL。例如:Referer:http://www.sina.com/ 2七、 Server: WEB 服務器代表本身是什麼軟件及版本等信息。例如:Server:Apache/2.0.61 (Unix) 2八、 User-Agent: 瀏覽器代表本身的身份(是哪一種瀏覽器)。例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/二、0、0、14 2九、 Transfer-Encoding: WEB 服務器代表本身對本響應消息體(不是消息體裏面的對象)做了怎樣的編碼,好比是否分塊(chunked)。例如:Transfer-Encoding: chunked 30、 Vary: WEB服務器用該頭部的內容告訴 Cache 服務器,在什麼條件下才能用本響應所返回的對象響應後續的請求。假如源WEB服務器在接到第一個請求消息時,其響應消息的頭部爲:Content- Encoding: gzip; Vary: Content-Encoding那麼 Cache 服務器會分析後續請求消息的頭部,檢查其 Accept-Encoding,是否跟先前響應的 Vary 頭部值一致,便是否使用相同的內容編碼方法,這樣就能夠防止 Cache 服務器用本身 Cache 裏面壓縮後的實體響應給不具有解壓能力的瀏覽器。例如:Vary:Accept-Encoding 3一、 Via: 列出從客戶端到 OCS 或者相反方向的響應通過了哪些代理服務器,他們用什麼協議(和版本)發送的請求。當客戶端請求到達第一個代理服務器時,該服務器會在本身發出的請求裏面添 加 Via 頭部,並填上本身的相關信息,當下一個代理服務器收到第一個代理服務器的請求時,會在本身發出的請求裏面複製前一個代理服務器的請求的Via 頭部,並把本身的相關信息加到後面,以此類推,當 OCS 收到最後一個代理服務器的請求時,檢查 Via 頭部,就知道該請求所通過的路由。例如:Via:1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)

 

Abbreviation

pv: page view 頁面瀏覽量

RDP: Remote Desktop Protocol port 3389

 

 

 

 

 

 

 

 

 

 

 

相關文章
相關標籤/搜索