http://reactivex.io/

- https://en.wikipedia.org/wiki/Erik_Meijer_(computer_scientist)

- https://github.com/jhusain

- https://en.wikipedia.org/wiki/Reactive_extensions

- https://github.com/ReactiveX/RxJava



https://github.com/ReactiveX/RxJava

- https://github.com/benjchristensen

- https://www.linkedin.com/in/david-karnok-725b3189/?originalSubdomain=hu

  (https://github.com/akarnokd)



https://github.com/ReactiveX/RxJava/wiki/Reactive-Streams

Reactive Streams has been a collaborative effort to standardize the protocol for asynchronous streams on the JVM. The RxJava team was part of the effort from the beginning and supports the use of Reactive Streams APIs and eventually the Java 9 Flow APIs which are resulting from the success of the Reactive Stream effort.




https://stackoverflow.com/questions/34387153/whats-the-difference-between-reactive-and-reactive-streams

The design of Reactive Streams was a joint effort from several engineers to define a standard minimum set of components that support (potentially) asynchronous event delivery with backpressure (and synchronous cancellation). It was mainly influenced by RxJava in its design along with Akka.

However, the resulting design was significanlty different from RxJava so RxJava 1.x would require a lot of binary-incompatible changes to make itself compliant. Instead, we have an RxJavaReactiveStreams bridge and RxJava 2.0 was reimplemented by Reactive-Streams norms completely.

I have a four part blog series about Reactive-Streams in the light of RxJava.



https://www.reactivemanifesto.org/

- Jonas Bonér, Dave Farley, Roland Kuhn, and Martin Thompson

- https://rolandkuhn.com/

- http://www.reactive-streams.org/

https://en.wikipedia.org/wiki/Akka_(toolkit)



http://www.reactive-streams.org/

- https://github.com/reactive-streams/reactive-streams-jvm

- https://github.com/ReactiveX/RxJava/wiki/Reactive-Streams

- https://github.com/ReactiveX/RxJavaReactiveStreams

- https://github.com/reactor

- https://www.reddit.com/r/java/comments/6acxe3/spring_reactor_vs_rxjava/

- http://eyeahs.github.io/blog/2017/01/24/a-journey-into-reactive-streams/



https://github.com/reactor

- https://github.com/smaldini

https://hyojoy.blogspot.com/2018/08/spring-reactor-rxjava.html

- http://tech.kakao.com/2018/05/29/reactor-programming/




'Development > Common' 카테고리의 다른 글

Rx and Reactive Streams  (0) 2018.10.21
math  (0) 2018.05.27
Using the OpenSSL toolkit  (0) 2017.09.17
Date and Time Formats  (0) 2016.06.28
development - 개행문자  (0) 2016.03.02
매개변수(parameter)와 전달인자(argument)  (0) 2015.09.20
Posted by linuxism

JAVA - NIO.2

Development/Java 2018.09.29 16:35


An asynchronous channel represents a connection that supports nonblocking operations, such as connecting, reading, and writing, and provides mechanisms for controlling the operations after they've been initiated. The More New I/O APIs for the Java Platform (NIO.2) in Java 7 enhance the New I/O APIs (NIO) introduced in Java 1.4 by adding four asynchronous channels to the java.nio.channels package:

  • AsynchronousSocketChannel
  • AsynchronousServerSocketChannel
  • AsynchronousFileChannel
  • AsynchronousDatagramChannel

These classes are similar in style to the NIO channel APIs. They share the same method and argument structures, and most operations available to the NIO channel classes are also available in the new asynchronous versions. The main difference is that the new channels enable some operations to be executed asynchronously.

The asynchronous channel APIs provide two mechanisms for monitoring and controlling the initiated asynchronous operations. The first is by returning a java.util.concurrent.Future object, which models a pending operation and can be used to query its state and obtain the result. The second is by passing to the operation an object of a new class, java.nio.channels.CompletionHandler, which defines handler methods that are executed after the operation has completed. Each asynchronous channel class defines duplicate API methods for each operation so that either mechanism can be used.

This article, the first in a two-part series on NIO.2, introduces each of the channels and provides some simple examples to demonstrate their use. The examples are available in a runnable state (see Download), and you can try them out on the Java 7 beta releases available from Oracle and IBM® (both still under development at the time of this writing; see Related topics). In Part 2, you'll learn about the NIO.2 file system API.

Asynchronous socket channels and futures

To start, we'll look at the AsynchronousServerSocketChannel and AsynchronousSocketChannel classes. Our first example demonstrates how a simple client/server can be implemented using these new classes. First we'll set up the server.

Server setup

An AsychronousServerSocketChannel can be opened and bound to an address similarly to a ServerSocketChannel:

1
2
AsynchronousServerSocketChannel server =
    AsynchronousServerSocketChannel.open().bind(null);

The bind() method takes a socket address as its argument. A convenient way to find a free port is to pass in a nulladdress, which automatically binds the socket to the local host address and uses a free ephemeral port.

Next, we can tell the channel to accept a connection:

1
Future<AsynchronousSocketChannel> acceptFuture = server.accept();

This is the first difference from NIO. The accept call always returns immediately, and — unlike ServerSocketChannel.accept(), which returns a SocketChannel — it returns a Future<AsynchronousSocketChannel>object that can be used to retrieve an AsynchronousSocketChannel at a later time. The generic type of the Future object is the result of the actual operation. For example, a read or write returns a Future<Integer> because the operation returns the number of bytes read or written.

Using the Future object, the current thread can block to wait for the result:

1
AsynchronousSocketChannel worker = future.get();

Here it blocks with a timeout of 10 seconds:

1
AsynchronousSocketChannel worker = future.get(10, TimeUnit.SECONDS);

Or it can poll the current state of the operation, and also cancel the operation:

1
2
3
if (!future.isDone()) {
    future.cancel(true);
}

The cancel() method takes a boolean flag to indicate whether the thread performing the accept can be interrupted. This is a useful enhancement; in previous Java releases, blocking I/O operations like this could only be aborted by closing the socket.

Client setup

Next, we can set up the client by opening and connecting a AsynchronousSocketChannel to the server:

1
2
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
    client.connect(server.getLocalAddress()).get();

Once the client is connected to the server, reads and writes can be performed via the channels using byte buffers, as shown in Listing 1:

Listing 1. Using byte buffers for reads and writes
1
2
3
4
5
6
7
// send a message to the server
ByteBuffer message = ByteBuffer.wrap("ping".getBytes());
client.write(message).get();
 
// read a message from the client
worker.read(readBuffer).get(10, TimeUnit.SECONDS);
System.out.println("Message: " + new String(readBuffer.array()));

Scattering reads and writes, which take an array of byte buffers, are also supported asynchronously.

The APIs of the new asynchronous channels completely abstract away from the underlying sockets: there's no way to obtain the socket directly, whereas previously you could call socket() on, for example, a SocketChannel. Two new methods — getOption and setOption — have been introduced for querying and setting socket options in the asynchronous network channels. For example, the receive buffer size can be retrieved by channel.getOption(StandardSocketOption.SO_RCVBUF) instead of channel.socket().getReceiveBufferSize();.

Completion handlers

The alternative mechanism to using Future objects is to register a callback to the asynchronous operation. The CompletionHandler interface has two methods:

  • void completed(V result, A attachment) executes if a task completes with a result of type V.
  • void failed(Throwable e, A attachment) executes if the task fails to complete due to Throwable e.

The attachment parameter of both methods is an object that is passed in to the asynchronous operation. It can be used to track which operation finished if the same completion-handler object is used for multiple operations.

Open commands

Let's look at an example using the AsynchronousFileChannel class. We can create a new channel by passing in a java.nio.file.Path object to the static open() method:

1
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(Paths.get("myfile"));

Path is a new class in Java 7 that we look at in more detail in Part 2. We use the Paths.get(String) utility method to create a Path from a String representing the filename.

By default, the file is opened for reading. The open() method can take additional options to specify how the file is opened. For example, this call opens a file for reading and writing, creates it if necessary, and tries to delete it when the channel is closed or when the JVM terminates:

1
2
3
fileChannel = AsynchronousFileChannel.open(Paths.get("afile"),
    StandardOpenOption.READ, StandardOpenOption.WRITE,
    StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE);

An alternative open() method provides finer control over the channel, allowing file attributes to be set.

Implementing a completion handler

Next, we want to write to the file and then, once the write has completed, execute something. We first construct a CompletionHandler that encapsulates the "something" as shown in Listing 2:

Listing 2. Creating a completion handler
1
2
3
4
5
6
7
8
9
10
11
12
CompletionHandler<Integer, Object> handler =
    new CompletionHandler<Integer, Object>() {
    @Override
    public void completed(Integer result, Object attachment) {
        System.out.println(attachment + " completed with " + result + " bytes written");
    }
    @Override
    public void failed(Throwable e, Object attachment) {
        System.err.println(attachment + " failed with:");
        e.printStackTrace();
    }
};

Now we can perform the write:

1
fileChannel.write(ByteBuffer.wrap(bytes), 0, "Write operation 1", handler);

The write() method takes:

  • ByteBuffer containing the contents to write
  • An absolute position in the file
  • An attachment object that is passed on to the completion handler methods
  • A completion handler

Operations must give an absolute position in the file to read to or write from. It doesn't make sense for the file to have an internal position marker and for reads/writes to occur from there, because the operations can be initiated before previous ones are completed and the order they occur in is not guaranteed. For the same reason, there are no methods in the AsynchronousFileChannel API that set or query the position, as there are in FileChannel.

In addition to the read and write methods, an asynchronous lock method is also supported, so that a file can be locked for exclusive access without having to block in the current thread (or poll using tryLock) if another thread currently holds the lock.

Asynchronous channel groups

Each asynchronous channel constructed belongs to a channel group that shares a pool of Java threads, which are used for handling the completion of initiated asynchronous I/O operations. This might sound like a bit of a cheat, because you could implement most of the asynchronous functionality yourself in Java threads to get the same behaviour, and you'd hope that NIO.2 could be implemented purely using the operating system's asynchronous I/O capabilities for better performance. However, in some cases, it's necessary to use Java threads: for instance, the completion-handler methods are guaranteed to be executed on threads from the pool.

By default, channels constructed with the open() methods belong to a global channel group that can be configured using the following system variables:

  • java.nio.channels.DefaultThreadPoolthreadFactory, which defines a java.util.concurrent.ThreadFactory to use instead of the default one
  • java.nio.channels.DefaultThreadPool.initialSize, which specifies the thread pool's initial size

Three utility methods in java.nio.channels.AsynchronousChannelGroup provide a way to create new channel groups:

  • withCachedThreadPool()
  • withFixedThreadPool()
  • withThreadPool()

These methods take either the definition of the thread pool, given as a java.util.concurrent.ExecutorService, or a java.util.concurrent.ThreadFactory. For example, the following call creates a new channel group that has a fixed pool of 10 threads, each of which is constructed with the default thread factory from the Executors class:

1
2
AsynchronousChannelGroup tenThreadGroup =
    AsynchronousChannelGroup.withFixedThreadPool(10, Executors.defaultThreadFactory());

The three asynchronous network channels have an alternative version of the open() method that takes a given channel group to use instead of the default one. For example, this call tells channel to use the tenThreadGroup instead of the default channel group to obtain threads when required by the asynchronous operations:

1
2
AsynchronousServerSocketChannel channel =
    AsynchronousServerSocketChannel.open(tenThreadGroup);

Defining your own channel group allows finer control over the threads used to service the operations and also provides mechanisms for shutting down the threads and awaiting termination. Listing 3 shows an example:

Listing 3. Controlling thread shutdown with a channel group
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// first initiate a call that won't be satisfied
channel.accept(null, completionHandler);
// once the operation has been set off, the channel group can
// be used to control the shutdown
if (!tenThreadGroup.isShutdown()) {
    // once the group is shut down no more channels can be created with it
    tenThreadGroup.shutdown();
}
if (!tenThreadGroup.isTerminated()) {
    // forcibly shutdown, the channel will be closed and the accept will abort
    tenThreadGroup.shutdownNow();
}
// the group should be able to terminate now, wait for a maximum of 10 seconds
tenThreadGroup.awaitTermination(10, TimeUnit.SECONDS);

The AsynchronousFileChannel differs from the other channels in that, in order to use a custom thread pool, the open()method takes an ExecutorService instead of an AsynchronousChannelGroup.

Asynchronous datagram channels and multicasting

The final new channel is the AsynchronousDatagramChannel. It's similar to the AsynchronousSocketChannel but worth mentioning separately because the NIO.2 API adds support for multicasting to the channel level, whereas in NIO it is only supported at the level of the MulticastDatagramSocket. The functionality is also available in java.nio.channels.DatagramChannel from Java 7.

An AsynchronousDatagramChannel to use as a server can be constructed as follows:

1
AsynchronousDatagramChannel server = AsynchronousDatagramChannel.open().bind(null);

Next, we set up a client to receive datagrams broadcast to a multicast address. First, we must choose an address in the multicast range (from 224.0.0.0 to and including 239.255.255.255), and also a port that all clients can bind to:

1
2
3
// specify an arbitrary port and address in the range
int port = 5239;
InetAddress group = InetAddress.getByName("226.18.84.25");

We also require a reference to which network interface to use:

1
2
// find a NetworkInterface that supports multicasting
NetworkInterface networkInterface = NetworkInterface.getByName("eth0");

Now, we open the datagram channel and set up the options for multicasting, as shown in Listing 4:

Listing 4. Opening a datagram channel and setting multicast options
1
2
3
4
5
6
7
8
9
10
// the channel should be opened with the appropriate protocol family,
// use the defined channel group or pass in null to use the default channel group
AsynchronousDatagramChannel client =
    AsynchronousDatagramChannel.open(StandardProtocolFamily.INET,  tenThreadGroup);
// enable binding multiple sockets to the same address
client.setOption(StandardSocketOption.SO_REUSEADDR, true);
// bind to the port
client.bind(new InetSocketAddress(port));
// set the interface for sending datagrams
client.setOption(StandardSocketOption.IP_MULTICAST_IF, networkInterface);

The client can join the multicast group in the following way:

1
MembershipKey key = client.join(group, networkInterface);

The java.util.channels.MembershipKey is a new class that provides control over the group membership. Using the key you can drop the membership, block and unblock datagrams from certain addresses, and return information about the group and channel.

The server can then send a datagram to the address and port for the client to receive, as shown in Listing 5:

Listing 5. Sending and receiving a datagram
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// send message
ByteBuffer message = ByteBuffer.wrap("Hello to all listeners".getBytes());
server.send(message, new InetSocketAddress(group, port));
 
// receive message
final ByteBuffer buffer = ByteBuffer.allocate(100);
client.receive(buffer, null, new CompletionHandler<SocketAddress, Object>() {
    @Override
    public void completed(SocketAddress address, Object attachment) {
        System.out.println("Message from " + address + ": " +
            new String(buffer.array()));
    }
 
    @Override
    public void failed(Throwable e, Object attachment) {
        System.err.println("Error receiving datagram");
        e.printStackTrace();
    }
});

Multiple clients can also be created on the same port and joined to the multicast group to receive the datagrams sent from the server.

Conclusion

NIO.2's asynchronous channel APIs provide a convenient and standard way of performing asynchronous operations platform-independently. They allow application developers to write programs that use asynchronous I/O in a clear manner, without having to define their own Java threads and, in addition, may give performance improvements by using the asynchronous support on the underlying OS. As with many Java APIs, the amount that the API can exploit an OS's native asynchronous capabilities will depend on the support for that platform.


source - https://www.ibm.com/developerworks/library/j-nio2-1/index.html







NIO.2 introduced asynchronous i/o.

Asynchronous I/O is an approach to non-blocking i/o that is not supported by NIO.

NIO: selectors / reactor pattern

NIO.2: completion handlers / proactor pattern

Thus when on Windows, NIO.2 uses I/O Completion Ports, which should boost performance. Except, nobody knows, because nobody uses Windows on the server side, and if they do, they probably do so because they are heavily invested in .net, and for that reason will most likely not consider using Java.


source - https://stackoverflow.com/questions/25537675/java-what-exactly-is-the-difference-between-nio-and-nio-2

'Development > Java' 카테고리의 다른 글

JAVA - NIO.2  (0) 2018.09.29
Java 8 - Memory Management  (0) 2018.09.16
Java - version history  (0) 2018.09.16
Java - Underscores in Numeric Literals  (0) 2018.08.11
java - Xms Xmx  (0) 2018.07.23
Java - Executor vs Thread  (0) 2018.07.20
Posted by linuxism

Tomcat - NIO

Web/WAS 2018.09.29 09:28


In HTTP 1.1, all connections between the browser and the server are considered persistent unless declared otherwise. Persistence, in this context, means to use a single TCP connection to send and receive multiple HTTP requests/responses, as opposed to opening a new connection for every single request/response pair.

In tomcat, the default HTTP connector is blocking and follows a one thread per connection model. This means that in order to serve 100 concurrent users, it requires 100 active threads. We end up wasting resources (the thread) because connections may not be used heavily, but just enough to avoid a timeout.

Opposed to this is the relatively new NIO or non blocking connector. This connector has a couple of poller threads used to keep the connection alive for all connected users while worker threads are called whenever data (a new HTTP request) is available. This model leads to a much better sharing of resources (threads) and a larger number of concurrent users can be served from the same server.

In order to configure tomcat to use the Non-blocking NIO connector instead of the default blocking BIO one simply change the value of the protocol attribute of the connector tag in the server.xml from HTTP/1.1 to org.apache.coyote.http11.Http11NioProtocol

<Connector connectionTimeout="20000" maxThreads="1000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>

To verify that you indeed are using the NIO connector, take a look at the startup logs. You should see lines similar to this.

Mar 28, 2014 3:59:04 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Mar 28, 2014 3:59:04 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector

Use VisualVM to look at the threads being created in both cases. You’ll find NIO to use threads much more efficiently.


source - https://dzone.com/articles/understanding-tomcat-nio






default(HTTP/1.1) on the Tomcat 7.0.91

9월 29, 2018 9:42:26 오전 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["http-bio-8080"]

9월 29, 2018 9:42:26 오전 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["http-bio-8443"]

9월 29, 2018 9:42:27 오전 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["ajp-bio-8009"]


default(org.apache.coyote.http11.Http11NioProtocol) on the Tomcat 9.0.8

9월 29, 2018 9:56:08 오전 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["http-nio-8080"]

9월 29, 2018 9:56:08 오전 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector

INFO: Using a shared selector for servlet write/read

9월 29, 2018 9:56:08 오전 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["https-jsse-nio-8443"]

9월 29, 2018 9:56:08 오전 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector

INFO: Using a shared selector for servlet write/read

9월 29, 2018 9:56:08 오전 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["ajp-nio-8009"]



references 

https://tomcat.apache.org/tomcat-8.0-doc/ssl-howto.html

https://en.wikipedia.org/wiki/Java_Secure_Socket_Extension


'Web > WAS' 카테고리의 다른 글

Tomcat - NIO  (0) 2018.09.29
was - certbot tomcat  (0) 2017.02.21
tomcat - At least one JAR was scanned for TLDs yet contained no TLDs  (0) 2016.10.12
tomcat - jmx, jstatd  (0) 2016.04.28
tomcat - Resource Links  (0) 2015.12.17
tomcat - Using resources  (0) 2015.12.12
Posted by linuxism