nuster基于 HAProxy 的高性能 HTTP 緩存服務(wù)器和 RESTful NoSQL 緩存服務(wù)
nuster
基于HAProxy的高性能HTTP緩存服務(wù)器和RESTful NoSQL緩存服務(wù)器。
中文版更新可能不及時(shí),最新版請(qǐng)參照英文版README.md
目錄
介紹
nuster是一個(gè)基于HAProxy的高性能HTTP緩存服務(wù)器和RESTful NoSQL緩存服務(wù)器,完全兼容HAProxy,并且利用HAProxy的ACL功能來提供非常細(xì)致的緩存規(guī)則。
特性
HTTP/TCP負(fù)載均衡器
nuster可以作為HTTP/TCP負(fù)載均衡器使用。
- 繼承了HAProxy的所有特性,完全兼容HAProxy
- 負(fù)載均衡
- 前端后端HTTPS
- HTTP壓縮
- HTTP重寫重定向
- HTTP信息增刪改
- HTTP2
- 監(jiān)控
- 粘性
- 訪問控制
- 內(nèi)容切換
HTTP緩存服務(wù)器
nuster也可以用作類似Varnish或者Nginx那樣的HTTP緩存服務(wù)器,來緩存動(dòng)態(tài)或者靜態(tài)的HTTP資源。
- HAProxy的所有特性(HTTPS, HTTP/2, ACL, etc)
- 非???/li>
- 強(qiáng)大的動(dòng)態(tài)緩存功能
- 基于HTTP method, URI, path, query, header, cookies, etc
- 基于HTTP request or response contents, etc
- 基于environment variables, server state, etc
- 基于SSL version, SNI, etc
- 基于connection rate, number, byte, etc
- 緩存管理
- 緩存清除
- 緩存統(tǒng)計(jì)信息
- 緩存生存時(shí)間
- 持久化
RESTful NoSQL緩存服務(wù)器
nuster也可以用作RESTful NoSQL緩存服務(wù)器, 用HTTP POST/GET/DELETE 來 添加/取得/刪除 Key/Value.
可以像Memcached或者Redis那樣放在應(yīng)用和數(shù)據(jù)庫之間作為內(nèi)部KV緩存使用,也可以放在用戶和應(yīng)用之間作為面向用戶的NoSQL使用。 支持header, cookie等等,所以可以將不同的用戶數(shù)據(jù)存到相同的路勁。
- HAProxy的所有特性(HTTPS, HTTP/2, ACL, etc)
- 有條件的緩存
- 內(nèi)部KV緩存
- 面向用戶緩存
- 支持任何類型的數(shù)據(jù)
- 支持所有編程語言,不需要特定的庫,只需HTTP支持
- 持久化
性能
非常快, 單進(jìn)程模式下是nginx的3倍,多進(jìn)程下nginx的2倍,varnish的3倍。
入門指南
下載
生產(chǎn)環(huán)境的話從Download下載最新穩(wěn)定版, 其他情況可以git clone。
編譯
make TARGET=linux2628 USE_LUA=1 LUA_INC=/usr/include/lua5.3 USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1
make install PREFIX=/usr/local/nuster
添加
USE_PTHREAD_PSHARED=1使用pthread
如果不需要可以刪除
USE_LUA=1 LUA_INC=/usr/include/lua5.3 USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1
具體可以參考HAProxy INSTALL。
配置文件
準(zhǔn)備一個(gè)配置文件: nuster.cfg
global
nuster cache on data-size 100m
nuster nosql on data-size 200m
master-worker # v3
defaults
mode http
frontend fe
bind *:8080
#bind *:4433 ssl crt example.com.pem alpn h2,http/1.1
use_backend be2 if { path_beg /_kv/ }
default_backend be1
backend be1
nuster cache on
nuster rule img ttl 1d if { path_beg /img/ }
nuster rule api ttl 30s if { path /api/some/api }
server s1 127.0.0.1:8081
server s2 127.0.0.1:8082
backend be2
nuster nosql on
nuster rule r1 ttl 3600
nuster監(jiān)聽8080端口,接受HTTP請(qǐng)求。 /_kv/開頭的請(qǐng)求分配到backend be2, 可以發(fā)送HTTP POST/GET/DELETE到/_kv/any_key 來 添加/取得/刪除 Key/Value. 其他的請(qǐng)求都被分配到backend be1, 并且會(huì)被轉(zhuǎn)發(fā)到服務(wù)器s1 or s2. 其中/img/*請(qǐng)求會(huì)被緩存1天,而/api/some/api會(huì)被緩存30秒。
啟動(dòng)
/usr/local/nuster/sbin/nuster -f nuster.cfg
Docker
docker pull nuster/nuster
docker run -d -v /path/to/nuster.cfg:/etc/nuster/nuster.cfg:ro -p 8080:8080 nuster/nuster
使用方法
nuster基于HAProxy, 支持所有的HAProxy指令。
基本
配置文件里有四個(gè)基本的sections: global, defaults, frontend and backend。
- global
- 定義全局指令
- 需要定義
nuster cache onornuster nosql on,否則cache和nosql無法使用
- defaults
- 定義
frontend,backend的默認(rèn)參數(shù) - 可以在
frontendorbackendsection重新定義
- 定義
- frontend
- 定義監(jiān)聽端口等等面向用戶的設(shè)置
- bankend
- 定義后端服務(wù)器等等設(shè)置
- 需要設(shè)置
nuster cache onornuster nosql on, 否則該backend沒有nosql或者nosql功能 - 需要設(shè)置
nuster rule
可以定義多個(gè)frontend or backend . 如果定義了nuster cache|nosql off或者沒有nuster cache|nosql on|off, nuster就是一個(gè)HAProxy。
無法在listen里定義nuster。
具體參考/doc下的HAProxy文檔, 或者在線HAProxy文檔
As TCP loader balancer
frontend mysql-lb
bind *:3306
mode tcp
default_backend mysql-cluster
backend mysql-cluster
balance roundrobin
mode tcp
server s1 10.0.0.101:3306
server s2 10.0.0.102:3306
server s3 10.0.0.103:3306
As HTTP/HTTPS loader balancer
frontend web-lb
bind *:80
#bind *:443 ssl crt XXX.pem
mode http
default_backend apps
backend apps
balance roundrobin
mode http
server s1 10.0.0.101:8080
server s2 10.0.0.102:8080
server s3 10.0.0.103:8080
#server s4 10.0.0.101:8443 ssl verify none
As HTTP cache server
global
nuster cache on data-size 200m
frontend fe
bind *:8080
default_backend be
backend be
nuster cache on
nuster rule all
server s1 127.0.0.1:8081
As RESTful NoSQL cache server
global
nuster nosql on data-size 200m
frontend fe
bind *:8080
default_backend be
backend be
nuster nosql on
nuster rule r1 ttl 3600
指令
global: nuster manager
syntax:
nuster manager on|off [uri URI] [purge-method method]
default: off
context: global
定義并開啟manager/stats/purge API, uri 和 purge method。
默認(rèn)是關(guān)閉的. 如果開啟了,注意開啟訪問控制(see FAQ).
具體請(qǐng)參考管理.
uri
自定義管理URI, 默認(rèn)是 /nuster
purge-method
自定義PURGE用的HTTP method,默認(rèn)是 PURGE.
global: nuster cache|nosql
syntax:
nuster cache on|off [data-size size] [dict-size size] [dir DIR] [dict-cleaner n] [data-cleaner n] [disk-cleaner n] [disk-loader n] [disk-saver n]
nuster nosql on|off [data-size size] [dict-size size] [dir DIR] [dict-cleaner n] [data-cleaner n] [disk-cleaner n] [disk-loader n] [disk-saver n]
default: none
context: global
控制是否開啟cache或者nosql。
會(huì)分配一塊data-size + dict-size的共享內(nèi)存來存儲(chǔ)HTTP頭,數(shù)據(jù),key等等,臨時(shí)數(shù)據(jù)從系統(tǒng)內(nèi)存池分配。 如果沒有足夠內(nèi)存,新的請(qǐng)求不會(huì)被緩存直到有內(nèi)存被釋放。
data-size
和dict-size一起決定內(nèi)存塊的大小。
可以使用m, M, g 和 G. 默認(rèn)是1MB,同時(shí)也是最小值。
dict-size
決定hash table的大小.
可以使用m, M, g 和 G. 默認(rèn)是1MB,同時(shí)也是最小值。
這個(gè)決定hash table buckets的大小,并非key的大小,key存在共享內(nèi)存中。
dict-size(bucket數(shù)) 不等于 key數(shù). 就算key的數(shù)量超過了dict-size,只要整個(gè)共享內(nèi)存有空間,新的key仍然可以被添加。
不過如果key數(shù)超過dict-size(bucket數(shù))性能也許會(huì)下降. dict-size可以設(shè)為大概的最大key數(shù)乘以8。當(dāng)然越大越好。
查看stats API:
dict.nosql.length: 131072
dict.nosql.used: 0
如果dict.nosql.used 比dict.nosql.length大,調(diào)高dict-size比較好。
將來版本會(huì)刪除dict-size, 像第一版本那樣自動(dòng)伸縮
dir
設(shè)置硬盤緩存文件的根目錄,必須設(shè)置以開啟硬盤緩存功能。
dict-cleaner
每次檢查最多 dict-cleaner 個(gè)entry,無效的entry將被刪除(默認(rèn)1000)
data-cleaner
每次檢查最多 data-cleaner 個(gè)entry,無效的data將被刪除(默認(rèn)1000)
disk-cleaner
每次檢查最多 disk-cleaner 個(gè)硬盤緩存文件,無效的文件將被刪除(默認(rèn)100)
disk-loader
啟動(dòng)后每次加載最多 disk-loader 個(gè)硬盤緩存文件的信息到內(nèi)存(默認(rèn)100)
disk-saver
每次檢查最多 disk-saver 個(gè)data,并將需要保存至硬盤的data保存到硬盤(默認(rèn)100)
詳細(xì)請(qǐng)參考Store.
proxy: nuster cache|nosql
syntax:
nuster cache [on|off]
nuster nosql [on|off]
default: on
context: backend
決定是否在這個(gè)backend開啟cache/nosql。 如果這個(gè)section有filter,記得放在最后。
proxy: nuster rule
syntax:
nuster rule name [key KEY] [ttl TTL] [extend EXTEND] [code CODE] [memory on|off] [disk on|off|sync] [etag on|off] [last-modified on|off] [if|unless condition]
default: none
context: backend
定義cache/nosql的生效條件,需要定義至少一個(gè)rule。
nuster cache on
# cache request `/asdf` for 30 seconds
nuster rule asdf ttl 30 if { path /asdf }
# cache if the request path begins with /img/
nuster rule img if { path_beg /img/ }
# cache if the response header `cache` is `yes`
acl resHdrCache res.hdr(cache) yes
nuster rule r1 if resHdrCache
可以定義多個(gè)rule,按定義順序先后匹配。
acl pathA path /a.html
nuster cache on
nuster rule all ttl 3600
nuster rule path01 ttl 60 if pathA
rule path01永遠(yuǎn)不會(huì)被匹配。
name
定義rule的name。
在cache manager API中使用, 不必唯一但是建議不同的rule用不同的name,否則相同name的rule視作一樣。
key KEY
定義cache/nosql的key, 由下列關(guān)鍵字加.組成
- method: http method, GET/POST...
- scheme: http or https
- host: the host in the request
- uri: first slash to end of the url
- path: the URL path of the request
- delimiter: '?' if query exists otherwise empty
- query: the whole query string of the request
- header_NAME: the value of header
NAME - cookie_NAME: the value of cookie
NAME - param_NAME: the value of query
NAME - body: the body of the request
CACHE的默認(rèn)key是 method.scheme.host.uri, NoSQL的默認(rèn)key是 GET.scheme.host.uri.
Example
GET http://www.example.com/q?name=X&type=Y
http header:
GET /q?name=X&type=Y HTTP/1.1
Host: www.example.com
ASDF: Z
Cookie: logged_in=yes; user=nuster;
生成:
- method: GET
- scheme: http
- host: www.example.com
- uri: /q?name=X&type=Y
- path: /q
- delimiter: ?
- query: name=X&type=Y
- header_ASDF: Z
- cookie_user: nuster
- param_type: Y
- body: (empty)
默認(rèn)key產(chǎn)生GET\0http\0www.example.com\0/q?name=X&type=Y\0, 而key method.scheme.host.path.header_ASDF.cookie_user.param_type 則生成 GET\0http\0www.example.com\0/q\0Z\0nuster\0Y\0.
\0是NULL字符
相同key的請(qǐng)求則會(huì)直接返回cache給客戶端。
ttl TTL
設(shè)置緩存生存時(shí)間,過期后緩存會(huì)被刪除。 可以使用 d, h, m and s。默認(rèn)0秒. 如果不希望失效則設(shè)為0
可以通過設(shè)置 extend 關(guān)鍵詞來自動(dòng)延長緩存的ttl。
extend EXTEND
自動(dòng)延長緩存ttl。
格式
extend on|off|n1,n2,n3,n4
默認(rèn): off.
n1,n2,n3,n4: 小于100的正整數(shù), n1 + n2 + n3之和也小于100. 他們定義四個(gè)時(shí)間段:
time: 0 ttl ttl * (1 + n4%)
access: | A1 | A2 | A3 | A4 | |
|---------------------------|---------|---------|---------|---------|
percentage: |<- (100 - n1 - n2 - n3)% ->|<- n1% ->|<- n2% ->|<- n3% ->|<- n4% ->|
滿足下列條件緩存的ttl將被延長:
- A4 > A3 > A2
- 在
ttl和ttl * (1 + n4%)之間有新的請(qǐng)求
on其實(shí)是33,33,33,33
code CODE1,CODE2...
默認(rèn)只緩存200的響應(yīng),如果需要緩存其他的則可以添加,all會(huì)緩存任何狀態(tài)碼。
cache-rule only200
cache-rule 200and404 code 200,404
cache-rule all code all
memory on|off
是否保存數(shù)據(jù)到內(nèi)存,默認(rèn)on。
詳見Store
disk on|off|sync
是否保存數(shù)據(jù)到硬盤,已經(jīng)如何保存,默認(rèn)off
需要設(shè)置memory on 以使用 disk sync
詳見Store
etag on|off
定義是否處理etag條件請(qǐng)求. 如果沒有 ETag 則添加。
默認(rèn)off.
last-modified on|off
定義是否處理last-modified條件請(qǐng)求. 如果沒有 Last-Modified 則添加.
默認(rèn)off.
if|unless condition
定義ACL條件
ACL分別在請(qǐng)求階段和響應(yīng)階段執(zhí)行。
當(dāng)下述條件滿足時(shí),會(huì)進(jìn)行緩存:
- 在請(qǐng)求階段ACL為真
- 請(qǐng)求階段ACL為假,但是響應(yīng)階段ACL為真
當(dāng)使用否定的ACL或者某些樣本獲取方法時(shí),需要特別注意
比如
-
緩存以
/img/開頭的請(qǐng)求nuster rule img if { path_beg /img/ }
請(qǐng)求階段要么為真要么為假,因?yàn)樵陧憫?yīng)階段無法獲取path所以永遠(yuǎn)為假。
-
緩存響應(yīng)的http頭部
Content-Type為image/jpegnuster rule jpeg if { res.hdr(Content-Type) image/jpeg }
因?yàn)樵谡?qǐng)求階段無法獲取res.hdr所以永遠(yuǎn)為假,在響應(yīng)階段要么為真要么為假。
- 以
/img/開頭,并且響應(yīng)頭Content-Type為image/jpeg時(shí)緩存
如果定義為下面的規(guī)則,則不會(huì)成功:
nuster rule img if { path_beg /img/ } { res.hdr(Content-Type) image/jpeg }
因?yàn)樵陧憫?yīng)階段無法獲取path所以永遠(yuǎn)為假,而在請(qǐng)求階段無法獲取res.hdr所以永遠(yuǎn)為假,那么這個(gè)ACL就永遠(yuǎn)無法匹配。
需要如下來定義:
http-request set-var(txn.pathImg) path
acl pathImg var(txn.pathImg) -m beg /img/
acl resHdrCT res.hdr(Content-Type) image/jpeg
nuster rule r3 if pathImg resHdrCT
或者nuster.path(v5):
nuster rule r3 if { nuster.path -m beg /img } { res.hdr(Content-Type) image/jpeg }
- 另一個(gè)例子,緩存所有不以
/api/開頭的請(qǐng)求
下面不正確:
acl NoCache path_beg /api/
nuster rule r3 if !NoCache
因?yàn)殡m然在響應(yīng)階段path并不存在,所以NoCache永遠(yuǎn)為假,而 !NoCache 為真,所有的請(qǐng)求都會(huì)被緩存。
需要改成:
http-request set-var(txn.path) path
acl NoCache var(txn.path) -m beg /api/
nuster rule r1 if !NoCache
新sample fetch詳見Sample fetches
詳見HAProxy configuration的7. Using ACLs and fetching samples
Cache
nuster也可以用作類似Varnish或者Nginx那樣的HTTP緩存服務(wù)器,來緩存動(dòng)態(tài)或者靜態(tài)的HTTP資源。 出了HAProxy的SSL, HTTP, HTTP2, 重寫重定向,增刪改Header等等,還提供了下面的功能。
global
nuster cache on data-size 200m
frontend fe
bind *:8080
default_backend be
backend be
nuster cache on
nuster rule r1 if { path /a1 }
nuster rule r2 key method.scheme.host.path.delimiter.query.cookie_userId if { path /a2 }
nuster rule r3 ttl 10 if { path /a3 }
nuster rule r4 disk only if { path /a4 }
server s1 127.0.0.1:8081
nuster會(huì)依次檢查rule, 先生成key然后查找,如果找到則返回緩存,否則就測試ACL, 如果ACL通過則緩存響應(yīng)。
NoSQL
nuster也可以用作RESTful NoSQL緩存服務(wù)器, 用HTTP POST/GET/DELETE 來 添加/取得/刪除 Key/Value.
基本操作
Set
curl -v -X POST -d value1 http://127.0.0.1:8080/key1
curl -v -X POST --data-binary @icon.jpg http://127.0.0.1:8080/imgs/icon.jpg
Get
curl -v http://127.0.0.1:8080/key1
Delete
curl -v -X DELETE http://127.0.0.1:8080/key1
Response
Check status code.
- 200 OK
- POST/GET: 成功
- DELETE: 總是
- 400 Bad request
- 空值
- 不正確的acl, rules, etc
- 404 Not Found
- POST: rule tests失敗
- GET: not found
- 405 Method Not Allowed
- 其他的methods
- 500 Internal Server Error
- 發(fā)生未知錯(cuò)誤
- 507 Insufficient Storage
- 超過data-size
分用戶的data
通過在key里加入header, cookie等等,可以將不同的用戶數(shù)據(jù)存到相同的路勁。
nuster rule r1 key method.scheme.host.uri.header_userId if { path /mypoint }
nuster rule r2 key method.scheme.host.uri.cookie_sessionId if { path /mydata }
Set
curl -v -X POST -d "333" -H "userId: 1000" http://127.0.0.1:8080/mypoint
curl -v -X POST -d "555" -H "userId: 1001" http://127.0.0.1:8080/mypoint
curl -v -X POST -d "userA data" --cookie "sessionId=ijsf023xe" http://127.0.0.1:8080/mydata
curl -v -X POST -d "userB data" --cookie "sessionId=rosre329x" http://127.0.0.1:8080/mydata
Get
curl -v http://127.0.0.1:8080/mypoint
< 404 Not Found
curl -v -H "userId: 1000" http://127.0.0.1:8080/mypoint
< 200 OK
333
curl -v --cookie "sessionId=ijsf023xe" http://127.0.0.1:8080/mydata
< 200 OK
userA data
客戶端
支持任何支持HTTP的客戶端,庫: curl, postman, python requests, go net/http, etc.
管理
可以通過uri定義一個(gè)endpoint并發(fā)送HTTP請(qǐng)求來進(jìn)行管理。
定義并且開啟
nuster manager on uri /internal/nuster purge-method PURGEX
方法一覽
| METHOD | Endpoint | description |
|---|---|---|
| GET | /internal/nuster | 獲得stats |
| POST | /internal/nuster | 開啟關(guān)閉rule, 更新ttl |
| DELETE | /internal/nuster | 高級(jí)Purge |
| PURGEX | /any/real/path | 基礎(chǔ)Purge |
統(tǒng)計(jì)
可以通過GET uri定義的endpoint來獲取統(tǒng)計(jì)信息。
Usage
curl http://127.0.0.1/nuster
Output
**NUSTER**
nuster.cache: on
nuster.nosql: on
nuster.manager: on
**MANAGER**
manager.uri: /nuster
manager.purge_method: PURGE
**DICT**
dict.cache.size: 1048576
dict.cache.length: 131072
dict.cache.used: 0
dict.cache.cleanup_idx: 0
dict.cache.sync_idx: 0
dict.nosql.size: 1048576
dict.nosql.length: 131072
dict.nosql.used: 0
dict.nosql.cleanup_idx: 0
dict.nosql.sync_idx: 0
**STORE MEMORY**
store.memory.cache.size: 2098200576
store.memory.cache.used: 1048960
store.memory.cache.count: 0
store.memory.nosql.size: 11534336
store.memory.nosql.used: 1048960
store.memory.nosql.count: 0
**STORE DISK**
store.disk.cache.dir: /tmp/nuster/cache
store.disk.cache.loaded: yes
store.disk.nosql.dir: /tmp/nuster/nosql
store.disk.nosql.loaded: yes
**STATS**
stats.cache.total: 0
stats.cache.hit: 0
stats.cache.fetch: 0
stats.cache.abort: 0
stats.cache.bytes: 0
stats.nosql.total: 0
stats.nosql.get: 0
stats.nosql.post: 0
stats.nosql.delete: 0
**PROXY cache app1**
app1.rule.rule1: state=on memory=on disk=off ttl=10
app1.rule.rule2: state=on memory=on disk=on ttl=10
app1.rule.rule3: state=on memory=on disk=sync ttl=10
app1.rule.rule4: state=on memory=off disk=on ttl=10
app1.rule.rule5: state=on memory=off disk=off ttl=10
**PROXY nosql app2**
app2.rule.ruleA: state=on memory=on disk=off ttl=10
app2.rule.ruleB: state=on memory=on disk=on ttl=10
app2.rule.ruleC: state=on memory=on disk=sync ttl=10
app2.rule.ruleD: state=on memory=off disk=on ttl=10
app2.rule.ruleE: state=on memory=off disk=off ttl=10
開啟關(guān)閉rule
rule可以通過manager uri動(dòng)態(tài)開啟關(guān)閉,關(guān)閉的rule不會(huì)再進(jìn)行匹配。
headers
| header | value | description |
|---|---|---|
| state | enable | enable rule |
| disable | disable rule | |
| name | rule NAME | the rule to be enabled/disabled |
| proxy NAME | all rules of proxy NAME | |
| * | all rules |
相同name的rule都會(huì)被開啟關(guān)閉。
Examples
-
關(guān)閉rule r1
curl -X POST -H "name: r1" -H "state: disable" http://127.0.0.1/nuster -
關(guān)閉backend app1b的所有rule
curl -X POST -H "name: app1b" -H "state: disable" http://127.0.0.1/nuster -
開啟所有的rule
curl -X POST -H "name: *" -H "state: enable" http://127.0.0.1/nuster
更新生存時(shí)間
更改TTL,只會(huì)影響后續(xù)的新緩存,不會(huì)影響已經(jīng)存在的緩存。
headers
| header | value | description |
|---|---|---|
| ttl | new TTL | see ttl in nuster rule |
| name | rule NAME | the rule to be changed |
| proxy NAME | all rules of proxy NAME | |
| * | all rules |
Examples
curl -X POST -H "name: r1" -H "ttl: 0" http://127.0.0.1/nuster
curl -X POST -H "name: r2" -H "ttl: 2h" http://127.0.0.1/nuster
同時(shí)設(shè)置state和ttl
同時(shí)設(shè)置state和ttl
curl -X POST -H "name: r1" -H "ttl: 0" -H "state: enabled" http://127.0.0.1/nuster
清除
有兩種清除模式:
- 基礎(chǔ)Purge: 發(fā)送
purge-method MYPURGE定義的方法到想要?jiǎng)h除的Path - 高級(jí)Purge: 發(fā)送DELETE 到manager uri
基礎(chǔ)Purge: 刪除一個(gè)特定URL
curl -XPURGE http://127.0.0.1/imgs/test.jpg
根據(jù)rule生成key并刪除那個(gè)key。只對(duì)GET請(qǐng)求生成的緩存有效。
默認(rèn)key 包含Host, 如果緩存時(shí)用了http://example.com/test 而在localhost刪除是需要Host header:
curl -XPURGE -H "Host: example.com" http://127.0.0.1/test
對(duì)cache和nosql都有效,nosql模式相當(dāng)于 DELETE。
高級(jí)Purge: 通過name刪除
可以通過帶上name header來 PURGE
headers
| header | value | description |
|---|---|---|
| name | nuster rule NAME | caches of rule ${NAME} will be purged |
| proxy NAME | caches of proxy ${NAME} | |
| * | all caches |
Examples
# 刪除所有緩存
curl -X DELETE -H "name: *" http://127.0.0.1/nuster
# 刪除backend applb的所有緩存
curl -X DELETE -H "name: app1b" http://127.0.0.1/nuster
# 刪除所有rule r1生成的緩存
curl -X DELETE -H "name: r1" http://127.0.0.1/nuster
高級(jí)Purge: 通過host刪除
通過帶上nuster-hostheader來刪除所有屬于這個(gè)host的緩存。
headers
| header | value | description |
|---|---|---|
| host | HOST | the ${HOST} |
| nuster-host | HOST | nuster-host存在則使用nuster-host |
| mode | cache, nosql | purge cache or nosql data |
Examples
curl -X DELETE -H "nuster-host: 127.0.0.1:8080" http://127.0.0.1/nuster
高級(jí)Purge: 通過path刪除
默認(rèn)情況下,query部分也包含在key中,所以相同的path不同的query會(huì)產(chǎn)生不同的緩存。
比如nuster rule imgs if { path_beg /imgs/ }, 然后請(qǐng)求
curl http://127.0.0.1/imgs/test.jpg?w=120&h=120
curl http://127.0.0.1/imgs/test.jpg?w=180&h=180
會(huì)生成兩個(gè)緩存,因?yàn)閝uery不一樣。
如果要?jiǎng)h除這些緩存,可以
如果知道所有的query,那么可以一個(gè)一個(gè)刪除
curl -XPURGE http://127.0.0.1/imgs/test.jpg?w=120&h=120
curl -XPURGE http://127.0.0.1/imgs/test.jpg?w=180&h=180
大多數(shù)情況下不知道所有的query
如果query部分不重要,則可以從key里面刪除query
定義nuster rule imgs key method.scheme.host.path if { path_beg /imgs }, 這樣的話只會(huì)生成一個(gè)緩存,那么就可以不用query刪除緩存
curl -XPURGE http://127.0.0.1/imgs/test.jpg
大多數(shù)情況需要query
通過rule name刪除
curl -X PURGE -H "name: imgs" http://127.0.0.1/nuster/cache
但是如果rule被定義成了 nuster rule static if { path_beg /imgs/ /css/ },則無法只刪除imgs
因此,可以通過path刪除
headers
| header | value | description |
|---|---|---|
| path | PATH | caches with ${PATH} will be purged |
| host | HOST | and host is ${HOST} |
| nuster-host | HOST | nuster-host has higher precedence over host |
| mode | cache, nosql | purge cache or nosql data |
Examples
# 刪除所有path是/imgs/test.jpg的緩存
curl -X DELETE -H "path: /imgs/test.jpg" http://127.0.0.1/nuster
# 刪除所有path是/imgs/test.jpg 并且host是127.0.0.1:8080的緩存
curl -X DELETE -H "path: /imgs/test.jpg" -H "nuster-host: 127.0.0.1:8080" http://127.0.0.1/nuster
高級(jí)Purge: 通過正則刪除
也可以通過正則刪除,所有匹配正則的緩存將被刪除。
headers
| header | value | description |
|---|---|---|
| regex | REGEX | caches which path match with ${REGEX} will be purged |
| host | HOST | and host is ${HOST} |
| nuster-host | HOST | nuster-host has higher precedence over host |
| mode | cache, nosql | purge cache or nosql data |
Examples
# 刪除所有 /imgs 開頭 .jpg結(jié)尾的緩存
curl -X DELETE -H "regex: ^/imgs/.*\.jpg$" http://127.0.0.1/nuster
#delete all caches which path starts with /imgs and ends with .jpg and with host of 127.0.0.1:8080
curl -X DELETE -H "regex: ^/imgs/.*\.jpg$" -H "127.0.0.1:8080" http://127.0.0.1/nuster
PURGE 注意事項(xiàng)
-
開啟訪問控制
-
如果有多個(gè)header,按照
name,path & host,path,regex & host,regex,host的順序處理curl -X DELETE -H "name: rule1" -H "path: /imgs/a.jpg": purge by name -
如果有重復(fù)的header,處理第一個(gè)
curl -X DELETE -H "name: rule1" -H "name: rule2": purge byrule1 -
regex不是 glob比如 /imgs下的.jpg文件是
^/imgs/.*\.jpg$而不是/imgs/*.jpg -
通過rule name或proxy name刪除緩存時(shí),需要注意這兩種方法只在當(dāng)前進(jìn)程有效。如果重啟了進(jìn)程則無法通過這兩種方法刪除緩存文件,因?yàn)閞ule name信息和proxy name信息并沒有保存在緩存文件中。
-
只有disk load結(jié)束后才能通過host or path or regex 來刪除緩存文件。是否已經(jīng)load結(jié)束可以查看stats URL。
Store
Nuster(cache和nosql) 支持多種后端存儲(chǔ). 目前支持memory和disk。計(jì)劃添加其他后段。
Memory
數(shù)據(jù)被存在一個(gè)大小由data-size定義的內(nèi)存區(qū)域。重啟后數(shù)據(jù)會(huì)消失。
Disk
數(shù)據(jù)被存到硬盤由dir定義的目錄下。重啟后數(shù)據(jù)不會(huì)消失。
有三種模式:
- off: 默認(rèn),不保存到硬盤
- on: 保存到硬盤
- sync: 需要設(shè)置
memory on。先保存至內(nèi)存然后由master進(jìn)程在一定時(shí)間后同步到硬盤,每次同步dict-saver個(gè)緩存。
Sample fetches
Nuster 加入了一些新的sample fetches
[cache] nuster.cache.hit: boolean
表示是否是HIT緩存,可以像如下使用
http-response set-header x-cache hit if { nuster.cache.hit }
[cache|nosql] nuster.host: string
類似HAProxy的 req.hdr(Host),但是請(qǐng)求和響應(yīng)中都可使用
[cache|nosql] nuster.uri: string
等同于HAProxy的capture.req.uri.
[cache|nosql] nuster.path: string
類似HAProxy的 path,但是請(qǐng)求和響應(yīng)中都可使用
[cache|nosql] nuster.query: string
類似HAProxy的 query,但是請(qǐng)求和響應(yīng)中都可使用
FAQ
無法啟動(dòng),報(bào)錯(cuò): not in master-worker mode
在global 添加 master-worker 或者啟動(dòng)時(shí)使用-W參數(shù)。
如何調(diào)試?
在global添加debug, 或者帶-d啟動(dòng)nuster
nuster相關(guān)的調(diào)試信息以[nuster開頭
如何緩存POST請(qǐng)求?
添加option http-buffer-request
如果自定義了key的話需要使用body關(guān)鍵字
請(qǐng)求body可能不完整,詳見HAProxy configuration 的 option http-buffer-request小節(jié)
另外可以為post請(qǐng)求單獨(dú)設(shè)置一個(gè)后端
如何做訪問控制?
類似
acl network_allowed src 127.0.0.1
acl purge_method method PURGE
http-request deny if purge_method !network_allowed
如何開啟HTTP2?
bind :443 ssl crt pub.pem alpn h2,http/1.1
Example
global
nuster cache on data-size 100m
nuster nosql on data-size 100m
master-worker # v3
# daemon
# debug
defaults
retries 3
option redispatch
timeout client 30s
timeout connect 30s
timeout server 30s
frontend web1
bind *:8080
mode http
acl pathPost path /search
use_backend app1a if pathPost
default_backend app1b
backend app1a
balance roundrobin
# mode must be http
mode http
# http-buffer-request must be enabled to cache post request
option http-buffer-request
acl pathPost path /search
# enable cache for this proxy
nuster cache
# cache /search for 120 seconds. Only works when POST/PUT
nuster rule rpost key method.scheme.host.uri.body ttl 120 if pathPost
server s1 10.0.0.10:8080
backend app1b
balance roundrobin
mode http
nuster cache on
# cache /a.jpg, not expire
acl pathA path /a.jpg
nuster rule r1 ttl 0 if pathA
# cache /mypage, key contains cookie[userId], so it will be cached per user
acl pathB path /mypage
nuster rule r2 key method.scheme.host.path.delimiter.query.cookie_userId ttl 60 if pathB
# cache /a.html if response's header[cache] is yes
http-request set-var(txn.pathC) path
acl pathC var(txn.pathC) -m str /a.html
acl resHdrCache1 res.hdr(cache) yes
nuster rule r3 if pathC resHdrCache1
# cache /heavy for 100 seconds if be_conn greater than 10
acl heavypage path /heavy
acl tooFast be_conn ge 100
nuster rule heavy ttl 100 if heavypage tooFast
# cache all if response's header[asdf] is fdsa
acl resHdrCache2 res.hdr(asdf) fdsa
nuster rule resCache ttl 0 if resHdrCache1
server s1 10.0.0.10:8080
frontend web2
bind *:8081
mode http
default_backend app2
backend app2
balance roundrobin
mode http
# disable cache on this proxy
nuster cache off
nuster rule all
server s2 10.0.0.11:8080
frontend nosql_fe
bind *:9090
default_backend nosql_be
backend nosql_be
nuster nosql on
nuster rule r1 ttl 3600
