这个问题可能与做大量的事情有关,但在这种情况下,我正在尝试发送电子邮件。
我已在新线程中设置发送过程,因此用户不会等待,并将请求超时重写为一小时。
问题在于,一旦进程发送了大约2000封电子邮件(通过以下代码循环约2000次),服务器就会耗尽内存,停止响应并需要重新启动。
阅读其他主题,CF应该能够很好地处理这一批电子邮件。
我考虑过的一件事是将所有对象调用更改为直接数据库查询并使用cfmail标记(我猜)删除所有对象的创建并在达到请求时构建(我猜是正在发生的事情),但是我不确定这是否会产生影响,并且如果可能的话,我真的想避免这种做法。我考虑的其他东西是将它分成3个或4个单独的线程,但同样,不确定这是否能解决问题。
有没有人遇到过这个问题,你发现什么能让处理继续进行而没有ram慢慢填满并杀死服务器?
thread name="sendBroadcastEmail" rc="#rc#" prc="#prc#" filters="#rc.filters#" email="#email#" emailSignature="#emailSignature#"{
createObject( "java", "coldfusion.tagext.lang.SettingTag" ).setRequestTimeout(javaCast( "double", 3600 ));
//get profiles that it will be sent to
var sendToProfiles = profileService.getWithFilters(rc.filters);
var mailService = getPlugin("MailService");
var emailSent = false;
var sentCount = 0;
var failedCount = 0;
//send the email (and log in profile events)
if (listFind(attributes.rc.email.action,'send')){
for ( i=1; i<=arrayLen(sendToProfiles);i++){
var profile = sendToProfiles[i];
try{
if (len(trim(profile.getPrimaryEmail()))){
var emailBody = profile.processDynamicPlaceholders(attributes.rc.email.body);
var emailBody = attributes.emailSignature.getHeader() & emailBody & attributes.emailSignature.getFooter();
var sendEmail = mailService.newMail(
from = attributes.emailSignature.getEmailAddress(),
//to = profile.getPrimaryEmail(),
to = Application.settings.testemail,
subject = attributes.rc.email.subject,
body = emailBody,
type="html");
sendEmail.addMailParam(disposition='attachment', file=attributes.email.getAttachmentWithPath());
mailService.send(sendEmail);
//log profile event
profile.saveEvent(eventType = 3,
title="Broadcast Email: #attributes.rc.email.subject#",
description="Broadcast Email Sent: Subject: <br> #attributes.rc.email.subject#",
sentContent=emailBody,
ref2=1);
sentCount++;
}
}
catch (any exception){
//log profile event
profile.saveEvent(eventType = 3,
title="FAILED Broadcast Email",
description="<br>Subject: #attributes.email.subject#<br>This email should have been sent to this profile, but the attempted send failed. The likely cause is a malformed email address.",
sentContent=emailBody,
ref2=0);
failedCount++;
}
}
emailSent = true;
}
//persist email object
if (listFind(attributes.rc.email.action,'save')){
email.setTstamp(attributes.prc.now);
email.setSent(emailSent);
email.setStatsSent(sentCount);
email.save();
}
}//end thread
答案 0 :(得分:3)
一种方法是以定时批量生成电子邮件以均匀分布负载。批次之间的批量大小和延迟可以根据您的环境进行调整。
thread name="sendBroadcastEmail" rc="#rc#" prc="#prc#" filters="#rc.filters#" email="#email#" emailSignature="#emailSignature#"{
createObject( "java", "coldfusion.tagext.lang.SettingTag" ).setRequestTimeout(javaCast( "double", 3600 ));
// set thread to a lowish prority
var currentThread = CreateObject( "java","java.lang.Thread" ).currentThread();
var priority = currentThread.getPriority();
currentThread.setPriority( 3 );
//get profiles that it will be sent to
var sendToProfiles = profileService.getWithFilters(rc.filters);
var mailService = getPlugin("MailService");
var emailSent = false;
var sentCount = 0;
var failedCount = 0;
//send the email (and log in profile events)
if (listFind(attributes.rc.email.action,'send')){
var emailsPerBatch = 1000; // divide into batches, set size here
var batchcount = Ceiling( ArrayLen( sendToProfiles ) / emailsPerBatch ); // number of batches
var batchdelay = 120000; // set delay between batches (ms)
// initialise first batch
var firstitem = 1;
var lastitem = emailsPerBatch;
for( var batch=1; batch<=batchcount; batch++ ) {
if( batch > 1 ){
// delay sending next batch and give way to other threads
currentThread.yield();
currentThread.sleep( batchdelay );
}
for ( var i=firstitem; i<=lastitem;i++ ){
var profile = sendToProfiles[i];
// generate emails ...
}
// initialise next batch
firstitem = lastitem++;
lastitem += emailsPerBatch;
if( lastitem > ArrayLen( sendToProfiles ) ) {
// last batch
lastitem = ArrayLen( sendToProfiles );
}
}
emailSent = true;
}
currentThread.setPriority( priority ); // reset thread priority
}//end thread