一、浏览器缓存机制
Cache-control策略(重点关注)
Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
![](https://images2015.cnblogs.com/blog/947547/201704/947547-20170401153321883-1653635625.jpg)
还是上面那个请求,web服务器返回的Cache-Control头的值为max-age=300,即5分钟(和上面的Expires时间一致,这个不是必须的)。
![](https://images2015.cnblogs.com/blog/947547/201704/947547-20170401153426711-1412453632.jpg)
Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用。
l Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
l If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
一、Django缓存机制
1、Django缓存原理:
Django根据设置的缓存方式,浏览器第一次请求时,cache会缓存单个变量或整个网页等内容到硬盘或者内存中,同时设置response头部,当浏览器再次发起请求时,附带f-Modified-Since请求时间到Django,Django 发现f-Modified-Since会先去参数之后,会与缓存中的过期时间相比较,如果缓存时间比较新,则会重新请求数据,并缓存起来然后返回response给客户端,如果缓存没有过期,则直接从缓存中提取数据,返回给response给客户端。
1.1、通用设置:
1.1.1、设置中间件
1 'django.middleware.cache.UpdateCacheMiddleware', #必须设置在第一个位置 2 ...其他中间件... 3 'django.middleware.cache.FetchFromCacheMiddleware',#必须设置在最后一个位置
1.1.2、通用设置:
1 CACHE_MIDDLEWARE_ALIAS = 'default' #用来存储的缓存别名 2 CACHE_MIDDLEWARE_SECONDS = 0 #所有页面默认缓存时间,默认600 3 CACHE_MIDDLEWARE_KEY_PREFIX ='www.demo.com' #关键的前缀,当多个站点使用同一个配置的时候,这个可以设置可以避免发生冲突,一般设置为网站域名 4 CACHE_MIDDLEWARE_ANONYMOUS_ONLY = False #那么只有匿名的请求会被缓存,这是一个禁用缓存非匿名用户页面的最简单的做法,注意确保已经启用了Django用户认证中间件
2.1、Django缓存方式选择:
2.1.1、memcached缓存
需要pip安装memcached的插件Python-mencached和pylibmc,可以同时支持多个服务器上面的memcached
1 'django.core.cache.backends.memcached.MemcachedCache' 2 'django.core.cache.backends.memcached.PyLibMCCache' 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 6 'LOCATION': [ 7 '172.19.26.240:11211', #服务器1 8 '172.19.26.242:11211', #服务器2 9 ] 10 #'LOCATION': 'unix:/tmp/memcached.sock', #unix的socket的方式 11 } 12 }
2.1.2、数据库缓存
注意的是数据库缓存使用的是你配置文件中的数据库作为默认的数据库,如果一定要选用其他的数据库,则需要修改数据库缓存表
生成数据库表:
运行命令:python manage.py createcachetable my_cache_table
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'my_cache_table', }
2.1.3、文件系统缓存
注意是绝对位置(从根目录开始),必须保证服务器对你列出的路径具有读写权限
1 CACHES = { 2 'default': { 3 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 4 'LOCATION': '/var/tmp/django_cache',#这个是文件夹的路径 5 #'LOCATION': 'c:fooar',#windows下的示例 6 } 7 }
2.1.4、本地内存缓存
本地内存缓存,这个缓存是多进程和线程安全的
1 CACHES = { 2 'default': { 3 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 4 'LOCATION': 'unique-snowflake' 5 } 6 }
缓存LOCATION用来区分每个内存存储,如果你只有一个本地内存缓存,你可以忽略这个设置;但如果你有多个的时候,你需要至少给他们中一个赋予名字以区分他们。
注意每个进程都有它们自己的私有缓存实例,所以跨进陈缓存是不可能的,因此,本地内存缓存不是特别有效率的,建议你只是在内部开发测时使用,不建议在生产环境中使用
2.1.5、虚拟缓存
虚拟缓存,实际是没有缓存,只不过你设置缓存时间,请求的时候一样会设置这个时间,但是服务器并没有缓存起来,这个在开发测试阶段,不希望缓存,发布之后则希望缓存,非常实用,到发布的时候,直接把dummy.DummyCache缓存真真的缓存方式即可,其他的无需修改代码
1 CACHES = { 2 'default': { 3 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', 4 } 5 }
2.1.6、自定义缓存
1 CACHES = { 2 'default': { 3 'BACKEND': 'path.to.backend', 4 } 5 }
三、独立视图缓存
导入
1 from django.views.decorators.cache import cache_page, cache_control, never_cache
3.1、cache_page只接受一个参数和两个关键字参数
注意:cache_page装饰器的方式,即使没有设置缓存中间件,只要设置的缓存方式,也一样可以缓存
- timeout是缓存时间,以秒为单位
- cache:指定使用你的CACHES设置中的哪一个缓存后端
- key_prefix:指定缓存前缀,可以覆盖在配置文件中CACHE_MIDDLEWARE_KEY_PREFIX的
1 @cache_page(60 * 15, key_prefix="site1") 2 def my_view(request): 3 或者 4 urlpatterns = ('', 5 (r'^foo/(d{1,2})/$', cache_page(60 * 15)(my_view)), 6 )
3.2、cache_control控制缓存:使用其他的头部信息
其他的一些关于缓存的问题是:数据的私有性和数据应该被存储在级联的缓存的问题。一个用户面对两种类型的缓存:自己的浏览器缓存(私有的)和提供者的缓存(共有的);一个共有的缓存被多个用户使用同时被某个人控制,这将涉及到一些敏感的问题,比如你的银行账单。因此,我们的web应用需要一个方法告诉缓存那些数据是私有的,那些是可以共享的
1 @cache_control(private=True) def my_view(request):
最后列举cache_control接收到的参数:
- public=True
- private=True
- no_cache=True
- no_transform=True
- must_revalidate=True
- proxy_revalidate=True
- max_age=num_seconds
- s_maxage=num_seconds