• django缓存和跨域问题


    一.如何提高网站的并发量

    在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.

    当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力.

    缓存是将一些常用的数据保存内存或者memcache中,在一定的时间内有人来访问这些数据时,则不再去执行数据库及渲染等操作,而是直接从内存或memcache的缓存中去取得数据,然后返回给用户.

    如何提高网站并发量?
                -cdn加速:把静态资源放到别人服务器
                -精灵图
                -后台数据库用mysql+redis
                -数据库的优化
                    -sql的优化
                    -索引
                    -分库分表
                    -读写分离
                -用缓存
                -程序架构
                    -集群化的部署
                    -分布式+异步  celery:分布式异步任务框架
                -语言

    二.django缓存的6种配置

    1. 开发调试(此模式为开发调试使用,实际上不执行任何操作)

    在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. 内存缓存(将缓存内容保存至内存区域中)

    在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. 数据库缓存(把缓存数据存储在数据库中)

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

    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的中间件中

  • 相关阅读:
    java mail实现Email的发送,完整代码
    Android NetworkOnMainThreadException异常
    Anguler Js 表单验证(邮箱)
    Android 调用系统邮件,发送邮件到指定邮箱
    Android 解决ScrollView下嵌套ListView进页面不在顶部的问题
    Eclipse 出错 Error:Could not create the Java Virtual Machine Error:A fatal exception has occurred
    Eclipse "Could not create java virtual machine"的问题解决
    Elasticsearch之watcher(告警)插件安装之后的浏览详解
    Elasticsearch之shield(权限)插件安装之后的浏览详解
    Elasticsearch之源码分析(shard分片规则)
  • 原文地址:https://www.cnblogs.com/ye-hui/p/10442871.html
Copyright © 2020-2023  润新知