这样的业务逻辑设计是否合理?

yzflying 2019-04-04 08:18:03
表A是待发短信数据表(每秒大概新增30条短信记录),有10个短信发送通道(由COM+接口提供)

现在要求:及时将表A中短信发送出去,10个通道轮流发送,发送成功后删除表A中对应的记录。


业务逻辑设计:

WINFORM 每秒 SELECT 表A一次,取出记录循环发送,送给10个通道中发送数最少的通道,完成发送。

总感觉这样发送效率不高,10个通道没有完全利用起来,每秒SELECT表一次效率低。


于是又想到另外一个设计:

WINFROM 开启10个线程,每个线程每秒一次去表中 SELECT记录、发送、删除,但又害怕10个线程会SELECT到同一条记录造成冲突。


有什么更好的业务逻辑吗?

...全文
2693 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_15826817 2019-04-08
  • 打赏
  • 举报
回复
设计思路也许一开始就是错的,这种快速大量产生的短信信息,应该源头一产生就直接放到MQ队列中去,然后客户端程序只要负责从队列中取内容来执行就完了,逻辑简单明了。而不应该放到数据库表中去然后对外开放webservice接口让外部访问。用了webservice,看来是只能定时轮询了,想不到好的办法。
yzflying 2019-04-07
  • 打赏
  • 举报
回复
引用 11 楼 qq_15826817 的回复:
[quote=引用 8 楼 yzflying 的回复:]
[quote=引用 4 楼 qq_15826817 的回复:]
用队列的思想,串行化处理,思路如下:
1、创建一个发送信息队列(用ConcurrentQueue,线程安全队列来做),每添加成功一条数据库记录,那么就将发送信息添加到该队列。保存的信息主要两个数据库记录自增ID或者主键(用于一会的删除数据库记录用),短信的内容。
2、创建10个线程,每个线程干的事如下:
1)从队列中取发送信息,执行发送动作,如果发送成功那么,将发送信息中的自增ID或者主键 保存到删除队列,然后继续取从队列中取信息。
3、创建一个线程,专门检查删除队列,如果队列有内容,那么就取出来。然后删除数据库记录。


WINFORM怎么知道数据库添加了记录?用SqlDependency?
[/quote]

数据库添加不是你的程序负责的?那就先遍历数据库表把所有记录取出来,通过10个通道按照上面的方法,全部发送完后再次取记录,一直循环[/quote]


数据库记录来自于对外提供的一个WEBSERVICES。
我的意思:数据库的记录如何及时快速的进入队列?传统的办法要用while(true)或者 定时器(每秒访问一次数据库) 不停的访问对应的表取出数据加入队列,才能保证到达表的数据迅速加入队列,有没有更好的办法。
阿卡林123 2019-04-07
  • 打赏
  • 举报
回复
应该合理吧,,,,,,,,,,,
qq_15826817 2019-04-06
  • 打赏
  • 举报
回复
用了MQ还可以使用消息必达服务,取了记录立马把记录从数据库中删除
qq_15826817 2019-04-06
  • 打赏
  • 举报
回复
多个程序放多个电脑确实可以,灵活扩展性稍候欠缺,比如数据库IP改了,每个程序都要重新布暑。我的思想是一个程序专门负责统一的任务分发,一个程序负责专门的任务处理(可以布暑在同多台电脑上),尽量的解耦。数据库IP如果改了,只要修改负责任务分发的程序即可。
LH135123 2019-04-06
  • 打赏
  • 举报
回复
多个程序放多个电脑不就完了
qq_15826817 2019-04-05
  • 打赏
  • 举报
回复
不知道你的处理速度如何,一秒增加30条记录,10个线程在1s内估计是发不完。如果速度跟 不上,数据库的记录只会越来越多。 这个时候你要考虑增加处理的程序,可以把处理程序放在分布式的不同电脑。一台电脑处理不完,多台总可以了吧。这个需要增加硬件投入。需要用到的技术是MQ,把任务推送到不同的客户端程序,让他们来统一处理。最麻烦的地方是处理完还要删除数据库记录,传统的数据库频繁的删除性能估计会有问题,建议用内存数据库比如redis来做
qq_15826817 2019-04-05
  • 打赏
  • 举报
回复
需要再加一个协调线程,这个线程做的事如下: 1、取出所有记录,放到发送队列。 2、等10个处理线程处理完所有记录,并且数据库记录全部删除完,再重复第1步。 只是说个大概,一些细节需要你自己 处理
qq_15826817 2019-04-05
  • 打赏
  • 举报
回复
引用 8 楼 yzflying 的回复:
[quote=引用 4 楼 qq_15826817 的回复:] 用队列的思想,串行化处理,思路如下: 1、创建一个发送信息队列(用ConcurrentQueue,线程安全队列来做),每添加成功一条数据库记录,那么就将发送信息添加到该队列。保存的信息主要两个数据库记录自增ID或者主键(用于一会的删除数据库记录用),短信的内容。 2、创建10个线程,每个线程干的事如下: 1)从队列中取发送信息,执行发送动作,如果发送成功那么,将发送信息中的自增ID或者主键 保存到删除队列,然后继续取从队列中取信息。 3、创建一个线程,专门检查删除队列,如果队列有内容,那么就取出来。然后删除数据库记录。
WINFORM怎么知道数据库添加了记录?用SqlDependency? [/quote] 数据库添加不是你的程序负责的?那就先遍历数据库表把所有记录取出来,通过10个通道按照上面的方法,全部发送完后再次取记录,一直循环
luj_1768 2019-04-05
  • 打赏
  • 举报
回复
应该是这样的:1. 建立com 端口集成线程池,统一管理和操作端口;2. 建立设备缓冲(可能要几十个G,因为速度差有些大);3. 写主进程代码(就是不停的往缓冲区写数据)。
❁小…鱼❁ 2019-04-05
  • 打赏
  • 举报
回复
。。。。。。。。。。
yzflying 2019-04-05
  • 打赏
  • 举报
回复
引用 4 楼 qq_15826817 的回复:
用队列的思想,串行化处理,思路如下:
1、创建一个发送信息队列(用ConcurrentQueue,线程安全队列来做),每添加成功一条数据库记录,那么就将发送信息添加到该队列。保存的信息主要两个数据库记录自增ID或者主键(用于一会的删除数据库记录用),短信的内容。
2、创建10个线程,每个线程干的事如下:
1)从队列中取发送信息,执行发送动作,如果发送成功那么,将发送信息中的自增ID或者主键 保存到删除队列,然后继续取从队列中取信息。
3、创建一个线程,专门检查删除队列,如果队列有内容,那么就取出来。然后删除数据库记录。


WINFORM怎么知道数据库添加了记录?用SqlDependency?
jx315425246 2019-04-04
  • 打赏
  • 举报
回复
如果短信发送是自己的,作一短信完成后的事件
qq_15826817 2019-04-04
  • 打赏
  • 举报
回复
用队列的思想,串行化处理,思路如下:
1、创建一个发送信息队列(用ConcurrentQueue,线程安全队列来做),每添加成功一条数据库记录,那么就将发送信息添加到该队列。保存的信息主要两个数据库记录自增ID或者主键(用于一会的删除数据库记录用),短信的内容。
2、创建10个线程,每个线程干的事如下:
1)从队列中取发送信息,执行发送动作,如果发送成功那么,将发送信息中的自增ID或者主键 保存到删除队列,然后继续取从队列中取信息。
3、创建一个线程,专门检查删除队列,如果队列有内容,那么就取出来。然后删除数据库记录。
baidu_27549073 2019-04-04
  • 打赏
  • 举报
回复
1个线程取数据,存入队列 10个线程发消息,发完删数据,然后从列取下一条
wanghui0380 2019-04-04
  • 打赏
  • 举报
回复
最重要的事情,不是想着什么轮流,别轮流。有人干的快,就让他多干。有人干的少,干的慢,分在多也没用。
wanghui0380 2019-04-04
  • 打赏
  • 举报
回复
其实你只要倒过来看,就明白。你的瓶颈不取决于你分给了谁,你分他在多,或者在公平,公正,公开,那也没用。

你的瓶颈取决于发送的效率,1个通道发送效率低,你按平均标准给他,那也是浪费,只能降级处理

所以不用什么分发,让他自己去取就行了
wanghui0380 2019-04-04
  • 打赏
  • 举报
回复
既然你觉着分发是问题,那么就不能倒过来么?
别分发,他自己去取。
奇点码农 2019-04-04
  • 打赏
  • 举报
回复
可以给一个全局变量,标记ID,开10个线程,比如每次从数据库中读取10(或者100条)个记录,则ID+10(这里需要lock一下),开一个线程发送信息,然后再读以下10条信息,这样的话就都预先读到内存里面,效率还高一点,如果担心线程的新建和关闭造成资源浪费,可以使用线程池(这个我也用的不多)

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧