我有2个问题。以下是场景 -
流程A和流程B有2个不同的流程。 进程A入队是消息队列中的消息。 进程B从消息队列中出列消息。
1)进程B关闭一段时间,但进程A继续将队列中的消息排入队列。当进程B返回时,如何在进程B脱机时如何将进程A发布的消息队列中的消息出列?
2)我正在使用的队列是多个消费者队列,因为需要有多个进程B才能使消息出列。设计背后的原因是,如果其中一个进程B中断,则另一个进程B仍然可以继续处理该消息。同时,如果进程B的一个实例已经接收到消息,则它应该通知其他进程B不处理该消息。
我找不到任何样品。任何帮助是极大的赞赏。
答案 0 :(得分:0)
我刚刚完成了一个具有相似要求的项目。
问题1) 我创建了一个Windows服务计时器,它调用WCF Restful服务定期运行。然后,WCF服务将使任何入队的队列出列(每次调用最多500条消息)。任何排队的东西都应该按顺序自动处理,所以即使这个计时器一旦重新启动就停止了,它会从它停止的地方开始。
问题2) 我正在将数据从Oracle复制到CouchBase,因此我在进程启动时有一个时间戳进行检索,并且在CouchBase中有已保存数据的时间戳,如果第一个比后者早,那么它就不会保存。 (这是为了照顾比赛条件)。
在Oracle中,我还有一个触发器,当某些东西入队时,它会将id和入队时间复制到第二个表。定期检查第二个表,如果一个项目已在队列表中出列但第二个表尚未更新以在WCF服务的某个时间范围内反映这一点,它将重新排队数据,因为该过程中出现故障
如果它有用,这里是使用odp.net的wcf restful服务的一个例子。
OracleAQQueue _queueObj;
OracleConnection _connObj;
_connString = ConfigurationManager.ConnectionStrings["connectionstring"].ToString();
_connObj = new OracleConnection(_connString);
_queueObj = new OracleAQQueue("QUEUENAME", _connObj);
_connObj.Open();
int i = 0;
bool messageAvailable = true;
while (messageAvailable && i < 500)
{
OracleTransaction _txn = _connObj.BeginTransaction();
//Makes dequeue part of transaction
_queueObj.DequeueOptions.Visibility = OracleAQVisibilityMode.OnCommit;
_queueObj.DequeueOptions.ConsumerName = "CONSUMERNAME"
try
{
//Wait number of seconds for dequeue, default is forever
_queueObj.DequeueOptions.Wait = 2;
_queueObj.MessageType = OracleAQMessageType.Raw;
_queueObj.DequeueOptions.ProviderSpecificType = true;
OracleAQMessage _depMsq = _queueObj.Dequeue();
var _binary = (OracleBinary)_depMsq.Payload;
byte[] byteArray = _binary.Value;
_txn.Commit();
}
catch (Exception ex)
{
//This catch will always fire when all messages have been dequeued
messageAvailable = false;
if (ex.Message.IndexOf("end-of-fetch during message dequeue") == -1)
{
//Actual error present.
log.Info("Problem occurred during dequeue process : " + ex.Message);
}
}
}
_queueObj.Dispose();
_connObj.Close();
_connObj.Dispose();
_connObj = null;