nuster: 基于 HAProxy 的高性能 HTTP 缓存服务器和 RESTful NoSQL 缓存服务

nuster#

Wiki | English | 中文 | 日本語

基于 HAProxy 的高性能 HTTP 缓存服务器和 RESTful NoSQL 缓存服务器。

中文版更新可能不及时,最新版请参照英文版 README.md

目录#

介绍#

nuster 是一个基于 HAProxy 的高性能 HTTP 缓存服务器和 RESTful NoSQL 缓存服务器,完全兼容 HAProxy,并且利用 HAProxy 的 ACL 功能来提供非常细致的缓存规则。

特性#

HTTP/TCP 负载均衡器#

nuster 可以作为 HTTP/TCP 负载均衡器使用。

  • 继承了 HAProxy 的所有特性,完全兼容 HAProxy
  • 负载均衡
  • 前端后端 HTTPS
  • HTTP 压缩
  • HTTP 重写重定向
  • HTTP 信息增删改
  • HTTP2
  • 监控
  • 粘性
  • 访问控制
  • 内容切换

HTTP 缓存服务器#

nuster 也可以用作类似 Varnish 或者 Nginx 那样的 HTTP 缓存服务器,来缓存动态或者静态的 HTTP 资源。

  • HAProxy 的所有特性 (HTTPS, HTTP/2, ACL, etc)
  • 非常快
  • 强大的动态缓存功能
    • 基于 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
  • 缓存管理
  • 缓存清除
  • 缓存统计信息
  • 缓存生存时间
  • 持久化

RESTful NoSQL 缓存服务器#

nuster 也可以用作 RESTful NoSQL 缓存服务器,用 HTTP POST/GET/DELETE 来 添加 / 取得 / 删除 Key/Value.

可以像 Memcached 或者 Redis 那样放在应用和数据库之间作为内部 KV 缓存使用,也可以放在用户和应用之间作为面向用户的 NoSQL 使用。
支持 header, cookie 等等,所以可以将不同的用户数据存到相同的路劲。

  • HAProxy 的所有特性 (HTTPS, HTTP/2, ACL, etc)
  • 有条件的缓存
  • 内部 KV 缓存
  • 面向用户缓存
  • 支持任何类型的数据
  • 支持所有编程语言,不需要特定的库,只需 HTTP 支持
  • 持久化

性能#

非常快,单进程模式下是 nginx 的 3 倍,多进程下 nginx 的 2 倍,varnish 的 3 倍。

详见 benchmark

入门指南#

下载#

生产环境的话从 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
    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 监听 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#

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 指令。

基本#

配置文件里有四个基本的 sections: 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。

无法在 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 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] [purge-method method] [uri uri]

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。

会分配一块 data-size + dict-size 的共享内存来存储 HTTP 头,数据,key 等等,临时数据从系统内存池分配。
如果没有足够内存,新的请求不会被缓存直到有内存被释放。

data-size#

dict-size 一起决定内存块的大小。

可以使用 m, M, gG. 默认是 1MB,同时也是最小值。

dict-size#

决定 hash table 的大小.

可以使用 m, M, gG. 默认是 1MB,同时也是最小值。

这个决定 hash table buckets 的大小,并非 key 的大小,key 存在共享内存中。

dict-size (bucket 数) 不等于 key 数. 就算 key 的数量超过了 dict-size,只要整个共享内存有空间,新的 key 仍然可以被添加。

不过如果 key 数超过 dict-size (bucket 数) 性能也许会下降. dict-size 可以设为大概的最大 key 数乘以 8。

将来版本会删除 dict-size, 像第一版本那样自动伸缩

dir#

设置硬盘缓存文件的根目录,必须设置以开启硬盘缓存功能。

dict-cleaner#

每次检查 dict-cleaner 个 entry,无效的 entry 将被删除(默认 100)

data-cleaner#

每次检查 data-cleaner 个 entry,无效的 data 将被删除(默认 100)

disk-cleaner#

每次检查 disk-cleaner 个硬盘缓存文件,无效的文件将被删除(默认 100)

disk-loader#

启动后每次加载 disk-loader 个硬盘缓存文件的信息到内存(默认 100)

disk-saver#

每次检查 disk-saver 个 data,并将需要保存至硬盘的 data 保存到硬盘(默认 100)

详细请参考 nuster rule disk mode.

purge-method [cache only]#

自定义 PURGE 用的 HTTP method,最大 14 个字符,默认是 PURGE.

uri [cache only]#

定义并开启 cache manager/stats API

nuster cache on uri /_my/_unique/_/_cache/_uri

cache manager/stats 默认是关闭的。如果开启了,主义开启访问控制 (see FAQ).

具体请参考缓存管理缓存统计.

proxy: nuster cache|nosql#

syntax:

nuster cache [on|off]

nuster nosql [on|off]

default: on

context: backend

决定是否在这个 backend 开启 cache/nosql。
如果这个 section 有 filter,记得放在最后。

nuster rule#

syntax: nuster rule name [key KEY] [ttl TTL] [code CODE] [disk MODE] [if|unless condition]

default: none

context: backend

定义 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 永远不会被匹配。

name#

定义 rule 的 name。

在 cache manager API 中使用,不必唯一但是建议不同的 rule 用不同的 name,否则相同 name 的 rule 视作一样。

key KEY#

定义 cache/nosql 的 key, 由下列关键字加. 组成

  • 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 的默认 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;

生成:

  • 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)

默认 key 产生 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 的请求则会直接返回 cache 给客户端。

ttl TTL#

设置缓存生存时间,过期后缓存会被删除。 可以使用 d, h, m and s。默认 0 秒.
如果不希望失效则设为 0

code CODE1,CODE2...#

默认只缓存 200 的响应,如果需要缓存其他的则可以添加,all 会缓存任何状态码。

cache-rule only200
cache-rule 200and404 code 200,404
cache-rule all code all

disk MODE#

定义缓存持久模式

  • off: 默认模式,仅保存在内存
  • only: 不保存在内存,仅保存在硬盘
  • sync: 保存到内存和硬盘后返回给客户端
  • async: 保存到内存后立即换回给客户的,内存数据会由 master 进程在一定时间后保存至硬盘

if|unless condition#

定义 ACL 条件

ACL 分别在请求阶段和响应阶段执行。

当下述条件满足时,会进行缓存:

  1. 在请求阶段 ACL 为真
  2. 请求阶段 ACL 为假,但是响应阶段 ACL 为真

当使用否定的 ACL 或者某些样本获取方法时,需要特别注意

比如

  1. 缓存以 /img/ 开头的请求

    nuster rule img if { path_beg /img/ }

请求阶段要么为真要么为假,因为在响应阶段无法获取 path 所以永远为假。

  1. 缓存响应的 http 头部 Content-Typeimage/jpeg

    nuster rule jpeg if { res.hdr(Content-Type) image/jpeg }

因为在请求阶段无法获取 res.hdr 所以永远为假,在响应阶段要么为真要么为假。

  1. /img/ 开头,并且响应头 Content-Typeimage/jpeg 时缓存

如果定义为下面的规则,则不会成功:

nuster rule img if { path_beg /img/ } { res.hdr(Content-Type) image/jpeg }

因为在响应阶段无法获取 path 所以永远为假,而在请求阶段无法获取 res.hdr 所以永远为假,那么这个 ACL 就永远无法匹配。

需要如下来定义:

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
  1. 另一个例子,缓存所有不以 /api/ 开头的请求

下面不正确:

acl NoCache path_beg /api/
nuster rule r3 if !NoCache

因为虽然在响应阶段 path 并不存在,所以 NoCache 永远为假,而 !NoCache 为真,所有的请求都会被缓存。

需要改成:

http-request set-var(txn.path) path
acl NoCache var(txn.path) -m beg /api/
nuster rule r1 if !NoCache

会添加一些新的样本获取方法来简化这些操作。

详见 HAProxy configuration7. Using ACLs and fetching samples

Cache#

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#

同时设置 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.

删除一个特定 URL#

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 删除#

可以通过带上 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

通过 host 删除#

通过带上 x-hostheader 来删除所有属于这个 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

通过 path 删除#

默认情况下,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 注意事项

  1. 开启访问控制

  2. 如果有多个 header,按照 name, path & host, path, regex & host, regex, host 的顺序处理

    curl -XPURGE -H "name: rule1" -H "path: /imgs/a.jpg": purge by name

  3. 如果有重复的 header,处理第一个

    curl -XPURGE -H "name: rule1" -H "name: rule2": purge by rule1

  4. regex 不是 glob

    比如 /imgs 下的.jpg 文件是 ^/imgs/.*\.jpg$ 而不是 /imgs/*.jpg

  5. 通过 rule name 或 proxy name 删除缓存时,需要注意这两种方法只在当前进程有效。如果重启了进程则无法通过这两种方法删除缓存文件,因为 rule name 信息和 proxy name 信息并没有保存在缓存文件中。

  6. 只有 disk load 结束后才能通过 host or path or regex 来删除缓存文件。是否已经 load 结束可以查看 stats URL。

缓存统计#

可以通过 GET uri 定义的 endpoint 来获取缓存统计信息。

Eanble and define the endpoint#

nuster cache on uri /nuster/cache

Usage#

curl http://127.0.0.1/nuster/cache

Output#

  • used_mem: http 缓存使用的内存,不包括 overhead
  • req_total: 开启了 cache 的所有的 backend 的总请求数,不包含那些没有 cache 的 backend 的请求数
  • req_hit: cache 击中数
  • req_fetch: 从后端取得数量
  • req_abort: 中断的请求

NoSQL#

nuster 也可以用作 RESTful NoSQL 缓存服务器,用 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
    • 发生未知错误
  • 507 Insufficient Storage
    • 超过 data-size

分用户的 data#

通过在 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 }

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.

硬盘持久化#

配置文件

global
    master-worker
    nuster cache on data-size 10m dir /tmp/cache
    nuster nosql on data-size 10m dir /tmp/nosql
backend be
    nuster cache on
    nuster rule off   disk off   ttl 1m if { path_beg /disk-off }
    nuster rule only  disk only  ttl 1d if { path_beg /disk-only }
    nuster rule sync  disk sync  ttl 1h if { path_beg /disk-sync }
    nuster rule async disk async ttl 2h if { path_beg /disk-async }
    nuster rule others ttl 100
  1. /disk-off 仅保存在内存
  2. /disk-only 仅保存在硬盘
  3. /disk-sync 保存至内存和硬盘后返回给客户端
  4. /disk-async 保存至内存后立即换回给客户端,内存数据会在一定时间后被缓存至硬盘
  5. 其他的所有请求都仅保存在内存

Sample fetches#

Nuster 加入了一些新的 sample fetches

nuster.cache.hit: boolean#

表示是否是 HIT 缓存,可以像如下使用

http-response set-header x-cache hit if { nuster.cache.hit }

FAQ#

无法启动,报错: not in master-worker mode#

global 添加 master-worker 或者启动时使用 -W 参数。

如何调试?#

global 添加 debug, 或者带 -d 启动 nuster

nuster 相关的调试信息以 [nuster 开头

如何缓存 POST 请求?#

添加 option http-buffer-request

如果自定义了 key 的话需要使用 body 关键字

请求 body 可能不完整,详见 HAProxy configurationoption 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

如何开启 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

Contributing#

  • Join the development
  • Give feedback
  • Report issues
  • Send pull requests
  • Spread nuster

License#

Copyright (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.

本作品采用《CC 协议》,转载必须注明作者和本文链接
高性能缓存服务器 nuster github.com/jiangwenyuan/nuster
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。