I want to clarify if I understood the ServiceStack.Server functionality correctly.
On this page, ServiceStack.Server API is described, and it states that
Creates a Redis MQ Server that processes each message on its own background thread
Am I correct when I then assumed that this is a standalone Redis server, so if I start this with the code below, I am running a fully fledged Redis server, meaning, no need to install the Redis software, or Memurai or the likes?
Because, if I follow this example, and have no other running Redis server, I get
'No connection could be made because the target machine actively refused it. 127.0.0.1:6379'
This line
var redisFactory = new PooledRedisClientManager("localhost:6379");
starts a client and tries to connect to 6379 and naturally fails. The redisFactory is then used in the line creating the MqServer, which is odd to me:
var mqHost = new RedisMqServer(redisFactory, retryCount: 2);
If this is a standalone MQ server, then creating a client before creating and starting the server isn't going to work, which makes me think this is not an Redis MQ server?
Am I correct when I then assumed that this is a standalone Redis server
That's an incorrect conclusion, the Redis Server is a distributed in-memory data structure server which just like other distributed servers like an RDBMS or MQ Broker runs in its own isolated networked process.
All ServiceStack Redis Libraries connect to a Redis Server, Redis MQ is like all other distributed ServiceStack MQ providers which process messages sent to a broker, in this case Redis MQ uses the Redis Server as its broker. The statement:
Creates a Redis MQ Server that processes each message on its own background thread
Explains how Redis MQ processes the messages that it receives, where each different Message Type (i.e. Request DTO Type) processes messages in its own background thread.
Related
I have a client and server, based on TcpListener and TcpClient. The client connects to the server and they exchange some data. Everything works just fine when I run locally.
But when I put the server in a Docker container on Azure Container Services, and connect the client to it, the following happens:
Client connects successfully to server
Client and server perform successful handshake
Data transfer begins
Approximately 20 seconds later (this is supposed to take several minutes) the whole thing blows up. The server reports "connection reset by peer" and the client reports "error reading past the end of the stream."
Each side seems to think the other side is the one with the problem. When I'm running locally, everything works as expected, which leads me to believe that the problem is somewhere in between.
There isn't a fundamental issue with establishing the connection, such as a firewall getting in the way, because I've verified at both ends that they're connecting and performing the handshake. The client is not "slamming the phone down"; it's expecting more data from the server. But "connection reset by peer" means that someone somewhere is intentionally sending a RST packet.
Is there any good way to figure out what's interfering with my data transfer?
For Azure Container Services (be it Azure Container Instances or Azure Kubernetes Service), the major cause for intermittent connection issues is hitting a limit while making new outbound connections. The limits you can hit include:
TCP Connections
SNAT ports
Please see:
Detecting SNAT port exhaustion on Azure Kubernetes Service
Troubleshooting intermittent outbound connection errors in Azure App Service (even if it is about Azure App Service most of them still apply)
More info:
kube-proxy Subtleties: Debugging an Intermittent Connection Reset
Fix a random network Connection Reset issue in Docker/Kubernetes
I have an application that communicate with local IBM MQ Queue Manager that
is also connected with a remote Queue Manager.
Is there an event in the IBM c# API that can notify me when the connection between the local and the remote queue manager fell?
If there isn't what is the best way to get it ?
That is why you implement an MQ monitoring solution rather than put monitoring code in each application.
I have an ASP.NET MVC application that runs on server A and some web services that run on server B. I have implemented real-time notifications for which I have used SignalR on server A. But now I need server B to also be able to send messages to a View served from server A (the main web application). Hence, I am trying the tutorial here to involve Redis backplane.
In my startup in server A, I have added the following:
GlobalHost.DependencyResolver.UseRedis("localhost", 6379, string.Empty, "abc");
app.MapHubs();
Here, I assume that "myApp" indicates the channel and when I run publish abc "hello world" on the Redis console, I can see the subscriber count returned as 1, but I am not able to figure out how a SignalR hub interacts with the channel. Where do I receive the message on the server/view? Can we subscribe to only one redis channel? Can't we dynamically configure to subscribe to a particular channel?
EDIT: I can see messages sent from chat Application implemented using SignalR on redis console if I subscribe to abc.
Also for now I have implemented my own redis listener on server A which in receiving a message from redis channel, calls the signalR hub function. I am sure there must be a different way to do this and I am hoping redis backplane can help me but unsure how it works.
Backplane distributes messages between servers.
GlobalHost.DependencyResolver.UseRedis("localhost", 6379, string.Empty, "abc");
Here, abc is the redis channel, that means whichever server is connected to redis server with this channel, they will share messages. SignalR channel (group) is different than Redis channel. You can share also SignalR channel (group) messages.
Then just install the Microsoft.AspNet.SignalR.Redis NuGet to your servers.
Connect your servers to Redis like this:
GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName");
app.MapSignalR();
Then, use your signalr as before. You don't have to do anything else.
When Server A sends a message to the clients, it will send the message first to Redis. Then Redis will share the message with all subscribers (servers A and B). Then, A and B will send the message to their clients. (Also viceversa is true, it will be same for if B sends a message).
Let's say A sends a message to the clients. _context.Clients.All.TestMessage("Hello");
This will go first to redis and redis will share this with A and B.
Then both A an B will send this message to their clients.
_context.Clients.All.TestMessage("Hello");
But you don't have to worry about these kind of things. I said before. Install package, conntect your servers to redis and use signalr as before.
If we come in your question. The answer is Yes. Server B can send messages to server A clients by Signalr Backplane.
This image summarizes what I told:
Using the StackExchange.Redis client in a C# application, I am attempting to use PubSub to perform cross-server communication between web servers running the same application. In this model, each server is running its own Redis server, and its connection multiplexer sets the local server as the first server in the list. In other words, SERVER_A and SERVER_B each run a Redis server on port 6379 and have connection strings as follows:
SERVER_A --> "SERVER_A:6379,SERVER_B:6379"
SERVER_B --> "SERVER_B:6379,SERVER_A:6379"
Using external clients to subscribe to each Redis server, I can see SERVER_A publishing messages to its local Redis server. However, SERVER_B is not picking up the message, despite having a connection via the multiplexer. When I rearrange the order of the connections so they match, then messages from A are picked up by B. Is there something in a setting or otherwise that I need to do so that the connection multiplexer will listen to subscriptions on all servers, or is this a bug in the StackExchange.Redis client?
You don't mention any replication in your description. When SE.Redis connects to multiple servers it is intended to be a related family of servers - for example, either:
two or more 2.* servers related via master/slave
three or more 3.* servers related via a formal cluster
Replication groups have distribution mechanisms for pub/sub. Two disconnected servers: do not.
The TIBCO EMS .NET reference guide says (pg 134)
To enable reconnection behavior and fault tolerance, the serverURL parameter must be a comma-separated list of two or more URLs. In a situation with only one server, you may supply two copies of that server’s URL to enable client reconnection (for example, tcp://localhost:7222,tcp://localhost:7222).
The TIBCO EMS user's guide (pg 292) talks about failover scenarios, client notification, and automatic transfer of clients to the backup server, but nothing specifically "reconnect" related.
In a "reconnect" scenario, does the server handle everything? or does the client have to do something with it's TIBCO.EMS.Connection instances?
Looks like from our testing that the there are settings on both the server and the client that enable this feature. On the client side, the SetReconnAttemptCount, Delay, Timeout govern the attempts the client tries to reconnect once its aware of a server failover / connection failover.
In our testing, we used a single server environment, listed the server twice in the connection string (using the trick you outlined above) and when that server was taken offline, we received a client notification of the failover process taking affect (we enabled Tibems.SetExceptionOnFTSwitch(true)) and when the server was brought back online, our client seemlessly reconnected without missing a beat. We didn't need to code anything, the internal reconnect logic worked its magic.
On the server side, fault tolerance needs to be enabled and I believe server-client and client-server heartbeats need to be enabled (though this has not yet been verified).
Hope this helps.