基於HAProxy的高性能HTTP緩存服務器和RESTful NoSQL緩存服務器。html
中文版更新可能不及時,最新版請參照英文版 README.md
NuSTER是一個基於HAProxy的高性能HTTP緩存服務器和RESTful NoSQL緩存服務器,徹底兼容HAProxy,而且利用HAProxy的ACL功能來提供很是細緻的緩存規則。mysql
NuSTER能夠做爲HTTP/TCP負載均衡器使用。linux
NuSTER也能夠用做相似Varnish或者Nginx那樣的HTTP緩存服務器,來緩存動態或者靜態的HTTP資源。nginx
強大的動態緩存功能git
NuSTER也能夠用做RESTful NoSQL緩存服務器, 用HTTP POST/GET/DELETE
來 添加/取得/刪除 Key/Value.github
能夠像Memcached或者Redis那樣放在應用和數據庫之間做爲內部KV緩存使用,也能夠放在用戶和應用之間做爲面向用戶的NoSQL使用。
支持header, cookie等等,因此能夠將不一樣的用戶數據存到相同的路勁。web
很是快, 單進程模式下是nginx的3倍,多進程下nginx的2倍,varnish的3倍。
生產環境的話從Download下載最新穩定版, 其餘狀況能夠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 README。
準備一個配置文件: nuster.cfg
global nuster cache on data-size 100m uri /_nuster nuster nosql on data-size 200m 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監聽8080端口,接受HTTP請求。/_kv/
開頭的請求分配到backend be2
, 能夠發送HTTP POST/GET/DELETE
到/_kv/any_key
來 添加/取得/刪除 Key/Value.
其餘的請求都被分配到backend be1
, 而且會被轉發到服務器s1
or s2
. 其中/img/*
請求會被緩存1天,而/api/some/api
會被緩存30秒。
/usr/local/nuster/sbin/nuster -f nuster.cfg
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指令。
配置文件裏有四個基本的section
s: global
, defaults
, frontend
and backend
。
global
nuster cache on
or nuster nosql on
,不然cache和nosql沒法使用defaults
frontend
, backend
的默認參數frontend
or backend
section從新定義frontend
bankend
nuster cache on
or nuster nosql on
, 不然該backend沒有nosql或者nosql功能nuster rule
能夠定義多個frontend
or backend
. 若是定義了nuster cache|nosql off
或者沒有nuster cache|nosql on|off
, nuster就是一個HAProxy。
具體參考/doc
下的HAProxy文檔, 或者在線HAProxy文檔
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
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
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
global nuster nosql on data-size 200m frontend fe bind *:8080 default_backend be backend be nuster nosql on nuster rule r1 ttl 3600
syntax:
nuster cache on|off [data-size size] [dict-size size] [purge-method method] [uri uri]
nuster nosql on|off [data-size size] [dict-size size]
default: none
context: global
控制是否開啓cache或者nosql。
會分配一塊data-size + dict-size
的共享內存來存儲HTTP頭,數據,key等等,臨時數據從系統內存池分配。
若是沒有足夠內存,新的請求不會被緩存直到有內存被釋放。
和dict-size
一塊兒決定內存塊的大小。
可使用m
, M
, g
和 G
. 默認是1MB,同時也是最小值。
決定hash table的大小.
可使用m
, M
, g
和 G
. 默認是1MB,同時也是最小值。
這個決定hash table buckets的大小,並不是key的大小,key存在共享內存中。
dict-size(bucket數) 不等於 key數. 就算key的數量超過了dict-size,只要整個共享內存有空間,新的key仍然能夠被添加。
不過若是key數超過dict-size(bucket數)性能也許會降低. dict-size能夠設爲大概的最大key數乘以8。
未來版本會刪除dict-size, 像初版本那樣自動伸縮
自定義PURGE用的HTTP method,最大14個字符,默認是 PURGE
.
定義並開啓cache manager/stats API
nuster cache on uri /_my/_unique/_/_cache/_uri
cache manager/stats默認是關閉的. 若是開啓了,主義開啓訪問控制(see FAQ).
syntax:
nuster cache [on|off]
nuster nosql [on|off]
default: on
context: backend, listen
決定是否在這個backend開啓cache/nosql。
若是這個section有filter,記得放在最後。
syntax: nuster rule name [key KEY] [ttl TTL] [code CODE] [if|unless condition]
default: none
context: backend, listen
定義cache/nosql的生效條件,須要定義至少一個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
能夠定義多個rule,按定義順序前後匹配。
acl pathA path /a.html nuster cache on nuster rule all ttl 3600 nuster rule path01 ttl 60 if pathA
rule path01
永遠不會被匹配。
定義rule的name。
在cache manager API中使用, 沒必要惟一可是建議不一樣的rule用不一樣的name,不然相同name的rule視做同樣。
定義cache/nosql的key, 由下列關鍵字加.
組成
NAME
NAME
NAME
CACHE的默認key是 method.scheme.host.uri
, NoSQL的默認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;
生成:
默認key產生GET.http.www.example.com./q?name=X&type=Y.
, 而key method.scheme.host.path.header_ASDF.cookie_user.param_type
則生成 GET.http.www.example.com./q.Z.nuster.Y.
.
相同key的請求則會直接返回cache給客戶端。
設置緩存生存時間,過時後緩存會被刪除。 可使用 d
, h
, m
and s
。默認3600
秒.
若是不但願失效則設爲0
默認只緩存200的響應,若是須要緩存其餘的則能夠添加,all
會緩存任何狀態碼。
cache-rule only200 cache-rule 200and404 code 200,404 cache-rule all code all
定義ACL條件
詳見HAProxy configuration的7. Using ACLs and fetching samples
NuSTER也能夠用做相似Varnish或者Nginx那樣的HTTP緩存服務器,來緩存動態或者靜態的HTTP資源。
出了HAProxy的SSL, HTTP, HTTP2, 重寫重定向,增刪改Header等等,還提供了下面的功能。
緩存能夠經過uri
定義一個endpoint併發送HTTP請求來進行管理。
定義而且開啓
nuster cache on uri /nuster/cache
基本用法
curl -X POST -H "X: Y" http://127.0.0.1/nuster/cache
記得進行訪問控制
rule能夠經過manager uri動態開啓關閉,關閉的rule不會再進行匹配。
headers
header | value | description |
---|---|---|
state | enable | enable rule |
disable | disable rule | |
name | rule NAME | the rule to be enabled/disabled |
proxy NAME | all rules belong to proxy NAME | |
* | all rules |
相同name的rule都會被開啓關閉。
Examples
curl -X POST -H "name: r1" -H "state: disable" http://127.0.0.1/nuster/cache
curl -X POST -H "name: app1b" -H "state: disable" http://127.0.0.1/nuster/cache
curl -X POST -H "name: *" -H "state: enable" http://127.0.0.1/nuster/cache
更改緩存TTL,只會影響後續的新緩存,不會影響已經存在的緩存。
headers
header | value | description |
---|---|---|
ttl | new TTL | see ttl in nuster rule |
name | rule NAME | the rule to be changed |
proxy NAME | all rules belong to proxy NAME | |
* | all rules |
Examples
curl -X POST -H "name: r1" -H "ttl: 0" http://127.0.0.1/nuster/cache curl -X POST -H "name: r2" -H "ttl: 2h" http://127.0.0.1/nuster/cache
同時設置state和ttl
curl -X POST -H "name: r1" -H "ttl: 0" -H "state: enabled" http://127.0.0.1/nuster/cache
There are several ways to purge cache by making HTTP PURGE
requests to the manager uri defined by uri
.
You can define customized http method using purge-method MYPURGE
other than the default PURGE
in case you need to forward PURGE
to backend servers.
curl -XPURGE https://127.0.0.1/imgs/test.jpg
生成key GET.scheme.host.uri
, 並刪除那個key。
默認key 包含Host
, 若是緩存時用了http://example.com/test
而在localhost刪除是須要Host
header:
curl -XPURGE -H "Host: example.com" http://127.0.0.1/test
能夠經過帶上name
header來 PURGE
headers
header | value | description |
---|---|---|
name | nuster rule NAME | caches belong to rule ${NAME} will be purged |
proxy NAME | caches belong to proxy ${NAME} | |
* | all caches |
Examples
# 刪除全部緩存 curl -X PURGE -H "name: *" http://127.0.0.1/nuster/cache # 刪除backend applb的全部緩存 curl -X PURGE -H "name: app1b" http://127.0.0.1/nuster/cache # 刪除全部rule r1生成的緩存 curl -X PURGE -H "name: r1" http://127.0.0.1/nuster/cache
經過帶上x-host
header來刪除全部屬於這個host的緩存。
headers
header | value | description |
---|---|---|
x-host | HOST | the ${HOST} |
Examples
curl -X PURGE -H "x-host: 127.0.0.1:8080" http://127.0.0.1/nuster/cache
默認狀況下,query部分也包含在key中,因此相同的path不一樣的query會產生不一樣的緩存。
好比nuster rule imgs if { path_beg /imgs/ }
, 而後請求
curl https://127.0.0.1/imgs/test.jpg?w=120&h=120 curl https://127.0.0.1/imgs/test.jpg?w=180&h=180
會生成兩個緩存,由於query不同。
若是要刪除這些緩存,能夠
若是知道全部的query,那麼能夠一個一個刪除
curl -XPURGE https://127.0.0.1/imgs/test.jpg?w=120&h=120 curl -XPURGE https://127.0.0.1/imgs/test.jpg?w=180&h=180
大多數狀況下不知道全部的query
若是query部分不重要,則能夠從key裏面刪除query
定義nuster rule imgs key method.scheme.host.path if { path_beg /imgs }
, 這樣的話只會生成一個緩存,那麼就能夠不用query刪除緩存
curl -XPURGE https://127.0.0.1/imgs/test.jpg
大多數狀況須要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 |
x-host | HOST | and host is ${HOST} |
Examples
# 刪除全部path是/imgs/test.jpg的緩存 curl -X PURGE -H "path: /imgs/test.jpg" http://127.0.0.1/nuster/cache # 刪除全部path是/imgs/test.jpg 而且host是127.0.0.1:8080的緩存 curl -X PURGE -H "path: /imgs/test.jpg" -H "x-host: 127.0.0.1:8080" http://127.0.0.1/nuster/cache
也能夠經過正則刪除,全部匹配正則的緩存將被刪除。
headers
header | value | description |
---|---|---|
regex | REGEX | caches which path match with ${REGEX} will be purged |
x-host | HOST | and host is ${HOST} |
Examples
# 刪除全部 /imgs 開頭 .jpg結尾的緩存 curl -X PURGE -H "regex: ^/imgs/.*\.jpg$" http://127.0.0.1/nuster/cache #delete all caches which path starts with /imgs and ends with .jpg and belongs to 127.0.0.1:8080 curl -X PURGE -H "regex: ^/imgs/.*\.jpg$" -H "127.0.0.1:8080" http://127.0.0.1/nuster/cache
PURGE 注意事項
name
, path & host
, path
, regex & host
, regex
, host
的順序處理curl -XPURGE -H "name: rule1" -H "path: /imgs/a.jpg"
: purge by name
curl -XPURGE -H "name: rule1" -H "name: rule2"
: purge by rule1
regex
不是 glob好比 /imgs下的.jpg文件是^/imgs/.*\.jpg$
而不是 /imgs/*.jpg
能夠經過GET uri
定義的endpoint來獲取緩存統計信息。
nuster cache on uri /nuster/cache
curl http://127.0.0.1/nuster/cache
NuSTER也能夠用做RESTful NoSQL緩存服務器, 用HTTP POST/GET/DELETE
來 添加/取得/刪除 Key/Value.
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
curl -v http://127.0.0.1:8080/key1
curl -v -X DELETE http://127.0.0.1:8080/key1
Check status code.
200 OK
400 Bad request
404 Not Found
405 Method Not Allowed
500 Internal Server Error
507 Insufficient Storage
經過在key里加入header, cookie等等,能夠將不一樣的用戶數據存到相同的路勁。
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 }
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
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.
在global
添加debug
, 或者帶-d
啓動haproxy
緩存相關的調試信息以[CACHE]
開頭
添加option http-buffer-request
若是自定義了key的話須要使用body
關鍵字
請求body可能不完整,詳見HAProxy configuration 的 option http-buffer-request小節
另外能夠爲post請求單獨設置一個後端
相似
acl network_allowed src 127.0.0.1 acl purge_method method PURGE http-request deny if purge_method !network_allowed
bind :443 ssl crt pub.pem alpn h2,http/1.1
global nuster cache on data-size 100m nuster nosql on data-size 100m #daemon ## to debug cache #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 listen web3 bind *:8082 mode http nuster cache nuster rule everything server s3 10.0.0.12:8080 frontend nosql_fe bind *:9090 default_backend nosql_be backend nosql_be nuster nosql on nuster rule r1 ttl 3600
.md
extension belong to NuSTER, otherwise HAProxyCopyright (C) 2017-2018, Jiang Wenyuan, < koubunen AT gmail DOT com >
All rights reserved.
Licensed under GPL, the same as HAProxy
HAProxy and other sources license notices: see relevant individual files.