基于HAProxy的高性能HTTP缓存服务器和RESTful NoSQL缓存服务器。html
中文版更新可能不及时,最新版请参照英文版http://www.javashuo.com/tag/readme.md前端
NuSTER是一个基于HAProxy的高性能HTTP缓存服务器和RESTful NoSQL缓存服务器,彻底兼容HAProxy,而且利用HAProxy的ACL功能来提供很是细致的缓存规则。python
NuSTER能够做为HTTP/TCP负载均衡器使用。mysql
NuSTER也能够用做相似Varnish或者Nginx那样的HTTP缓存服务器,来缓存动态或者静态的HTTP资源。linux
NuSTER也能够用做RESTful NoSQL缓存服务器, 用HTTP POST/GET/DELETE
来 添加/取得/删除 Key/Value.nginx
能够像Memcached或者Redis那样放在应用和数据库之间做为内部KV缓存使用,也能够放在用户和应用之间做为面向用户的NoSQL使用。 支持header, cookie等等,因此能够将不一样的用户数据存到相同的路劲。git
很是快, 单进程模式下是nginx的3倍,多进程下nginx的2倍,varnish的3倍。github
详见benchmarkweb
生产环境的话从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
。
nuster cache on
or nuster nosql on
,不然cache和nosql没法使用frontend
, backend
的默认参数frontend
or backend
section从新定义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
关闭rule r1
curl -X POST -H "name: r1" -H "state: disable" http://127.0.0.1/nuster/cache
关闭backend app1b的全部rule
curl -X POST -H "name: app1b" -H "state: disable" http://127.0.0.1/nuster/cache
开启全部的rule
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 注意事项
开启访问控制
若是有多个header,按照name
, path & host
, path
, regex & host
, regex
, host
的顺序处理
curl -XPURGE -H "name: rule1" -H "path: /imgs/a.jpg"
: purge by name
若是有重复的header,处理第一个
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.
经过在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.