一.如何提升网站的并发量javascript
在动态网站中,用户全部的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.html
当一个网站的用户访问量很大的时候,每一次的的后台操做,都会消耗不少的服务端资源,因此必须使用缓存来减轻后端服务器的压力.java
缓存是将一些经常使用的数据保存内存或者memcache中,在必定的时间内有人来访问这些数据时,则再也不去执行数据库及渲染等操做,而是直接从内存或memcache的缓存中去取得数据,而后返回给用户.python
如何提升网站并发量? -cdn加速:把静态资源放到别人服务器 -精灵图 -后台数据库用mysql+redis -数据库的优化 -sql的优化 -索引 -分库分表 -读写分离 -用缓存 -程序架构 -集群化的部署 -分布式+异步 celery:分布式异步任务框架 -语言
二.django缓存的6种配置mysql
1. 开发调试(此模式为开发调试使用,实际上不执行任何操做)redis
在settings.py文件配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 缓存后台使用的引擎 'TIMEOUT': 300, # 缓存超时时间(默认300秒,None表示永不过时,0表示当即过时) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, } }
2. 内存缓存(将缓存内容保存至内存区域中)sql
在settings.py文件配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 指定缓存使用的引擎 'LOCATION': 'unique-snowflake', # 写在内存中的变量的惟一值 'TIMEOUT':300, # 缓存超时时间(默认为300秒,None表示永不过时) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
3.文件缓存(把缓存数据存储在文件中)数据库
在settings.py文件配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎 'LOCATION': '/var/tmp/django_cache', #指定缓存的路径 'TIMEOUT':300, #缓存超时时间(默认为300秒,None表示永不过时) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
4. 数据库缓存(把缓存数据存储在数据库中)django
在settings.py文件配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', # 指定缓存使用的引擎 'LOCATION': 'cache_table', # 数据库表 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
注意,建立缓存的数据库表使用的语句:
python manage.py createcachetable
5.Memcache缓存(使用python-memcached模块链接memcache)json
Memcached是Django原生支持的缓存系统.要使用Memcached,须要下载Memcached的支持库python-memcached或pylibmc.
settings.py文件配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', # 指定缓存使用的引擎 'LOCATION': '192.168.10.100:11211', # 指定Memcache缓存服务器的IP地址和端口 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
LOCATION也能够配置成以下:
'LOCATION': 'unix:/tmp/memcached.sock', # 指定局域网内的主机名加socket套接字为Memcache缓存服务器 'LOCATION': [ # 指定一台或多台其余主机ip地址加端口为Memcache缓存服务器 '192.168.10.100:11211', '192.168.10.101:11211', '192.168.10.102:11211', ]
6. Memcache缓存(使用pylibmc模块链接memcache)
settings.py文件配置 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', # 指定缓存使用的引擎 'LOCATION':'192.168.10.100:11211', # 指定本机的11211端口为Memcache缓存服务器 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, } }
LOCATION也能够配置成以下:
'LOCATION': '/tmp/memcached.sock', # 指定某个路径为缓存目录 'LOCATION': [ # 分布式缓存,在多台服务器上运行Memcached进程,程序会把多台服务器看成一个单独的缓存,而不会在每台服务器上复制缓存值 '192.168.10.100:11211', '192.168.10.101:11211', '192.168.10.102:11211', ]
Memcached是基于内存的缓存,数据存储在内存中.因此若是服务器死机的话,数据就会丢失,因此Memcached通常与其余缓存配合使用
三. Django中的缓存应用
Django提供了不一样粒度的缓存,能够缓存某个页面,能够只缓存一个页面的某个部分,甚至能够缓存整个网站
1.单页面缓存
视图:
from django.views.decorators.cache import cache_page import time from .models import * @cache_page(15) #超时时间为15秒 def index(request): t=time.time() #获取当前时间 bookList=Book.objects.all() return render(request,"index.html",locals())
模板(index.html):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>当前时间:-----{{ t }}</h3> <ul> {% for book in bookList %} <li>{{ book.name }}--------->{{ book.price }}$</li> {% endfor %} </ul> </body> </html>
上面的例子是基于内存的缓存配置,基于文件的缓存该怎么配置呢??
更改settings.py的配置
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 指定缓存使用的引擎 'LOCATION': 'E:\django_cache', # 指定缓存的路径 'TIMEOUT': 300, # 缓存超时时间(默认为300秒,None表示永不过时) 'OPTIONS': { 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数以后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
而后再次刷新浏览器,能够看到在刚才配置的目录下生成的缓存文件
经过实验能够知道,Django会以本身的形式把缓存文件保存在配置文件中指定的目录中.
2.全站使用缓存
既然是全站缓存,固然要使用Django中的中间件.
用户的请求经过中间件,通过一系列的认证等操做,若是请求的内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户
当返回给用户以前,判断缓存中是否已经存在,若是不存在,则UpdateCacheMiddleware会将缓存保存至Django的缓存之中,以实现全站缓存
缓存整个站点,是最简单的缓存方法 在 MIDDLEWARE_CLASSES 中加入 “update” 和 “fetch” 中间件 MIDDLEWARE_CLASSES = ( ‘django.middleware.cache.UpdateCacheMiddleware’, #第一 'django.middleware.common.CommonMiddleware', ‘django.middleware.cache.FetchFromCacheMiddleware’, #最后 ) “update” 必须配置在第一个
修改settings.py配置文件
MIDDLEWARE_CLASSES = ( 'django.middleware.cache.UpdateCacheMiddleware', #响应HttpResponse中设置几个headers 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', #用来缓存经过GET和HEAD方法获取的状态码为200的响应 ) CACHE_MIDDLEWARE_SECONDS=10
视图函数:
from django.views.decorators.cache import cache_page import time from .models import * def index(request): t=time.time() #获取当前时间 bookList=Book.objects.all() return render(request,"index.html",locals()) def foo(request): t=time.time() #获取当前时间 return HttpResponse("HELLO:"+str(t))
模板(index.html):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3 style="color: green">当前时间:-----{{ t }}</h3> <ul> {% for book in bookList %} <li>{{ book.name }}--------->{{ book.price }}$</li> {% endfor %} </ul> </body> </html>
其他代码不变,刷新浏览器是10秒,页面上的时间变化一次,这样就实现了全站缓存.
3.局部视图缓存
例子,刷新页面时,整个网页有一部分实现缓存
views视图函数
from django.views.decorators.cache import cache_page
import time
from .models import *
def index(request):
t=time.time() #获取当前时间
bookList=Book.objects.all()
return render(request,"index.html",locals())
模板(index.html):'name'是别名'
{% load cache %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3 style="color: green">不缓存:-----{{ t }}</h3> {% cache 2 'name' %} <h3>缓存:-----:{{ t }}</h3> {% endcache %} </body> </html>
四.跨域问题
1.-同源策略:浏览器的安全策略,请求发出去了,也正常响应了,可是被浏览器拦截了
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,若是缺乏了同源策略,则浏览器的正常功能可能都会受到影响。能够说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.
好比:我在本地上的域名是127.0.0.1:8000,请求另一个域名:127.0.0.1:8001一段数据
浏览器上就会报错,个就是同源策略的保护,若是浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险
2.CORS(跨域资源共享)(处理跨域问题)
(1)什么是cors
CORS须要浏览器和服务器同时支持。目前,全部浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,
就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。
所以,实现CORS通讯的关键是服务器。只要服务器实现了CORS接口,就能够跨源通讯
(2)cors分类
只要同时知足如下两大条件,就属于简单请求。
(1) 请求方法是如下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出如下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不一样时知足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不同的。
简单请求和非简单请求的区别?
简单请求:一次请求
非简单请求:两次请求,在发送数据以前会先发一次请求用于作“预检”,只有“预检”经过后才再发送一次请求用于数据传输。
* 关于“预检”
- 请求方式:OPTIONS
- “预检”其实作检查,检查若是经过则容许传输数据,检查不经过则再也不发送真正想要发送的消息
- 如何“预检”
=> 若是复杂请求是PUT等请求,则服务端须要设置容许某请求,不然“预检”不经过
Access-Control-Request-Method
=> 若是复杂请求设置了请求头,则服务端须要设置容许某请求头,不然“预检”不经过
Access-Control-Request-Headers
支持跨域,简单请求
服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'
支持跨域,复杂请求
因为复杂请求时,首先会发送“预检”请求,若是“预检”成功,则发送真实数据。
.“预检”请求时,容许请求方式则需服务器设置响应头:Access-Control-Request-Method
.“预检”请求时,容许请求头则需服务器设置响应头:Access-Control-Request-Headers
(3)Django项目中支持CORS
在返回的结果中加入容许信息(简单请求)
def test(request):
import json
obj=HttpResponse(json.dumps({'name':'lqz'}))
# obj['Access-Control-Allow-Origin']='*'
obj['Access-Control-Allow-Origin']='http://127.0.0.1:8004'
return obj
放到中间件处理复杂和简单请求:
在api下建立py文件
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
def process_response(self,request,response):
if request.method=="OPTIONS":
#能够加*
response["Access-Control-Allow-Headers"]="Content-Type"
response['Access-Control-Allow-Methods']='PUT,DELETE'
response["Access-Control-Allow-Origin"] = "http://localhost:8080"
return response
而后把该文件配置到setting的中间件中