2013년 10월 4일 금요일

JacORB Chapter 16

16 Connection Management and Connection Timeouts

JacORB offers a certain level of control over connections and timeouts. You can
  • set connection idle timeouts.
  • set request timing.
  • set the maximum number of accepted TCP/IP connections on the server

16.1 Timeouts

Connection idle timeouts can be set individually for the client and the server. They control how long an idle connection, i.e. a connection that has no pending replies, will stay open. The corresponding properties are jacorb.connection.client.idle timeout and jacorb.connection.server.timeout and take their values as milliseconds. If not set, connections will stay open indefinitely (or until the OS decides to close them).
Request timing controls how long an individual request may take to complete. The programmer can specify this using QoS policies, discussed in chapter 15.

16.2 Connection Management

When a client wants to invoke a remote object, it needs to send the request over a connection to the server. If the connection isn’t present, it has to be created. In JacORB, this will only happen once for every combination of host name and port. Once the connection is established, all requests and replies between client and server will use the same connection. This saves resources while adding a thin layer of necessary synchronization, and is the recommended approach of the OMG. Occasionally people have requested to allow for multiple connections to the same server, but nobody has yet presented a good argument that more connections would speed up things considerably.
On the server side, the property jacorb.connection.max server transports allows to set the maximum number of TCP/IP connections that will be listened on for requests. When using a network sniffer or tools like netstat, more inbound TCP/IP connections than the configured number may be displayed. This is for the following reason: Whenever the connection limit is reached, JacORB tries to close existing idle connections (see the subsection below). This is done on the thread that accepts the new connections, so JacORB will not actively accept more connections. However, the ServerSocket is initialized with a backlog of 20. This means that 20 more connections will be quasi-accepted by the OS. Only the 21st will be rejected right away.


16.2.1 Basics and Design

Whenever there is the need to close an existing connection because of the connection limit, the question arises on which of the connection to close. To allow for maximum flexibility, JacORB provides the interface SelectionStrategy that allows for a custom way to select a connection to close. Because selecting a connection usually requires some sort of statistical data about it, the interface StatisticsProvider allows to implement a class that collects statistical data.

package org.jacorb.orb.giop;

public interface SelectionStrategy
{
public ServerGIOPConnection
selectForClose( java.util.List connections );
}

public interface StatisticsProvider
{
public void messageChunkSent( int size );
public void flushed();
public void messageReceived( int size );
}

The interface SelectionStrategy has only the single method of selectForClose(). This is called by the class GIOPConnectionManager when a connection needs to be closed. The argument is a List containing objects of type ServerGIOPConnection. The call itself is synchronized in the GIOPConnectionManager, so no additional synchronization has to be done by the implementor of SelectionStrategy. When examining the connections, the strategy can get hold of the StatisticsProvider via the method getStatisticsProvider() of the class GIOPConnection. The strategy implementor should take care only to return idle connections. While the connection state is checked anyway while closing (it may have changed in the meantime), it seems to be more efficient to avoid cycling through the connections. When no suitable connection is available, the strategy may return null. The GIOPConnectionManager will then wait for a configurable time, and try again. This goes on until a connection can be closed.
The interface StatisticsProvider is used to collect statistical data about a connection and provide it to the SelectionStrategy. Because the nature of this data may vary, there is no standard access to the data via the interface. Therefore, StatisticsProvider and SelectionStrategy usually need to be implemented together. Whenever a new connection is created, a new StatisticsProvider object is instanciated and stored with the GIOPConnection. The StatisticsProvider interface is oriented along the mode of use of the GIOPConnection.
For efficiency reasons, messages are not sent as one big byte array. Instead, they are sent piecewise over the wire. When such a chunk is sent, the method messageChunkSent(int size) will be called. After the message has been completely sent, method flush() is called. This whole process is synchronized, so all consecutive messageChunkSents until a flush() form a single message. Therefore, no synchronization on this level is necessary. However, access to gathered statistical data by the SelectionStrategy is concurrent, so care has to be taken. Receiving messages is done only on the whole, so there exists only one method, messageReceived(int size), to notify the StatisticsProvider of such an event.
JacORB comes with two pre-implemented strategies: least frequently used and least recently used. LFU and LRU are implemented by the classes org.jacorb.orb.giop.L[F|R]USelectionStrategyImpl and org.jacorb.orb.giop. L[F|R]UStatisticsProviderImpl.

16.2.2 Configuration

To configure connection management, the following properties are provided:
jacorb.connection.max_server_connections This property sets the maximum number of TCP/IP connections that will be listened on by the server–side ORB.
jacorb.connection.wait_for_idle_interval This property sets the interval to wait until the next try is made to find an idle connection to close. Value is in microseconds.
jacorb.connection.selection_strategy_class This property sets the SelectionStrategy.
jacorb.connection.statistics_provider_class This property sets the StatisticsProvider.
jacorb.connection.delay_close If turned on, JacORB will delay closing of TCP/IP connections to avoid certain situations, where message loss can occur. See also section 16.2.3.

16.2.3 Limitations

When trying to close a connection, it is first checked that the connection is idle, i.e. has no pending messages. If this is the case, a GIOP CloseConnection message is sent, and the TCP/IP connection is closed. Under high load, this can lead to the following situation:
  1. Server sends the CloseConnection message.
  2. Server closes the TCP/IP connection.
  3. The client sends a new request into the connection, because it hasn’t yet read and acted on the CloseConnection message.
  4. The server–side OS will send a TCP RST, which cancels out the CloseConnection message.
  5. The client finds the connection closed and must consider the request lost.
To get by this situation, JacORB takes the following approach. Instead of closing the connection right after sending the CloseConnection message, we delay closing and wait for the client to close the connection. This behaviour is turned off by default, but can be enabled by setting the property jacorb.connection.delay_close to “yes”. When non-JacORB clients are used care has to be taken that these ORBs do actively close the connection upon receiving a CloseConnection message.

댓글 없음: