简体   繁体   English

WCF远程MSMQ - 我可以写入远程队列,但无法接收

[英]WCF Remote MSMQ - I can write to a remote queue, but cannot receive

jobsServer: Windows Server 2008 R2 .NET Version: 4.5 jobsServer:Windows Server 2008 R2 .NET版本:4.5

I'm using WCF to connect two servers - app and queue . 我正在使用WCF连接两个服务器 - 应用程序队列 I want app to be able to send/receive messages from queue . 我希望应用程序能够从队列发送/接收消息。 For some reason, app can send messages, but CANNOT receive them. 出于某种原因,应用程序可以发送消息,但无法接收消息。

The netMsmq binding looks like: netMsmq绑定看起来像:

<binding name="JobExecutionerBinding" receiveErrorHandling="Move">
  <security>
    <transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
  </security>
</binding>

And the service binding looks like: 服务绑定看起来像:

Now, the client binding looks like: 现在,客户端绑定看起来像:

<endpoint   address="net.msmq://queue/private/jobs" 
            binding="netMsmqBinding" 
            bindingConfiguration="JobExecutionerBinding" 
            contract="JobExecution.Common.IJobExecutionService" 
            name="SimpleEmailService" 
            kind="" 
            endpointConfiguration=""/>

I changed a few names for security's sake. 为安全起见,我改了几个名字。

So, the WC client can send to the remote queue without a problem. 因此,WC客户端可以毫无问题地发送到远程队列。 It even properly queues the outgoing message and forwards it on later in the event that the remote queue server is down. 它甚至可以正确排队传出的消息,并在远程队列服务器关闭的情况下稍后将其转发。 But every time I start up the WCF service, I get this: 但是每次启动WCF服务时,我都会得到:

There was an error opening the queue. 打开队列时出错。 Ensure that MSMQ is installed and running, the queue exists and has proper authorization to be read from. 确保MSMQ已安装并正在运行,队列存在并具有可从中读取的适当权限。 The inner exception may contain additional information. 内部异常可能包含其他信息。 ---> System.ServiceModel.MsmqException: An error occurred while opening the queue:The queue does not exist or you do not have sufficient permissions to perform the operation. ---> System.ServiceModel.MsmqException:打开队列时发生错误:队列不存在或您没有足够的权限来执行操作。 (-1072824317, 0xc00e0003). (-1072824317,0xc00e0003)。 The message cannot be sent or received from the queue. 无法从队列中发送或接收消息。 Ensure that MSMQ is installed and running. 确保已安装并运行MSMQ。 Also ensure that the queue is available to open with the required access mode and authorization. 还要确保可以使用所需的访问模式和授权打开队列。 at System.ServiceModel.Channels.MsmqQueue.OpenQueue() at System.ServiceModel.Channels.MsmqQueue.GetHandle() at System.ServiceModel.Channels.MsmqQueue.SupportsAccessMode(String formatName, Int32 accessType, MsmqException& msmqException) --- End of inner exception stack trace --- at System.ServiceModel.Channels.MsmqVerifier.VerifyReceiver(MsmqReceiveParameters receiveParameters, Uri listenUri) at System.ServiceModel.Channels.MsmqTransportBindingElement.BuildChannelListener[TChannel](BindingContext context) at System.ServiceModel.Channels.Binding.BuildChannelListener[TChannel](Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) at System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, System.ServiceModel.Channels.MsmqQueue.OpenQueue()at System.ServiceModel.Channels.MsmqQueue.GetHandle()at System.ServiceModel.Channels.MsmqQueue.SupportsAccessMode(String formatName,Int32 accessType,MsmqException&msmqException)---内部结束异步堆栈跟踪--- System.ServiceModel.Channels.MsmqVerifier.VerifyReceiver(MsmqReceiveParameters receiveParameters,Uri listenUri)位于System.ServiceModel.Channels.Binding.BuildChannelListener的System.ServiceModel.Channels.MsmqTransportBindingElement.BuildChannelListener [TChannel](BindingContext context)处System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener中的[TChannel](Uri listenUriBaseAddress,String listenUriRelativeAddress,ListenUriMode listenUriMode,BindingParameterCollection参数)(Boolean actualCreate,Type [] supportedChannels,Binding binding,BindingParameterCollection参数,Uri listenUriBaseAddress,String listenUriRelativeAddress,ListenUriMode listenUriMode, ServiceThrottle油门, IChannelListener& result, Boolean supportContextSession) at System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) at System.ServiceModel.ServiceHostBase.InitializeRuntime() at IChannelListener&result,Boolean supportContextSession)at System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff,ServiceHostBase serviceHost,Uri listenUri,ListenUriMode listenUriMode,Boolean supportContextSession,IChannelListener&result)at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description,ServiceHostBase) service.ServiceModel.ServiceHostBase.InitializeRuntime()at at ServiceHost)

I've been all over StackOverflow and the internet for 8 hours. 我已经在StackOverflow和互联网上待了8个小时。 Here's what I've done: 这就是我所做的:

  • Ensured that ANONYMOUS LOGIN, Everyone, Network, Network Service, and Local Service have full control 确保ANONYMOUS LOGIN,Everyone,Network,Network Service和Local Service具有完全控制权
  • Stopped the remote MSMQ server and observed what the WCF service does, and I get a different error - so I'm sure that the WCF service when starting up is speaking to the MSMQ server 停止了远程MSMQ服务器并观察了WCF服务的作用,我得到了一个不同的错误 - 所以我确信启动时的WCF服务是对MSMQ服务器说话
  • Disabled Windows Firewall on both boxes and opened all ports via EC2 security groups 两个框上都禁用了Windows防火墙,并通过EC2安全组打开了所有端口
  • Set AllowNonauthenticatedRpc and NewRemoteReadServerAllowNoneSecurityClient to 1 in the registry 在注册表中将AllowNonauthenticatedRpc和NewRemoteReadServerAllowNoneSecurityClient设置为1
  • Configured MS DTC on both servers (the queue is transactional, but I get the same error regardless as to whether the queue is transactional or not) 在两台服务器上配置MS DTC(队列是事务性的,但无论队列是否是事务性的,我都会得到相同的错误)
  • Confirmed that the WCF server starts up fine if I use the local queue, and receives without a problem 确认如果我使用本地队列,WCF服务器启动正常,并且没有问题地收到

Help!!! 救命!!! I can't scale my app without a remote queueing solution. 没有远程排队解决方案,我无法扩展我的应用程序。

It's not clear from your post which tier can not read and more importantly which queue . 从您的帖子不清楚哪个层无法读取 ,更重要的是哪个队列

However, reading remote queues transactionally is not supported: 但是,不支持以事务方式读取远程队列:

Message Queuing supports sending transactional messages to remote queues, but does not support reading messages from a remote queue within a transaction . 消息队列支持事务性消息发送到远程队列, 但不支持从事务中的远程队列中读取消息 This means that reliable, exactly-once reception is not available from remote queues. 这意味着远程队列无法提供可靠,准确的一次接收。 See Reading Messages from Remote Queues 请参阅从远程队列中读取消息

I suspect that somewhere your system is still performing transactional remote reads even though you mentioned you disabled it. 我怀疑你的系统仍在执行事务性远程读取的某个地方,即使你提到你禁用了它。

From a best practice point of view, even if you got it to work, your design will not scale which is a shame as it is something you mentioned you wanted. 从最佳实践的角度来看,即使你让它发挥作用,你的设计也不会扩展,因为它是你提到的你想要的东西。

Remote reading is a high-overhead and therefore inefficient process. 远程读取是一个高开销,因此效率低下的过程。 Including remote read operations in an application limits scaling. 在应用程序中包括远程读取操作会限制扩展。 1 1

You should always remote write not remote read. 你应该总是远程写 远程读。

A better way is to insert a message broker or router service that acts as the central point for messaging. 更好的方法是插入消息代理路由器服务 ,作为消息传递的中心点。 Your app and queue services (confusing names by the way) should merely read transactionally from their local queues . 您的应用程序队列服务(顺便说一句令人困惑的名称)应该只是从其本地队列中以事务方式读取

ie

  • app should transactionally read it's local queue app应该以事务方式读取它的本地队列
  • app should transactionally send to the remote broker app应以事务方式发送给远程代理
  • broker transactionally reads local queue 代理事务性地读取本地队列
  • broker transactionally sends to remote queue 代理事务性地发送到远程队列

Similarly if your queue tier wanted to reply the reverse process to the above would occur. 同样,如果您的队列层想要回复,则会发生上述相反的过程。

Later if you wish to improve performance you can introduce a Dynamic router which redirects a message to a different remote queue on another machine based on dynamic rulesets or environmental conditions such as stress levels. 稍后,如果您希望提高性能,可以引入动态路由器 ,该路由器根据动态规则集或环境条件(如压力级别)将消息重定向到另一台计算机上的其他远程队列。

Remote transactional reads are supported as of MSMQ 4.0 (Windows server 2008). 从MSMQ 4.0(Windows Server 2008)开始支持远程事务读取。 If you are facing this issue, be sure to checkout https://msdn.microsoft.com/en-us/library/ms700128(v=vs.85).aspx 如果您遇到此问题,请务必查看https://msdn.microsoft.com/en-us/library/ms700128(v=vs.85).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM