I am current reading in depth about RabbitMQ as I will have a task working with it. I've read about channels. In RabbitMQ Essentials
"Channel: This is a logical connection between a publisher/consumer and
a broker. Multiple channels can be established within a single connection."
Can some explain a bin in details how this is accomplished. I can imagine that a channel represents some kind of a publisher/consumer where they send use the TCP channel IN TURNs, for example in Round Robin fashion. when a logical channel is using the physical one other channels wait until the current is finished then its passed to the next logical channel. Is this assumption is true or I am missing something ?
Related
.. when the http response entity is not consumed, or the client tcp buffer becomes full, or when the rate of client taking from its tcp buffer is lower then the rate of server pushing data to it?
I am looking for a way for to achieve the following:
Let's assume that there is a backpressure-able source of data on the server, such as an Apache Kafka topic.
If I consume this source from a remote location it may be possible that the rate at which that remote location can consume is lower - this is solved if Kafka client or consumer is used.
However let's assume that the client is a browser and that exposing direct Kafka protocol / connectivity is not a possibility.
Further, let's assume that there is a possibility of getting all the value even if jumping over some messages.
For instance in case of compacted topics, getting only the latest values for each key is enough for a client, no need to go through intermediate values.
This would be equivalent to Flowable.onBackpressureLatest() or AkkaStreams.aggregateOnBackpressure or onBackpressureAggregate.
Would it be a way to expose the topic over HTTP REST (e.g. Server Side Events / chunked transfer-encoding) or over web-sockets, that would achieve this effect of skipping over intermediate values for each key?
Please advise, thanks
Akka http supports back pressure based on TCP protocol very well and you can read about using it in combination with streaming here
Kafka consumption and exposure via http with back pressure can be easily achieved in combination of akka-http, akka-stream and alpakka-kafka.
Kafka consumers need to do polling and alpakka covers back pressure with reduction of polling requests.
I don't see the necessity of skipping over the messages when back pressure is fully supported. Kafka will keep track of the offset consumed by a consumer group (the one you pick for your service or http connection) and this will guarantee eventual consumption of all messages. Of course, if you produce messages way faster in a topic, the consumer will never catch up. Let me know if this is your case.
As a final note, you may check out Confluent REST Proxy API, which allows you to read Kafka messages in a restful manner.
Section NATS Server Clustering states that:
Note that NATS clustered servers have a forwarding limit of one hop.
This means that each gnatsd instance will only forward messages that
it has received from a client to the immediately adjacent gnatsd
instances to which it has routes. Messages received from a route will
only be distributed to local clients. Therefore a full mesh cluster,
or complete graph, is recommended for NATS to function as intended and
as described throughout the documentation.
Let's assume that I have a NATS cluster of 3 nodes: A -> B -> C ( -> denotes a route). Would you please let me know what will happen wit NATS clients in the following scenario:
A message sent to node A
Node A suddenly terminates before delivering the message to node B
Thanks in advance
In the case you described, the message will be dropped.
Core NATS provides a delivery guarantee of "at most once", so if you cannot tolerate lost messages, your application needs to detect that the message never arrived in its destination and resend the message. You might detect this from a timeout using the request/reply pattern, or implement your own type of remediation for lost messages.
Alternatively, you can use NATS streaming, which provides log based persistence and sits atop NATS. It will guarantee the message will be delivered "at least once".
I have seen a number of examples of paho clients reading sensor data then publishing, e.g., https://github.com/jamesmoulding/motion-sensor/blob/master/open.py. None that I have seen have started a network loop as suggested in https://eclipse.org/paho/clients/python/docs/#network-loop. I am wondering if the network loop is unnecessary for publishing? Perhaps only needed if I am subscribed to something?
To expand on what #hardillb has said a bit, his point 2 "To send the ping packets needed to keep a connection alive" is only strictly necessary if you aren't publishing at a rate sufficient to match the keepalive you set when connecting. In other words, it's entirely possible the client will never need to send a PINGREQ and hence never need to receive a PINGRESP.
However, the more important point is that it is impossible to guarantee that calling publish() will actually complete sending the message without using the network loop. It may work some of the time, but could fail to complete sending a message at any time.
The next version of the client will allow you to do this:
m = mqttc.publish("class", "bar", qos=2)
m.wait_for_publish()
But this will require that the network loop is being processed in a separate thread, as with loop_start().
The network loop is needed for a number of things:
To deal with incoming messages
To send the ping packets needed to keep a connection alive
To handle the extra packets needed for high QOS
Send messages that take up more than one network packet (e.g. bigger than local MTU)
The ping messages are only needed if you have a low message rate (less than 1 msg per keep alive period).
Given you can start the network loop in the background on a separate thread these days, I would recommend starting it regardless
Because of geographic distance between server and client network latency can vary a lot. So I want to get "pure" req. processing time of service without network latency.
I want to get network latency as TCP connecting time. As far as I understand this time depends a lot on network.
Main idea is to compute:
TCP connecting time,
TCP first packet receive time,
Get "pure" service time = TCP first packet receive (waiting time) – TCP connecting.
I divide TCP connecting by 2 because in fact there are 2 requests-response (3-way handshake).
I have two questions:
Should I compute TCP all packets receive time instead of only first packet?
Is this method okay in general?
PS: As a tool I use Erlang's gen_tcp. I can show the code.
If at all, i guess the "pure" service time = TCP first packet receive - TCP connecting.. You have written other way round.
A possible answer to your first questions is , you should ideally compute atleast some sort of average by considering pure service time of many packets rather than just first packet.
Ideally it can also have worst case, average case, best case service times.
For second question to be answered we would need why would you need pure service time only. I mean since it is a network application, network latencies(connection time etc...) should also be included in the "response time", not just pure service time. That is my view based on given information.
I have worked on a similar question when working for a network performance monitoring vendor in the past.
IMHO, there are a certain number of questions to be asked before proceeding:
connection time and latency: if you base your network latency metric, beware that it takes into account 3 steps: Client sends a TCP/SYN, Server responds with a TCP/SYN-ACK, the Client responds by a final ACK to set up the TCP connection. This means that the CT is equivalent to 1.5 RTT (round trip time). This validates taking the first two steps of the TCP setup process in acccount like you mention.
Taking in account later TCP exchanges: while this first sounds like a great idea to keep evaluating network latency in the course of the session, this becomes a lot more tricky. Here is why: 1. Not all packets have to be acknowledged (RFC1122 or https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment) , which will generate false measurements when it occurs, so you will need an heuristic to take these off your calculations. 2. Not all systems consider acknowledging packets a high priority tasks. This means that some high values will pollute your network latency data and simply reflect the level of load of the server for example.
So if you use only the first (and reliable) measurement you may miss some network delay variation (especially in apps using long lasting TCP sessions).
Netty channels have multiple states but I am unable to find any
documentation on the actual state transitions. The closest to any
documentation on this that I could find for Netty 3.2.x system is
here.
I was able to locate the possible states that a channel can be in
here.
However there is nothing that describes the normal transitions that a
channel can make from one state to another. It appears that not all
channels make all possible state transitions.
Different Netty channels do indeed have different state transitions.
In general the possible state transitions for TCP based server
channels are:
OPEN -> ( BOUND -> UNBOUND )* -> CLOSE
If you are using a SimpleChannelHandler subclass in your pipeline
the equivalent methods for handling the upstream events when one of
these state changes occur are:
channelOpen
channelBound
channelUnbound
channelClose
Server channels never move into the CONNECTED state.
Server channels rarely move back into the BOUND state once they
move into the UNBOUND state, however this appears to be dependent
on the application so YMMV.
Note that server channels can fire events when a child channel is
opened or closed. These events can occur only after the server
channel is in the BOUND state. When these events are sent
upstream on behalf of the server channel then the following methods on
your SimpleChannelHandler subclass are called:
childChannelOpen
childChannelClosed
The possible state transitions for TCP based child and client channels
are:
OPEN -> ( BOUND -> ( CONNECTED -> DISCONNECTED )* -> UNBOUND )* -> CLOSE
It appears that moving into the CONNECTED state first is not
enforced within the channel code; however this state is invariably
fired first for both child and client channels within the Netty
framework before the channel is moved into the CONNECTED state.
If you are using SimpleChannelHandler or a subclass thereof in
your pipeline the equivalent methods are:
channelOpen
channelBound
channelConnected
channelDisconnected
channelUnbound
channelClose
A TCP based channel must be in the CONNECTED state before anything
can be read or written to the channel. This includes server channels,
which can never be read from or written to, which is not much of a
surprise as server channels are invariably used only for managing the
connect operation on behalf of the server.
Datagram sockets operate differently than TCP based sockets in that
they can be used to read and write data without actually being
connected (though connecting a datagram socket can be faster as you
avoid security checks). Datagram sockets can be effectively used
using both of the state transitions listed for TCP based child and
server channels described above.