在网络服务器运行的时候,可能会碰到这样的需求,主程序处理会很耗时,
1,网络流量很大,但有紧急情况需要发送邮件通知别人,这时如果在程序中发送邮件,将会很费时,
但又必须做
2,处理客户端请求后,剩下的事情跟正常逻辑没有关系,但有些耗时的操作需要完成
遇到这样的情况,可以有几种办法:
1,开一个线程跑这些数据,主程序继续处理其他的任务
2,用redis阻塞队列,将消息传到队列中,其他的事情由别的程序来重redis中读取队列中的消息,
并进行处理
1,开一个线程处理:
如果这样的操作很多的话,对程序影响很大的,因为每次涉及到线程资源的申请和销毁,这些都
要占用一些主程序时间,并且这样破坏了主要逻辑的流程
2,用redis的阻塞队列实现:
先说一下环境:处理客户端请求用php,处理redis的消息队列用python脚本
实现方法:由php向redis中写人的队列写入消息,由python脚本读redis中的队列中的消息,可能
有朋友会考虑说让python这样一直跑不也占系统资源吗,但redis中有一个阻塞队列,
使用该方法,当python读取队列 的时候,如果为空,则阻塞,如果有消息,则唤醒并
执行,效果很好
补充:
redis中,python调用的一个方法为blpop(key, timeout)
当把timeout致为0时表示永久不超时,这样的话,这个python进程就是类似一个监听进程,
当有消息的时候他就努力工作,没有的时候就看着
示例代码:
#! /usr/bin/python
#-*- coding:utf-8 -*-
#Filename: hh.py
#Author: xiaobing
#E-mail: [email protected]
#Date: 2013-11-26
#Description:
import redis
import sendgrid
class Sendmess():
def __init__(self):
self.redis = redis.Redis(host= 'localhost', port=6739, password = 'ps', db= 0)
self.queue = 'messagequeue'
def sendmess(self):
"""接收消息message,并发送邮件
邮件信息格式:
message形式为:
to=mailaddr&title=mailtitle&plainContent=plaincontent&htmlContent=htmlcontent
"""
while True:
mess = self.redis.blpop(self.queque, 0)[1]
params = {}
params = {'plainContent':'', 'htmlContent':''}
for item in maillist:
temlist = item.split('=')
params[temlist[0]] = temlist[1]
#print params
self.sendEmail(title = params['title'], mail_list = [params['to']], \
plainContent = params['plainContent'], htmlContent = params['htmlContent'])
def sendEmail(mail_list, title, plainContent = '', htmlContent = ''):
"""发送邮件
@params mail_list 接收人邮件列表
@params title 发送邮件的标题
@params plainContent普通内容文本
@params htmlContent html内容文本
notice:
plainContent 和 htmlContent同时存在时,只发送htmlContent
"""
s = sendgrid.Sendgrid('user', 'password', secure = True)
message = sendgrid.Message('[email protected]', title, plainContent, htmlContent)
message.add_to(mail_list)
s.smtp.send(message)
if __name__ == '__mail__':
sendmess = Sendmess()
sendmess.sendmess()