public final class MessagingService extends MessagingServiceMBeanImpl
IVerbHandler
.
Message
, and you should pick one depending on the desired behaviour:
1. To send a request that expects a response back, use
sendWithCallback(Message, InetAddressAndPort, RequestCallback)
method. Once a response
message is received, RequestCallback.onResponse(Message)
method will be invoked on the
provided callback - in case of a success response. In case of a failure response (see Verb.FAILURE_RSP
),
or if a response doesn't arrive within verb's configured expiry time,
RequestCallback.onFailure(InetAddressAndPort, RequestFailureReason)
will be invoked instead.
2. To send a response back, or a message that expects no response, use send(Message, InetAddressAndPort)
method.
See also: Message.out(Verb, Object)
, Message.responseWith(Object)
,
and Message.failureResponse(RequestFailureReason)
.
RequestCallback
interface - so long as your response verb handler is the default ResponseVerbHandler
.
There are two steps you need to perform to implement request handling:
1. Create a IVerbHandler
to process incoming requests and responses for the new type (if applicable).
2. Add a new Verb
to the enum for the new request type, and, if applicable, one for the response message.
MessagingService will now automatically invoke your handler whenever a Message
with this verb arrives.
OutboundConnections.LARGE_MESSAGE_THRESHOLD
(65KiB by default)
- one for small messages - defined as smaller than that threshold
- and finally, a connection for urgent messages - usually small and/or that are important to arrive
promptly, e.g. gossip-related ones
Message.Serializer
, alongside with format evolution notes.
For the list and descriptions of available frame decoders see FrameDecoder
comments. You can
find wire format documented in the javadoc of FrameDecoder
implementations:
see FrameDecoderCrc
and FrameDecoderLZ4
in particular.
OutboundConnection
is the core class implementing outbound connection logic, with
OutboundConnection.enqueue(Message)
being its main entry point. The connections are initiated
by OutboundConnectionInitiator
.
Netty pipeline for outbound messaging connections generally consists of the following handlers:
[(optional) SslHandler] <- [FrameEncoder]
OutboundConnection
handles the entire lifetime of a connection: from the very first handshake
to any necessary reconnects if necessary.
Message-delivery flow varies depending on the connection type.
For ConnectionType.SMALL_MESSAGES
and ConnectionType.URGENT_MESSAGES
,
Message
serialization and delivery occurs directly on the event loop.
See OutboundConnection.EventLoopDelivery
for details.
For ConnectionType.LARGE_MESSAGES
, to ensure that servicing large messages doesn't block
timely service of other requests, message serialization is offloaded to a companion thread pool
(SocketFactory.synchronousWorkExecutor
). Most of the work will be performed by
AsyncChannelOutputPlus
. Please see OutboundConnection.LargeMessageDelivery
for details.
To prevent fast clients, or slow nodes on the other end of the connection from overwhelming
a host with enqueued, unsent messages on heap, we impose strict limits on how much memory enqueued,
undelivered messages can claim.
Every individual connection gets an exclusive permit quota to use - 4MiB by default; every endpoint
(group of large, small, and urgent connection) is capped at, by default, at 128MiB of undelivered messages,
and a global limit of 512MiB is imposed on all endpoints combined.
On an attempt to OutboundConnection.enqueue(Message)
, the connection will attempt to allocate
permits for message-size number of bytes from its exclusive quota; if successful, it will add the
message to the queue; if unsuccessful, it will need to allocate remainder from both endpoint and lobal
reserves, and if it fails to do so, the message will be rejected, and its callbacks, if any,
immediately expired.
For a more detailed description please see the docs and comments of OutboundConnection
.
InboundMessageHandler
is the core class implementing inbound connection logic, paired
with FrameDecoder
. Inbound connections are initiated by InboundConnectionInitiator
.
The primary entry points to these classes are FrameDecoder.channelRead(ShareableBytes)
and AbstractMessageHandler.process(FrameDecoder.Frame)
.
Netty pipeline for inbound messaging connections generally consists of the following handlers:
[(optional) SslHandler] -> [FrameDecoder] -> [InboundMessageHandler]
FrameDecoder
is responsible for decoding incoming frames and work stashing; InboundMessageHandler
then takes decoded frames from the decoder and processes the messages contained in them.
The flow differs between small and large messages. Small ones are deserialized immediately, and only
then scheduled on the right thread pool for the Verb
for execution. Large messages, OTOH,
aren't deserialized until they are just about to be executed on the appropriate Stage
.
Similarly to outbound handling, inbound messaging imposes strict memory utilisation limits on individual
endpoints and on global aggregate consumption, and implements simple flow control, to prevent a single
fast endpoint from overwhelming a host.
Every individual connection gets an exclusive permit quota to use - 4MiB by default; every endpoint
(group of large, small, and urgent connection) is capped at, by default, at 128MiB of unprocessed messages,
and a global limit of 512MiB is imposed on all endpoints combined.
On arrival of a message header, the handler will attempt to allocate permits for message-size number
of bytes from its exclusive quota; if successful, it will proceed to deserializing and processing the message.
If unsuccessful, the handler will attempt to allocate the remainder from its endpoint and global reserve;
if either allocation is unsuccessful, the handler will cease any further frame processing, and tell
FrameDecoder
to stop reading from the network; subsequently, it will put itself on a special
org.apache.cassandra.net.InboundMessageHandler.WaitQueue
, to be reactivated once more permits
become available.
For a more detailed description please see the docs and comments of InboundMessageHandler
and
FrameDecoder
.
InternodeInboundMetrics
and
InternodeOutboundMetrics
for JMX-exposed counters.
We also provide system_views.internode_inbound
and system_views.internode_outbound
virtual tables -
implemented in InternodeInboundTable
and
InternodeOutboundTable
respectively.Modifier and Type | Class and Description |
---|---|
static class |
MessagingService.Version |
Modifier and Type | Field and Description |
---|---|
RequestCallbacks |
callbacks |
static int |
current_version |
InboundSink |
inboundSink |
LatencySubscribers |
latencySubscribers |
static int |
minimum_version |
OutboundSink |
outboundSink |
SocketFactory |
socketFactory |
static int |
VERSION_30 |
static int |
VERSION_3014 |
static int |
VERSION_40 |
channelManagers, MBEAN_NAME, messageHandlers, metrics, versions
Modifier and Type | Method and Description |
---|---|
void |
closeOutbound(InetAddressAndPort to)
Only to be invoked once we believe the endpoint will never be contacted again.
|
static MessagingService |
instance() |
void |
interruptOutbound(InetAddressAndPort to)
Closes any current open channel/connection to the endpoint, but does not cause any message loss, and we will
try to re-establish connections immediately
|
void |
listen() |
io.netty.util.concurrent.Future<java.lang.Void> |
maybeReconnectWithNewIp(InetAddressAndPort address,
InetAddressAndPort preferredAddress)
Reconnect to the peer using the given
addr . |
void |
removeInbound(InetAddressAndPort from)
Only to be invoked once we believe the connections will never be used again.
|
void |
send(Message message,
InetAddressAndPort to)
Send a message to a given endpoint.
|
void |
send(Message message,
InetAddressAndPort to,
ConnectionType specifyConnection) |
void |
sendWithCallback(Message message,
InetAddressAndPort to,
RequestCallback cb)
Send a non-mutation message to a given endpoint.
|
void |
sendWithCallback(Message message,
InetAddressAndPort to,
RequestCallback cb,
ConnectionType specifyConnection) |
void |
sendWriteWithCallback(Message message,
Replica to,
AbstractWriteResponseHandler<?> handler,
boolean allowHints)
Send a mutation message or a Paxos Commit to a given endpoint.
|
void |
shutdown()
Wait for callbacks and don't allow any more to be created (since they could require writing hints)
|
void |
shutdown(long timeout,
java.util.concurrent.TimeUnit units,
boolean shutdownGracefully,
boolean shutdownExecutors) |
void |
waitUntilListening() |
getBackPressurePerHost, getDroppedMessages, getGossipMessageCompletedTasks, getGossipMessageCompletedTasksWithPort, getGossipMessageDroppedTasks, getGossipMessageDroppedTasksWithPort, getGossipMessagePendingTasks, getGossipMessagePendingTasksWithPort, getLargeMessageCompletedTasks, getLargeMessageCompletedTasksWithPort, getLargeMessageDroppedTasks, getLargeMessageDroppedTasksWithPort, getLargeMessagePendingTasks, getLargeMessagePendingTasksWithPort, getSmallMessageCompletedTasks, getSmallMessageCompletedTasksWithPort, getSmallMessageDroppedTasks, getSmallMessageDroppedTasksWithPort, getSmallMessagePendingTasks, getSmallMessagePendingTasksWithPort, getTimeoutsPerHost, getTimeoutsPerHostWithPort, getTotalTimeouts, getVersion, isBackPressureEnabled, reloadSslCertificates, setBackPressureEnabled
public static final int VERSION_30
public static final int VERSION_3014
public static final int VERSION_40
public static final int minimum_version
public static final int current_version
public final SocketFactory socketFactory
public final LatencySubscribers latencySubscribers
public final RequestCallbacks callbacks
public final InboundSink inboundSink
public final OutboundSink outboundSink
public static MessagingService instance()
public void sendWithCallback(Message message, InetAddressAndPort to, RequestCallback cb)
message
- message to be sent.to
- endpoint to which the message needs to be sentcb
- callback interface which is used to pass the responses or
suggest that a timeout occurred to the invoker of the send().public void sendWithCallback(Message message, InetAddressAndPort to, RequestCallback cb, ConnectionType specifyConnection)
public void sendWriteWithCallback(Message message, Replica to, AbstractWriteResponseHandler<?> handler, boolean allowHints)
message
- message to be sent.to
- endpoint to which the message needs to be senthandler
- callback interface which is used to pass the responses or
suggest that a timeout occurred to the invoker of the send().public void send(Message message, InetAddressAndPort to)
message
- messages to be sent.to
- endpoint to which the message needs to be sentpublic void send(Message message, InetAddressAndPort to, ConnectionType specifyConnection)
public void closeOutbound(InetAddressAndPort to)
public void removeInbound(InetAddressAndPort from)
public void interruptOutbound(InetAddressAndPort to)
public io.netty.util.concurrent.Future<java.lang.Void> maybeReconnectWithNewIp(InetAddressAndPort address, InetAddressAndPort preferredAddress)
addr
. Outstanding messages in each channel will be sent on the
current channel. Typically this function is used for something like EC2 public IP addresses which need to be used
for communication between EC2 regions.address
- IP Address to identify the peerpreferredAddress
- IP Address to use (and prefer) going forward for connecting to the peerpublic void shutdown()
public void shutdown(long timeout, java.util.concurrent.TimeUnit units, boolean shutdownGracefully, boolean shutdownExecutors)
public void listen()
public void waitUntilListening() throws java.lang.InterruptedException
java.lang.InterruptedException
Copyright © 2009-2021 The Apache Software Foundation