[INet] 借助 HTTP Cache 加速应用响应
背景:
GET 访问一个应用的时候,内容一般都不会时刻在变,如何让下一个人请求时极速获取响应过的内容,并且在内容发生变更时能够识别出来。
在应用层做 Cache 是一种方法,但是依旧要响应整个 Body 给客户端,没有减少带宽消耗,只减少 CPU、DB 消耗。
HTTP Cache 就是解决这个问题的,相同请求的第二次不再到达后端,具体支持是由标准 HTTP 协议。
使用 HTTP Cache 之后的请求流程可以看这篇 HTTP Caching 的两种模式图解:https://tomayko.com/blog/2008/things-caches-do
这里提一下另一种方式 HTTP Gateway Cache,是完全把 Client 和 Application 独立开,相当于一个中间层,接受客户端请求,接收后端响应并发送给客户端。
HTTP gateway cache 的方案有 Varnish,Squid。
HTTP Cache 提供了常用的四个缓存头来启用缓存,只工作于安全方法 GET、HEAD,
Cache-Control
Expires
ETag(entity-tag 的意思)
Last-Modified
前两个方式都可用于设置缓存过期时间,后两个方式都可用于给客户端验证缓存是否已失效。
缓存过期时间 和 缓存验证 可以结合起来达到最好效果。
在 Laravel 中使用 HTTP Cache
https://laravel.com/docs/6.x/responses#attaching-headers-to-responses,
第一种方式是借助 Response 组件的 API,通过给 Response 附加 Header 信息,header() 与 withHeaders() 两类方法。
第二种方式是使用 Cache Control Middleware 给一组路由快速设置 cache-control、etag、last_modified 等。
# routeMiddleware
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class
# Apply example
Route::middleware('cache.headers:private;max_age=60')
某些场景,如果不希望/没必要刷新设置好的 HTTP Cache,其它位置又想获取该 API 的实时数据,最简单的方式是加随机参数,如 ?t=time(),互不影响。
Symfony HTTP Cache:https://symfony.com/doc/current/http_cache.html
Symfony HTTP Cache Validation:https://symfony.com/doc/current/http_cache/validation.html
HTTP/1.1 RFC, HTTP Caches and associated header fields:https://tools.ietf.org/html/rfc7234
HTTP/1.1 RFC, HTTP Conditional Request:https://tools.ietf.org/html/rfc7234
cache-control private:https://baike.baidu.com/item/Cache-control/1885913