Skip to content
HTTP cache server, such as varnish
Go JavaScript CSS Other
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode
assets
cache
config
df
log
middleware
server
stats
upstream
util
web
.gitignore
.travis.yml
Dockerfile
Makefile
README.md
config.yml
director.yml
go.mod
go.sum chore: update modules Aug 16, 2019
main.go
runner.conf

README.md

pike

Build Status

HTTP cache server like varnish.

主要特性

  • 支持gzipbr压缩智能选择
  • 多数据源配置方式:文件与ETCD
  • 实时无中断的配置更新(TODO如何做到)
  • 通过Cache-Control的标准化缓存处理

HTTP缓存

根据HTTP请求生成缓存的key

缓存的key默认的生成方式为Method Host RequestURI,根据此三个参数生成请求的唯一key,以此判断是否可使用同一缓存。Host先从HTTP头中获取,如果没有,则从url中获取,需要注意,如果同一服务使用多个域名,如wwww.aslant.site与aslant.site是指向同一个服务,此两个域名会导致生成两个不同的缓存,建议在前置反向代理中将HTTP请求头统一重设。

根据HTTP响应头生成缓存时长

  • 响应头有Set-Cookie则不可缓存
  • 响应头没有Cache-Control则不可缓存
  • Cache-Control包含no-cacheno-store或者private则不可缓存
  • 获取Cache-Control中的s-maxage的值,如果没有则获取max-age的值为初始缓存时长
  • 再获取Age请求头中的值,如果能获取到该值,则初始缓存时长减去Age则为真正的缓存时长

模块

  • cache 缓存模块
    • brotli 提供brotli压缩
    • gzip 提供gzip压缩
    • cache 根据key获取相应的缓存数据,以分区的形式保存,减少锁的场景提升性能
    • lru LRU缓存
  • config 应用程序配置模块
    • config 程序配置
    • etcd_config 从ETCD中读写配置
    • file_config 从文件中读写配置
  • middleware 相关中间件
    • initialization 初始请求,主要判断是否超出最大请求数,设置请求头以及成功处理后设置响应头
    • cache_identifier 判断请求是否可缓存,如果不可缓存,直接转至下一中间件。如果获取不至缓存,则设置为fetch状态,根据最终响应数据转换为hit for pass或cacheable。如果获取到缓存,则设置缓存并转至下一中间件。
    • proxy 如果该请求已获取到相应的缓存数据,则转至下一中间件,否则转发至相应的upstream
    • responder 将缓存转换为相应的HTTP响应数据

测试场景

  • 非GET、HEAD直接请求pass至后端
  • 非文本类数据不压缩
  • POST不可缓存请求,后端返回数据未压缩
  • POST不可缓存请求,后端返回数据已压缩
  • GET不可缓存请求,后端返回数据未压缩
  • GET不可缓存请求,后端返回数据已压缩
  • GET可缓存请求,后端返回数据未压缩
  • GET可缓存请求,后端返回数据已压缩
  • 后端返回数据未添加ETag
  • 后端返回数据已添加ETag
  • 304的处理

性能测试

可缓存的接口,gzip(2436字节),原数据9286字节

wrk -c1000 -t10 -d1m -H 'Accept-Encoding: gzip, deflate' --latency 'http://127.0.0.1:3005/chapters'
Running 1m test @ http://127.0.0.1:3005/chapters
  10 threads and 1000 connections

  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    23.90ms   47.63ms   1.23s    97.84%
    Req/Sec     5.16k   595.36     9.68k    76.77%
  Latency Distribution
     50%   16.88ms
     75%   23.88ms
     90%   38.70ms
     99%   94.31ms
  3081367 requests in 1.00m, 7.73GB read
Requests/sec:  51276.94
Transfer/sec:    131.68MB

可缓存的接口,br(1958字节),原数据9286字节

wrk -c1000 -t10 -d1m -H 'Accept-Encoding: br' --latency 'http://127.0.0.1:3005/chapters'
Running 1m test @ http://127.0.0.1:3005/chapters
  10 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.63ms   27.32ms   1.04s    94.50%
    Req/Sec     5.18k   534.52    11.17k    72.66%
  Latency Distribution
     50%   16.77ms
     75%   23.72ms
     90%   37.78ms
     99%   80.60ms
  3094104 requests in 1.00m, 6.38GB read
Requests/sec:  51480.91
Transfer/sec:    108.63MB

文件配置

首次启动时,无配置文件,因此需要通过ENV的形式指定管理后台路径,如下:

docker run -it --rm \
  -p 3015:3015 \
  -v ~/tmp/pike:/home/pike \
  -e ADMIN_PATH=/pike \
  vicanso/pike

打开地址http://127.0.0.1:3015/pike/#/,配置相关信息:

配置完成后,则可正式启动服务:

docker run -d --restart=always \
  -p 3015:3015 \
  -v ~/tmp/pike:/home/pike \
  vicanso/pike

ETCD

建议使用ETCD来存储配置文件(便于启用多实例),如果未有ETCD的服务,可以使用下面的方式简单启动:

docker run -d --restart=always \
  -p 2379:2379 \
  --name etcd \
  vicanso/etcd etcd \
  --listen-client-urls 'http://0.0.0.0:2379' \
  --advertise-client-urls 'http://0.0.0.0:2379'

使用ETCD存储文件,需要指定连接地址,因为首次启动时,ETCD中无相关配置,因此需要通过ENV的形式指定管理后台路径,如下:

docker run -it --rm \
  -p 3015:3015 \
  -e CONFIG=etcd://172.20.10.2:2379/test-pike \
  -e ADMIN_PATH=/pike \
  vicanso/pike

后续的配置与使用文件的配置形式一样,在配置完成后,则可以正式启用服务:

docker run -d --restart=always \
  -p 3015:3015 \
  -e CONFIG=etcd://172.20.10.2:2379/test-pike \
  vicanso/pike

程序运行中会监听ETCD中配置的文件,自动更新配置,因此可以配置多实例,在其中一个的管理后台上修改配置则各实例实时生效。

You can’t perform that action at this time.