| |
| -登录 |
| -手机验证码登录---》输入框输入手机号---》监听失去焦点事件---》手机号正则校验(js),查询手机号是否存在----》发送验证码的按钮可以点击---》点击发送验证码按钮---》ajax 发送验证码---》起了个定时任务---》手机收到了验证码,填入验证码框-----》点击登录按钮----》向后端发送登录ajax请求----》返回给前端token和username----》前端保存到cookie中----》子传父,关闭了登录模态框----》在Header.vue 取了一下token和username |
| -多方式登录---》输入用户名和密码后----》点击登录--》后端登录成功,返回username和token---》后面的同上 |
| |
| -注册 |
| -输入手机号---》监听失去焦点事件---》手机号正则校验(js),查询手机号是否存在-如果不存在---》发送验证码的按钮可以点击---》点击发送验证码按钮---》ajax 发送验证码---》起了个定时任务---》手机收到了验证码,填入验证码框-----》填入密码---》点击注册---》调用注册接口完成注册----》子传父---》Register.vue---->显示出Login.vue |
| |
| |
| |
| -数据库,非关系型数据库,缓存数据库,key-value形式存储,数据都在内存中,有5大数据类型,速度非常快,数据操作是单线程,不存在并发安全的问题 |
| -redis的缓存更新策略 |
| -为什么这么快: |
| 1 纯内存操作 |
| 2 高性能的网络模型 IO多路复用(epoll) |
| 3 单线程,不存在线程间切换 |
| |
| -redis版本 |
| 7.x 最新 |
| 6.x 从它后,多进程,多线程架构 |
| 5.x及之前 单进程单线程架构 |
| |
| -进程:资源分配的最小单位,一个程序运行起来,可能一个进程,也可能多个进程 |
| -线程:cpu调度的最小单位,遇到io操作,操作系统层面切换 |
| -协程:单线程下的并发,程序层面控制,遇到io操作,切换到别的任务执行 |
| |
| |
| |
| |
| -mac 编译完成了,bin路径下 redis-server redis-cli |
| -linux 编译安装 |
| -win 专门的安装包 |
| 一路下一步 |
| |
| |
| -安装完成会有两个命令:启动服务端,启动客户端 cs架构的软件 |
| -客户端和服务端在同一台机器上 |
| -本地的客户端可以连接远程的服务器 |
| -mysql 也是cs架构软件 |
| -pymysql :是mysql的客户端 |
| -Navicate:是mysql客户端 |
| -go语言操作mysql:是mysql客户端 |
| |
| -启动redis服务 |
| -redis-server 指定配置文件 |
| -使用服务启动 |
| -客户端连接 |
| -cmd中使用redis-cli |
| -图形化界面 |
| -python的redis模块操作redis |
| |
| |
| -普通连接 |
| -连接池连接:单例模式 |
| -django 使用mysql连接池 |
| |
| |
| |
| |
| -get |
| -set |
| -strlen |
| -mset |
| -mget |
| -getrang |
| .... |
| |
| |
| |
| |
1 redis之列表
| ''' |
| 1 lpush(name, values) |
| 2 rpush(name, values) 表示从右向左操作 |
| 3 lpushx(name, value) |
| 4 rpushx(name, value) 表示从右向左操作 |
| 5 llen(name) |
| 6 linsert(name, where, refvalue, value)) |
| 7 r.lset(name, index, value) |
| 8 r.lrem(name, value, num) |
| 9 lpop(name) |
| 10 rpop(name) 表示从右向左操作 |
| 11 lindex(name, index) |
| 12 lrange(name, start, end) |
| 13 ltrim(name, start, end) |
| 14 rpoplpush(src, dst) |
| 15 blpop(keys, timeout) |
| 16 r.brpop(keys, timeout),从右向左获取数据 |
| 17 brpoplpush(src, dst, timeout=0) |
| |
| ''' |
| |
| import redis |
| |
| conn = redis.Redis() |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| conn.close() |
| |
| |
| ''' |
| lpush |
| lpop |
| llen |
| lrange |
| ''' |

2 redis之hash
| ''' |
| 1 hset(name, key, value) |
| 2 hmset(name, mapping) |
| 3 hget(name,key) |
| 4 hmget(name, keys, *args) |
| 5 hgetall(name) |
| 6 hlen(name) |
| 7 hkeys(name) |
| 8 hvals(name) |
| 9 hexists(name, key) |
| 10 hdel(name,*keys) |
| 11 hincrby(name, key, amount=1) |
| 12 hincrbyfloat(name, key, amount=1.0) |
| 13 hscan(name, cursor=0, match=None, count=None) |
| 14 hscan_iter(name, match=None, count=None) |
| |
| ''' |
| |
| import redis |
| |
| conn = redis.Redis() |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| conn.hincrby('userinfo', 'age', 2) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| res=conn.hscan_iter('hash_test',count=10) |
| |
| |
| |
| |
| |
| |
| ''' |
| hset |
| hget |
| hmget |
| hlen |
| hdel |
| hscan_iter 获取所有值,但是省内存 等同于hgetall |
| ''' |
| |
| |
| |
| conn.close() |
| |
3 redis其他操作
| ''' 通用操作,不指定类型,所有类型都支持 |
| 1 delete(*names) |
| 2 exists(name) |
| 3 keys(pattern='*') |
| 4 expire(name ,time) |
| 5 rename(src, dst) |
| 6 move(name, db)) |
| 7 randomkey() |
| 8 type(name) |
| ''' |
| |
| import redis |
| |
| conn = redis.Redis() |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| print(conn.type('age')) |
| conn.close() |
| |
4 redis 管道
| |
| -原子性 |
| -一致性 |
| -隔离性 |
| -持久性 |
| |
| |
| |
| |
| |
| |
| -执行命令 一条一条执行 |
| -张三 金额 -100 conn.decr('zhangsan_je',100) |
| 挂了 |
| -你 金额 100 conn.incr('李四_je',100) |
| |
| |
| - 把这两条命令,放到一个管道中,先不执行,执行excute,一次性都执行完成 |
| conn.decr('zhangsan_je',100) conn.incr('李四_je',100) |
| |
| |
| |
| |
| import redis |
| conn = redis.Redis() |
| p=conn.pipeline(transaction=True) |
| p.multi() |
| p.decr('zhangsan_je', 100) |
| |
| p.incr('lisi_je', 100) |
| |
| p.execute() |
| conn.close() |
| |
5 django中使用redis
| |
| -第一步:写一个pool.py |
| import redis |
| POOL = redis.ConnectionPool(max_connections=100) |
| -第二步:以后在使用的地方,直接导入使用即可 |
| conn = redis.Redis(connection_pool=POOL) |
| conn.incr('count') |
| res = conn.get('count') |
| |
| |
| |
| |
| -方案一:django的缓存使用redis 【推荐使用】 |
| -settings.py 中配置 |
| CACHES = { |
| "default": { |
| "BACKEND": "django_redis.cache.RedisCache", |
| "LOCATION": "redis://127.0.0.1:6379", |
| "OPTIONS": { |
| "CLIENT_CLASS": "django_redis.client.DefaultClient", |
| "CONNECTION_POOL_KWARGS": {"max_connections": 100} |
| |
| } |
| } |
| } |
| |
| -在使用redis的地方:cache.set('count', res+1) |
| -pickle序列化后,存入的 |
| |
| -方案二:第三方:django-redis模块 |
| from django_redis import get_redis_connection |
| def test_redis(request): |
| conn=get_redis_connection() |
| print(conn.get('count')) |
| return JsonResponse({'count': '今天这个接口被访问的次数为:%s'}, json_dumps_params={'ensure_ascii': False}) |
| |
5 celery介绍和安装
| |
| -翻译过来是 芹菜 的意思,跟芹菜没有关系 |
| -框架:服务,python的框架,跟django无关 |
| -能用来做什么 |
| -1 异步任务 |
| -2 定时任务 |
| -3 延迟任务 |
| |
| |
| |
| """ |
| 1)可以不依赖任何服务器,通过自身命令,启动服务 |
| 2)celery服务为为其他项目服务提供异步解决任务需求的 |
| 注:会有两个服务同时运行,一个是项目服务,一个是celery服务,项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求 |
| |
| 人是一个独立运行的服务 | 医院也是一个独立运行的服务 |
| 正常情况下,人可以完成所有健康情况的动作,不需要医院的参与;但当人生病时,就会被医院接收,解决人生病问题 |
| 人生病的处理方案交给医院来解决,所有人不生病时,医院独立运行,人生病时,医院就来解决人生病的需求 |
| """ |
| |
| |
| |
| |
| - 1 任务中间件 Broker(中间件),其他服务提交的异步任务,放在里面排队 |
| -需要借助于第三方 redis rabbitmq |
| - 2 任务执行单元 worker 真正执行异步任务的进程 |
| -celery提供的 |
| - 3 结果存储 backend 结果存储,函数的返回结果,存到 backend中 |
| -需要借助于第三方:redis,mysql |
| |
| |
| |
| |
| |
| 异步执行:解决耗时任务 |
| 延迟执行:解决延迟任务 |
| 定时执行:解决周期(周期)任务 |
| |
| |
| |
| |
6 celery快速使用
| |
| pip install celery |
| win:pip install eventlet |
| |
| |
| |
| |
| from celery import Celery |
| |
| broker = 'redis://127.0.0.1:6379/1' |
| |
| backend = 'redis://127.0.0.1:6379/2' |
| app = Celery('test', broker=broker, backend=backend) |
| @app.task |
| def add(a, b): |
| import time |
| time.sleep(3) |
| print('------',a + b) |
| return a + b |
| |
| |
| res = add.delay(5,6) |
| print(res) |
| |
| |
| |
| |
| win: |
| -4.x之前版本 |
| celery worker -A main -l info -P eventlet |
| -4.x之后 |
| celery -A main worker -l info -P eventlet |
| mac: |
| celery -A main worker -l info |
| |
| |
| |
| |
| |
| |
| from main import app |
| from celery.result import AsyncResult |
| id = '51611be7-4914-4bd2-992d-749008e9c1a6' |
| if __name__ == '__main__': |
| a = AsyncResult(id=id, app=app) |
| if a.successful(): |
| result = a.get() |
| print(result) |
| elif a.failed(): |
| print('任务失败') |
| elif a.status == 'PENDING': |
| print('任务等待中被执行') |
| elif a.status == 'RETRY': |
| print('任务异常后正在重试') |
| elif a.status == 'STARTED': |
| print('任务已经开始被执行') |
7 celery包结构
| project |
| ├── celery_task |
| │ ├── __init__.py |
| │ ├── celery.py |
| │ └── tasks.py |
| ├── add_task.py |
| └── get_result.py |
| |
| |
| |
| |
| from celery import Celery |
| broker = 'redis://127.0.0.1:6379/1' |
| backend = 'redis://127.0.0.1:6379/2' |
| app = Celery('test', broker=broker, backend=backend, include=['celery_task.order_task', 'celery_task.user_task']) |
| |
| |
| |
| |
| from .celery import app |
| import time |
| @app.task |
| def add(a, b): |
| print('-----', a + b) |
| time.sleep(2) |
| return a + b |
| |
| |
| from .celery import app |
| import time |
| @app.task |
| def send_sms(phone, code): |
| print("给%s发送短信成功,验证码为:%s" % (phone, code)) |
| time.sleep(2) |
| return True |
| |
| |
| celery -A celery_task worker -l info -P eventlet |
| |
| |
| |
| from celery_task import send_sms |
| res=send_sms.delay('1999999', 8888) |
| print(res) |
| |
| |
| |
| |
| |
| from celery_task import app |
| from celery.result import AsyncResult |
| id = '7d39033c-4cc7-4af2-8d78-e62c277db183' |
| if __name__ == '__main__': |
| a = AsyncResult(id=id, app=app) |
| if a.successful(): |
| result = a.get() |
| print(result) |
| elif a.failed(): |
| print('任务失败') |
| elif a.status == 'PENDING': |
| print('任务等待中被执行') |
| elif a.status == 'RETRY': |
| print('任务异常后正在重试') |
| elif a.status == 'STARTED': |
| print('任务已经开始被执行') |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY