在写运维工单的消息推送时,直接使用邮件发送会致使系统反应特别慢,因此研究了一下rabbitmq+celery来实现邮件发送的异步执行html
部署rabbitmqpython
RabbitMQ是基于Erlang的,因此首先必须配置Erlang环境。数据库
从Erlang的官网 http://www.erlang.org/download.html 下载最新的erlang安装包,我下载的版本是 otp_src_R15B01.tar.gz。django
tar xvzf otp_src_R15B01.tar.gz cd otp_src_R14B03 ./configure make make install
安装完Erlang,开始安装RabbitMQ-Server。json
主要参考官方文档:http://www.rabbitmq.com/build-server.htmlbash
须要安装一个比较新的Python版本。安装略。app
'''运维
这一步我没有作,安装也没收到影响,在此仅是记载异步
须要安装simplejson。今后处下载最新的版本: http://pypi.python.org/pypi/simplejson#downloads 。我下载的版本是 simplejson-2.2.1.tar.gzide
$ tar xvzf simplejson-2.2.1.tar.gz $ cd simplejson-2.2.1 $ sudo python setup.py install
''''
而后安装RabbitMQ Server。今后处下载源代码版本的RabbitMQ: http://www.rabbitmq.com/server.html。我下载的版本是 rabbitmq_server-3.5.4.tar.gz
$ tar xvzf rabbitmq_server-3.5.4.tar.gz $ cd rabbitmq_server-3.5.4 $ make # TARGET_DIR=/usr/local SBIN_DIR=/usr/local/sbin MAN_DIR=/usr/local/man make install
在sbin/目录下出现了三个命令:
rabbitmqctl rabbitmq-env rabbitmq-server
安装成功。
运行
找到sbin/目录,运行程序:
/usr/local/sbin/rabbitmq-server –detached
中止程序:
/usr/local/sbin/rabbitmqctl stop
在settings.py中加入rabbitmq配置:
BROKER_HOST = "127.0.0.1" BROKER_PORT = 5672 BROKER_USER = "guest" BROKER_PASSWORD = "guest" BROKER_VHOST = "/"
'''如下为参考资料'''
配置
主要参考官方文档:http://www.rabbitmq.com/configure.html
通常状况下,RabbitMQ的默认配置就足够了。若是但愿特殊设置的话,有两个途径:
一个是环境变量的配置文件 rabbitmq-env.conf ;
一个是配置信息的配置文件 rabbitmq.config;
注意,这两个文件默认是没有的,若是须要必须本身建立。
rabbitmq-env.conf
这个文件的位置是肯定和不能改变的,位于:/etc/rabbitmq目录下(这个目录须要本身建立)。
文件的内容包括了RabbitMQ的一些环境变量,经常使用的有:
#RABBITMQ_NODE_PORT= //端口号
#HOSTNAME=
RABBITMQ_NODENAME=mq
RABBITMQ_CONFIG_FILE= //配置文件的路径
RABBITMQ_MNESIA_BASE=/rabbitmq/data //须要使用的MNESIA数据库的路径
RABBITMQ_LOG_BASE=/rabbitmq/log //log的路径
RABBITMQ_PLUGINS_DIR=/rabbitmq/plugins //插件的路径
具体的列表见:http://www.rabbitmq.com/configure.html#define-environment-variables
rabbitmq.config
这是一个标准的erlang配置文件。它必须符合erlang配置文件的标准。
它既有默认的目录,也能够在rabbitmq-env.conf文件中配置。
文件的内容详见:http://www.rabbitmq.com/configure.html#config-items
部署celery
直接执行
pip install django-celery
在settings.py中加入如下配置
import djcelery djcelery.setup_loader() ... INSTALLED_APPS = ( ... 'djcelery', ... )
最后建立Celery所需的数据表, 若是使用South做为数据迁移工具, 则运行:
python manage.py migrate
不然运行: (Django 1.6或Django 1.7均可以)
python manage.py syncdb
到此django+rabbitmq+celery的环境就部署完了,下面是邮件发送的代码,这里是用的django自带的邮件发送功能
在settings.py中加入邮件发送配置:
EMAIL_HOST='outlook.office365.com' EMAIL_HOST_USER='**@**.com' EMAIL_HOST_PASSWORD='***' EMAIL_USE_TLS = True
建立一个新py文件,命名为tasks.py
from celery.task import Task from celery import task from workflow import models from django.core.mail import EmailMessage from django.template import loader from worksystem.settings import EMAIL_HOST_USER @task() def send_email(subject, content, to_name_list): html_content = loader.render_to_string( 'sendmail.html', #须要渲染的html模板 { 'content':content } ) msg = EmailMessage(subject, html_content, EMAIL_HOST_USER, to_name_list) msg.content_subtype = "html" # Main content is now text/html msg.send()
sendmail.html模版:
<!DOCTYPE html> <html lang="en"> <h>您好,您有新工单消息提醒,详情请点击 http://**.**.com/</h> <table class="cellspacing="1px" style="width: 50%; border: 1px outset rgb(128, 128, 128); border-spacing: 1px;""> <thead> <tr> <th style="border:1px #808080 inset;padding:1px;">列名</th> <th style="border:1px #808080 inset;padding:1px;">相应值</th> </tr> </thead> <tbody> {% for item in content %} <tr> <th style="border:1px #808080 inset;padding:1px;">主键ID</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.id }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">工单名称</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.title }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">申请人</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.creator }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">工单类型</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.type }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">建立时间</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.create_time|date:"Y-m-d H:i:s" }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">审批人</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.approveuser }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">描述</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.description }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">处理人</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.deal_user }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">运帷回复</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.opsreply }}</th> </tr> <tr> <th style="border:1px #808080 inset;padding:1px;">状态</th> <th style="border:1px #808080 inset;padding:1px;">{{ item.state }}</th> </tr> {% endfor %} </tbody> </table> </html>