why
开发需求:
- 现有平台用户管理系统,注册用户后,同步用户信息到gitlab。
- 同步信息执行完成后,邮件发送通知注册用户。
what
思路:
- 使用python-gitlab 模块来调用gitlab的API来管理用户注册。
- 使用celery将发送邮件的任务转成异步执行,无需用户等待。使用redis作为队列,将异步任务进行缓存。不影响服务器主进程。
when
准备好了再干活!
貌似redius和celery有版本兼容问题,最好使用以下版本避免入坑。
环境:
$ pip install redis==2.7.0#安装python-redis
$ pip install celery==3.1.26#安装celery
$ python --version
Python 3.6.4
$ pip list
Package Version
------------------------- ------------
celery 3.1.26.post2
Django 2.0
python-gitlab 1.8.0
redis 2.7.0
$ wget http://59.80.44.98/download.redis.io/releases/redis-2.6.14.tar.gz#下载redis
$ tar xvf redis-2.6.14.tar.gz && cd redis-2.6.14 && make
$ src/redis-server #启动redis
HOW
gitlab用户同步
- 根据vue前端用户注册的返回,在序列化类中使用python-gitlab同步用户信息。
- 配置gitlab服务器settings,增加gitlab服务器信息
projects\settings.py:
GITLAB_TOKEN = 'token'
GITLAB_URL = 'http://gitlabserver/'
- 注册用户默认调用序列化类中的create方法,重写create调用create_gitlab,创建一个create_gitlab。
project\apps\users\serializer.py:
def create_gitlab(self, validated_data):
gl = gitlab.Gitlab(settings.GITLAB_URL, settings.GITLAB_TOKEN)
gl.users.create(validated_data)
celery+redis异步发送邮件
- \projects\settings.py增加如下配置:
#Celery settings
BROKER_URL = 'redis://localhost:6379/0'
BROKER_TRANSPORT = 'redis'
#email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
#每个邮箱都有不同的服务器 163邮箱为smtp.163.com,这是使用qq邮箱为smtp.qq.com
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 25
#发送源即发送邮件的邮箱
EMAIL_HOST_USER = 'xx@xx.com'
#在邮箱中设置的客户端授权密码
#如果是aliyun邮箱这个是你账号的密码,如果是163/126邮箱或qq邮箱这个是授权码,
#163/126的授权码会在你开通SMTP服务时自行设置,qq邮箱会分配一个授权码。
EMAIL_HOST_PASSWORD = 'xxxxxxxxxx'
EMAIL_FROM = EMAIL_HOST_USER
- 创建 \projects\celery.py:
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'devops.settings')
app = Celery('devops')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
- 在apps的目录创建tasks:
from django.conf import settings
from django.core.mail import send_mail
from devops.celery import app
@app.task
def send_msg(email, title, content):
# send_mail的第一个参数为:主标题;
# 第二个参数为:文本内容;
# 第三个参数为发送源邮箱;
# 第四个参数为一个列表或元组表示要发送给哪个邮箱可以是多个;
# 第五个参数为:可以将html标签翻译如a标签中如果有href属性他的内容就可以被点击。
# 注意:第二个参数和第五个参数不能同时存在,如果同时存在第五个参数会覆盖掉第二个参数中的内容。
# send_mail(
# "标题", "不能够翻译html标签的内容",
# settings.EMAIL_HOST_USER, (email,),
# html_message="<a href='127.0.0.1/index/'>html_message这是一个能够翻译html标签的内容</a>"
# )
print('正在发送')
send_mail(
title,
content,
settings.EMAIL_HOST_USER,
[email],
fail_silently=False)
print('发送成功')```
- 在views中调用send_msg:
from .tasks import send_msg
class UserInfoViewset(viewsets.ViewSet):
send_msg.delay(email='xx@xx.com', title='test', content='成功了!!')
permission_classes = (permissions.IsAuthenticated,)
def list(self, request, *args, **kwargs):
data = {
"username": "admin",
"name": "admin"
}
return response.Response(data)
- 先运行django,然后运行redius,最后运行celery:
$python mannger runserver 0:8000#django项目目录执行
$src/redis-server#redis目录执行
$celery -A projectn_ame worker -l debug#django项目目录执行
成功后celery有如下打印:
[2019-04-16 15:04:36,010: INFO/MainProcess] Received task: users.tasks.send_msg[a1503a63-71ae-423d-a686-c821db568912]
[2019-04-16 15:04:36,011: DEBUG/MainProcess] TaskPool: Apply <function _fast_trace_task at 0x7f4ec88fc840> (args:('users.tasks.send_msg', 'a1503a63-71ae-423d-a686-c821db568912', [], {'email': 'xxxxx@qq.com', 'title': 'test', 'content': '成功了!!'}, {'task': 'users.tasks.send_msg', 'id': 'a1503a63-71ae-423d-a686-c821db568912', 'args': [], 'kwargs': {'email': 'xxxx@qq.com', 'title': 'test', 'content': '成功了!!'}, 'retries': 0, 'eta': None, 'expires': None, 'utc': True, 'callbacks': None, 'errbacks': None, 'timelimit': (None, None), 'taskset': None, 'chord': None, 'headers': {}, 'reply_to': 'e7f89e7c-1949-368c-ab43-9913b6153c16', 'correlation_id': 'a1503a63-71ae-423d-a686-c821db568912', 'delivery_info': {'exchange': 'celery', 'routing_key': 'celery', 'priority': 0, 'redelivered': None}, 'hostname': 'celery@localhost', 'is_eager': False, 'group': None}) kwargs:{})
[2019-04-16 15:04:36,012: WARNING/Worker-1] 正在发送
[2019-04-16 15:04:36,013: DEBUG/MainProcess] Task accepted: users.tasks.send_msg[a1503a63-71ae-423d-a686-c821db568912] pid:6859
[2019-04-16 15:04:36,014: INFO/MainProcess] Received task: users.tasks.send_msg[5d8eefe1-9ad2-4136-96f7-afe2e2aca18c]
[2019-04-16 15:04:36,018: INFO/MainProcess] Received task: users.tasks.send_msg[8ed3722a-a210-4865-9e52-1bfd11e3cb61]
[2019-04-16 15:04:37,114: WARNING/Worker-1] 发送成功```