java群发上万条短信解决方案,请各位xdjm赐教,给分不是问题,万分感谢

zzlglgogo124 2011-02-12 12:57:27
最近公司有一个短信群发的问题,api是第三方提供商,我们只是开发web层,碰到一个题,群发500,600条不是万问题,上千到上万就发不出去,下面有个方法,
请教一下csdn的xdjm们,牛人们,看商量有什么解决。。。非常感谢,给多少分没问题!
出错日志:
java.lang.Exception: SMS Message Model is incomplete. Can not initialize object.
at sms.util.SMSMessagesModel.<init>(SMSMessagesModel.java:25)
at com.oas.service.impl.SMSGroupServiceImpl.sendGroupMessage(SMSGroupServiceImpl.java:48)
at com.oas.service.impl.SMSGroupServiceImpl.initializeSendingSMS(SMSGroupServiceImpl.java:194)

主要发送短信方法:

public String sendGroupMessage(String searchType, Timestamp startDate, Timestamp endDate,
String[] priorityLevel, String[] customerLevel, String smsType, String message) throws CrownOASException {
try {
List<SMSMessagesModel> smsMessagesModels = new ArrayList<SMSMessagesModel>();

List<SMSPartialModel> smsPartialModels = smsDao.getListOfRecipients(searchType, startDate, endDate, priorityLevel, customerLevel, smsType);

for(SMSPartialModel smsPartialModel : smsPartialModels) {
SMSMessagesModel smsMessageModel = new SMSMessagesModel (Constants.PRODUCT_CODE,smsPartialModel.getLoginname(),smsPartialModel.getPhone(),smsPartialModel.getPermission(),smsType,message,"");
smsMessagesModels.add(smsMessageModel);
}

SMSSender sms = new SMSSender(Constants.SMS_URL);
List<SMSMessagesModel> k = sms.sendByBatchWithTimeDelay(smsMessagesModels, 10, 5000, Constants.GB);

if(k != null){
for(SMSMessagesModel j : k) {
System.out.println("Output Log: " + j.getPhone() + " | " + j.getResponseCode());
}
}
} catch (Exception e) {
e.printStackTrace();
}

return "success";
}


我想是不是SMSMessagesModel smsMessageModel = new SMSMessagesModel ()这个发送短信对象有问题,如果有上千条new就不行,不知道各位大侠有什么好的解决方案,谢谢!
...全文
526 点赞 收藏 32
写回复
32 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zzlglgogo124 2011-02-18
有一个星级组客户是5,6千,不是5,6千万。。。
回复
zzlglgogo124 2011-02-18
我做了如下修改,每批发送500条,有一个星级组客户有5-6千万,有一个星级客户有900条反而发不出,有一个有一万多也发出,用的同一道代码,不知道为什么。。。各位CSDN的XDJM们帮忙一下,万分感谢!
错误日志还是以前一样?
-Hibernate: SELECT C.LOGINNAME loginname, C.PHONE phone, 'Y' permission FROM customers C LEFT JOIN smssubscription S ON C.LOGINNAME = S.LOGINNAME WHERE C.PHONE IS NOT NULL AND (UPPER(S.regards) != 'N' OR S.regards IS NULL) AND C.level IN (?)
java.lang.Exception: SMS Message Model is incomplete. Can not initialize object.
at sms.util.SMSMessagesModel.<init>(SMSMessagesModel.java:25)
at com.oas.service.impl.SMSGroupServiceImpl.sendGroupMessage(SMSGroupServiceImpl.java:58)
at com.oas.service.impl.SMSGroupServiceImpl.initializeSendingSMS(SMSGroupServiceImpl.java:253)
public String sendGroupMessage(String searchType, Timestamp startDate, Timestamp endDate,
String[] priorityLevel, String[] customerLevel, String smsType, String message) throws CrownOASException {
try {
List<SMSMessagesModel> smsMessagesModels = new ArrayList<SMSMessagesModel>();

//ASSUMPTION: no loginnames provided from the user
List<SMSPartialModel> smsPartialModels = smsDao.getListOfRecipients(searchType, startDate, endDate, priorityLevel, customerLevel, smsType);

int total=smsPartialModels.size();
int num=total/Constants.SMS_GROUP_SIZE;
int count=0;
int smscount=0;
for(SMSPartialModel smsPartialModel : smsPartialModels) {
smscount++;
if(total>=Constants.SMS_GROUP_SIZE){
SMSMessagesModel smsMessageModel = new SMSMessagesModel(Constants.PRODUCT_CODE,
smsPartialModel.getLoginname(),
smsPartialModel.getPhone(),
smsPartialModel.getPermission(),
smsType,
message,
"");
count++;
smsMessagesModels.add(smsMessageModel);
if(count==Constants.SMS_GROUP_SIZE){
count=0;
sendSMS500(smsMessagesModels);
smsMessagesModels.clear();
}else if(total-smscount<Constants.SMS_GROUP_SIZE&&smscount==total){
sendSMS500(smsMessagesModels);
smsMessagesModels.clear();
}
}else{

SMSMessagesModel smsMessageModel = new SMSMessagesModel(Constants.PRODUCT_CODE,
smsPartialModel.getLoginname(),
smsPartialModel.getPhone(),
smsPartialModel.getPermission(),
smsType,
message,
"");
count++;
smsMessagesModels.add(smsMessageModel);
if(count==total){
sendSMS500(smsMessagesModels);
smsMessagesModels.clear();
}


}

}


/*SMSSender sms = new SMSSender(Constants.SMS_URL);
List<SMSMessagesModel> k = sms.sendByBatchWithTimeDelay(smsMessagesModels, 10, 5000, Constants.GB);

if(k != null){
for(SMSMessagesModel j : k) {
System.out.println("Output Log: " + j.getPhone() + " | " + j.getResponseCode());
}
}*/

} catch (Exception e) {
e.printStackTrace();
}

return "success";
}

public void sendSMS500(List smsMessagesModels){
SMSSender sms;
try {
sms = new SMSSender(Constants.SMS_URL);
List<SMSMessagesModel> k = sms.sendByBatchWithTimeDelay(smsMessagesModels, 10, 5000, Constants.GB);

if(k != null){
for(SMSMessagesModel j : k) {
System.out.println("Output Log: " + j.getPhone() + " | " + j.getResponseCode());
}
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
回复
wshcdr 2011-02-18
分批分送
回复
hown 2011-02-18
想当年。我去面试的时候也是面临这个问题。
回复
[Quote=引用 24 楼 xihuanni0509 的回复:]
引用 19 楼 zzlglgogo124 的回复:
17楼说得正是,是选择了一个类型。正是这种情况(则首先要决断要发送多少个用户。如果用户数据太大,则把所有的用户查出来放到集合里把集合进行拆分分组发送。)
用多线程处理效率更高(一组一个线程,看情况来定)。这个情况怎么处理,我那个方法有什么改进,请各位牛人指导一下,谢谢!

支持
[/Quote]

这个比较好!
回复
li463968565 2011-02-18
[Quote=引用 28 楼 dada_fangfang 的回复:]
虽然26楼的代码,已经比原先的好了很多,但是还是存在浪费内存的情况。

首先,你一次性取出所有的短信记录放在内存,再对内存进行分批操作,如果你的短信数据量很大,你能保证你的内存不爆掉吗,即使不爆掉,内存的速度也慢上好几倍。

其次,为什么不写一个线程类,你可以通过构造函数,传入你的短信发送条件,线程的run方法增加一个执行标识,例如线程的run根据你传入的条件,修改执行标识(线程启动),每……
[/Quote]

学习了,最近在自学线程,都是写些简单的,有什么好的例子?给个思路,万分感谢~~
回复
dada_fangfang 2011-02-18
虽然26楼的代码,已经比原先的好了很多,但是还是存在浪费内存的情况。

首先,你一次性取出所有的短信记录放在内存,再对内存进行分批操作,如果你的短信数据量很大,你能保证你的内存不爆掉吗,即使不爆掉,内存的速度也慢上好几倍。

其次,为什么不写一个线程类,你可以通过构造函数,传入你的短信发送条件,线程的run方法增加一个执行标识,例如线程的run根据你传入的条件,修改执行标识(线程启动),每次读取300,发完后继续读,整个批次的短信发完后,通过设置执行标识退出线程(线程停止)。
这样不是很清晰吗?

不要问别人要代码!我们只能提供思路。不写代码的程序员。有什么用?
回复
xihuanni0509 2011-02-16
[Quote=引用 19 楼 zzlglgogo124 的回复:]
17楼说得正是,是选择了一个类型。正是这种情况(则首先要决断要发送多少个用户。如果用户数据太大,则把所有的用户查出来放到集合里把集合进行拆分分组发送。)
用多线程处理效率更高(一组一个线程,看情况来定)。这个情况怎么处理,我那个方法有什么改进,请各位牛人指导一下,谢谢!
[/Quote]
支持
回复
hanmiit 2011-02-16
看来还是要分批发
回复
liuyuhua0066 2011-02-16
你一次发500条,中间线程休息片刻,再重复执行发送。
回复
Allan01 2011-02-16
can you try to modify like this: (refer to Prototype pattern)

for(SMSPartialModel smsPartialModel : smsPartialModels) {
SMSMessagesModel smsMessageModel = new SMSMessagesModel (Constants.PRODUCT_CODE,smsPartialModel.getLoginname(),smsPartialModel.getPhone(),smsPartialModel.getPermission(),smsType,message,"");
smsMessagesModels.add(smsMessageModel);
}

--->

SMSMessagesModel sModel = new SMSMessagesModel();
for(SMSPartialModel smsPartialModel : smsPartialModels) {
SMSMessagesModel smsMessageModel = (SMSMessagesModel)sModel.colone();
// set all parameters through setters, rather than creating from constructor.
smsMessageModel.setXXX();
smsMessageModel.setYYY();
//.....

smsMessagesModels.add(smsMessageModel);
}
回复
mopishv0 2011-02-15
WEB前端收集请求 把请求都存到数据库
然后写个线程 取数据库数据 发送短信 每次发几百条
如果前端需要发送进度 用AJAX做个进度条就行了
回复
zzlglgogo124 2011-02-15
17楼说得正是,是选择了一个类型。正是这种情况(则首先要决断要发送多少个用户。如果用户数据太大,则把所有的用户查出来放到集合里把集合进行拆分分组发送。)
用多线程处理效率更高(一组一个线程,看情况来定)。这个情况怎么处理,我那个方法有什么改进,请各位牛人指导一下,谢谢!
回复
lebut2012 2011-02-14
public String sendGroupMessage(String searchType, Timestamp startDate, Timestamp endDate,
String[] priorityLevel, String[] customerLevel, String smsType, String message) throws CrownOASException {
try {
List<SMSMessagesModel> smsMessagesModels = new ArrayList<SMSMessagesModel>();

List<SMSPartialModel> smsPartialModels = smsDao.getListOfRecipients(searchType, startDate, endDate, priorityLevel, customerLevel, smsType);

for(SMSPartialModel smsPartialModel : smsPartialModels) {
SMSMessagesModel smsMessageModel = new SMSMessagesModel (Constants.PRODUCT_CODE,smsPartialModel.getLoginname(),smsPartialModel.getPhone(),smsPartialModel.getPermission(),smsType,message,"");
smsMessagesModels.add(smsMessageModel);
}

SMSSender sms = new SMSSender(Constants.SMS_URL);
List<SMSMessagesModel> k = sms.sendByBatchWithTimeDelay(smsMessagesModels, 10, 5000, Constants.GB);

if(k != null){
for(SMSMessagesModel j : k) {
System.out.println("Output Log: " + j.getPhone() + " | " + j.getResponseCode());
}
}
} catch (Exception e) {
e.printStackTrace();
}

return "success";
}

回复
暗然的白天 2011-02-14
额、曾经做过一个一次发送上万封邮件的。你只是调用的是短信服务平台的接口,按照它的接口规范传数据,发短信还是短信平台的事,所以
首先你要弄明白发送短信的服务器有几个、怎么发的。如果有多台服务器的话是不是一个链接过去它会自动识别哪台闲置而自动链接哪台。这样的话你大量的短信可以分几次链接比较好。一次链接发多少条短信。不要把上万条短信用一个链接到一台短信服务器上处理。因为大量的短信在短信服务器上也需要排队。效率不高。
你还要知道创建一个发送短信的对象可以发送几条短信。难道一个发送对象只能发送一个?如果不是一个则取多少个合适?
如果客户选择了一个类型。则首先要决断要发送多少个用户。如果用户数据太大,则把所有的用户查出来放到集合里把集合进行拆分分组发送。可以一组创建一个链接,一个发送对象发送十个(这些看情况自己来定)。
用多线程处理效率更高(一组一个线程,看情况来定)。
你也可以问问短信平台那边有没有群发接口,如果有最多一次支持多少个用户,可以综合上面所说的调用群发接口来实现更好。如果没有或者不能调用的话也就算了。
说了这么多不知道对你有用没有,批量处理确实不太好弄。有了更好,没有的话也对不住了。祝你好运呀~
回复
四川民工甲 2011-02-14
生产:
每次读取一定数量的SMSMessagesModel ,即一个批次。
消费:
发送一个批次的短信
回复
greatmind829 2011-02-12
后台用线程来控制发送的数量。
回复
zzlglgogo124 2011-02-12
怎么分批发送?
回复
zzlglgogo124 2011-02-12
假设我有10000个1星级客户,在前台点选这个一星级,点击发送短信,每次发送600条怎么发送?
回复
zzlglgogo124 2011-02-12
除了数据库之外,如果全部取出来之后,在发送这端在程序这端怎么控制分批发送?
回复
加载更多回复
相关推荐
发帖
Web 开发
创建于2007-09-28

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2011-02-12 12:57
社区公告
暂无公告