0%

异步方案 celery 发短信 && Python单例方法

Python 单例方法
异步方案 celery 发短信

Python 单例方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


# 方式1 创建单例
class A:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)

return cls._instance

def goto(self,):
print("cj>>>>>")


a = A()
print(id(a)) #2641366741704
b = A()
print(id(b)) #2641366741704

# 方式2 创建单例
class A:

def __new__(cls, *args, **kwargs):
if not hasattr(A, "_instance"): # 是否有_instance属性
cls._instance = super().__new__(cls, *args, **kwargs)

return cls._instance

def goto(self,):
print("cj>>>>>")

使用单例 控制 只有一个短信发送对象

内存优化,减少内存消耗

使用pipline 操作redis

1
2
3
4
5
6
7
8
pl = redis.cli.pipeline()
pl.setex("send_flag_%s" % mobile, 60, 1)
pl.setex("sms_%s" % mobile, 300, sms_code)

# 5. 保存短信验证码到redis
# redis_cli.setex()
# 执行请求
pl.execute() #一次执行,减少内存消耗

异步方案 celery 发短信

生产消费者模式

  • 安装celery创建sms 包,并添加异步

    1
    pip install -U celery
  • 在根目录下 创建celery的包

    1618539278351

  • main.py

    • 1 设置django环境
      2 创建celery对象
      3 设置 broker
      4 celery自动检测任务
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import os

    # 1 设置django环境
    # set the default Django settings module for the 'celery' program.
    from celery import Celery

    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo.settings')

    # 2 创建celery对象
    app = Celery('celery_tasks')

    # 3 设置 broker
    app.config_from_object("celery_tasks.config")

    # 4celery自动检测任务 这里会自动去celery_tasks.sms下找tasks.py
    app.autodiscover_tasks(['celery_tasks.sms'])

  • redis 作为队列

    • config.py
    1
    2
    3
    4
    5

    # 把redis 作为队列
    broker_url = "redis://127.0.0.1/15"


  • sms的tasks.py里添加任务

    • tasks.py文件名不可改变

    1618539600277

启动celery

1
celery -A celery_tasks.main worker -l info

1618540420762

win10 遇到的小bug

开启服务发现,任务并未执行 上网查资料后发现,celery 对win10 支持并不是很好

解决此方案的

  • 方案1

  • 添加–pool=solo参数

    1
    2

    celery -A celery_tasks.main worker --pool=solo -l info
  • 方案2

  • 先安装gevent,然后在启动celery的时候添加gevent参数

    1
    2
    pip install gevent
    celery -A celery_tasks.main worker -l info -P gevent

参考资料:https://stackoverflow.com/questions/37255548/how-to-run-celery-on-windows

Django 地址设计

省市区三级联动

  • 缓存省市区数据

    提示:

    • 省市区数据是我们动态查询的结果。
    • 但是省市区数据不是频繁变化的数据,所以没有必要每次都重新查询。
    • 所以我们可以选择对省市区数据进行缓存处理。
  • 缓存方式

    • from django.core.cache import cache
    • 存储缓存数据:cache.set('key', 内容, 有效期)
    • 读取缓存数据:cache.get('key')
    • 删除缓存数据:cache.delete('key')
    • 注意:存储进去和读取出来的数据类型相同,所以读取出来后可以直接使用。
  • 缓存逻辑实现

    • 省份缓存数据
      • cache.set('province_list', province_list, 3600)
    • 市或区缓存数据
      • cache.set('sub_area_' + area_id, sub_data, 3600)

省级三联orm

1
2
3
4
5
# 查询所有省份
select * from tb_areas where parent_id is Null;

area_list = Area.objects.filter(parent=None)
Area.objects.filter(parent__isnull = True)

查询市级

1
2
3
4
5
6
7
select * from tb_areas where parent_id=130000; # 市
Area.objects.filter(parent_id = 130000)

area_hebei = Area.objects.get(id = 130000) 河北省
area_hebei.subs.all() 河北省所有的市

select * from tb_areas where parent_id=130200; # 区县
------ 本文结束------

欢迎关注我的其它发布渠道