Background
In my java application, I have reasonably large amounts of data sitting in ConcurrentHashMap.
Now, I need to give this data to a consumer client in XML format when the client connects to my application via a TCP port.
So in a nutshell - I have a TCP Server that a client connects to. As soon as the client connects, I have to read all the data in the Map and spit it out in XML format (custom) on the TCP port. The data in the Map keeps getting updated automatically from somewhere else using worker threads etc, so I have to keep sending the fresh data over and over to the client on this tcp port.
I want to implement a solution that is memory and cpu efficient - Mainly I would prefer not to generate too many immutable objects in the heap. .
NOTE:In future I might have to support multiple output formats (like comma separated or Json or HL7 etc). To keep it simple lets say there's different TCP port the client can connect for a specific format.
Question
With that said - I've been looking around for the best solution for my TCP Server implementation and data conversion process from ConcurrentHashMap to XML.
For TCP Server, people talk about
NETTY
Kryonet
Apache MINA
My client will be some third party, so i think kryonet is out, since client wont do the "register" business needed by Kryonet. So out of MINA and NETTY, which one is scalable and easier to understand? Any other suggestion?
FOR data conversion from ConcurrentHashMap to XML, I was thinking of using XSTREAM
Any other suggestion?
Thanks
If you have 100s or 1000s of connections you should start to consider scalability. However if you have small number of connections, using plain Sockets may be all you need.
If only a portion of the data is changing, you better off sending only the data which has changed, or at least only regenerating the XML which has changed.
How fast does it need to be? It seems like you should be able to create something that returns in less than 10ms (plus RTT) just using tomcat and a standard framework like spring-mvc. Use JAXB to convert objects to XML. If you want to support additional output formats like json it's trivial (use Jackson library for that, api is similar to JAXB).
I had a co-worker that tried the socket server approach and in the end we used tomcat because it was almost as fast and the QPS was more stable/predictable.
Related
I have developed an embedded system which sends data to a server as TCP requests. I can't use more-frequent HTTP requests, because of its data overhead. Less package length will result in less energy consumption and less communication expenses.
The server has to listen to a special port, get the data from device and store in a table.
As I explored, Java servlets + Apache Tomcat is a popular solution but in this case should not be used, because a Java servlet is more suitable for HTTP-based connections.
Is there a better solution for this type of communication?
Please take a look at Sockets. They are on the Application layer TCP/IP model and they provide reliable, bidirectional communication, with no data overhead. However, you will need to design a tiny protocol for the communication to much your needs.
Most probably this will suffice your needs, but if you decide to go with the HTTP solution, keep in mind Websockets which is an interesting solution, will diminish the overhead of the HTTP protocol (but they won't eliminate it, the overhead will remain at around 2-10 bytes.). Unfortunately, Java SE doesn't built in provide support for Websockets so you will need to use an external library.
PS: Both options support encryption over TLS but I didn't mention it, cause it adds a noticeable overhead (at least during the initialization of the connection)
For testing purposes I want to create a socket server which will contain 10+ million concurrent socket connections spread over X number of ec2 instance on AWS (still deciding on either node.js with JXCore, Java, or Erlang). These sockets will be sending messages randomly to one other socket every 10 seconds. I am just having trouble understanding how I can store and read these sockets effectively.
The two options I can see are to store the socket objects in something like a map in the application itself, or store the sockets in a fast database such as Redis. The problem with having sockets stored in a data structure inside of the application is will it be able to scale, be robust, and how will the read performance be when millions of sockets need to find one another. And If I store them in something like a database such as redis there must be a network call every time because Socket A needs to know where Socket B is located to send the message. This I fear will bring down performance considerably.
I was wondering what the best practices are for scalable socket servers as I can't find anything on the internet which answer this question. Every socket server I find online simple broadcasts to every other socket instead of having specific sockets and only contain something like 10 sockets.
If you want this application to be distributed across a number of nodes there need to be a way to at least determine destination node. If it may be a pure function of source and current packet, no central storage is required, which is the best possible solution.
In the rest of the cases central storage is inevitable but some optimizations may be applied to reduce access to it. Local sockets can be easily stored in a local map (ets or mnesia in erlang, shared singleton map in other languages) and checked first. Source may be told to cache destination address so the packet would contain all the necessary information. Or that destination cache could be stored on the source socket node to not depend on client behavior. This cache may be used for routing and only if the route operation was unsuccessful the central storage may be accessed.
The may be some other optimizations which depend on what's available in your case.
I have a server that needs to stream data to multiple clients as quickly as possible in the Observer pattern.
At least 200 messages need to be sent to each client per second until the client disconnects from the sever, and each message consists of 8 values of several primitive types. Because each message needs to be sent as soon as it is created, messages cannot be combined into one large message. Both the server and the clients reside on the same LAN.
Which technology is more suitable to implement streaming under this situation, RMI or socket?
The overhead of RMI is significant so it would not be suitable. It would be better to create a simple protocol and use sockets to send the data.
Depending on the latency that is acceptable you should configure socket buffer sizes and turn off Nagle algorithm.
I would not use RMI for this, RMI is just there for Remote Method Invocation, i.e. when the client wants to execute a method (i.e. some business logic) on the server side.
Sockets are OK for this, but you might want to consider JMS (Java Messaging Service) for this specific scenario. JMS supports something called a Topic, which is essentially a broadcast to all listeners interested in that topic. It is also generally optimised to be very fast.
You can use something like Apache ActiveMQ to achieve what you want. You also have lots of options such as persistence (in case the queue goes down messages remain in queue), message expiry (in case you want the messages to become outdated if a client does not pick them up) etc.
You can obviously implement all this using normal Sockets and take care of everything yourself, but JMS provides all this for you. You can send text or binary data, or even serialized object (I don't personally recommend the latter).
RMI is a request/response protocol, not a streaming protocol. Use TCP.
I have two Java netty servers that need to pass lots of messages between themselves fairly frequently and I want it to happen fairly promptly.
I need a TCP socket between the two servers that I can send these messages over.
These messages are already-packed byte[] arrays and are self-contained.
The servers are currently both running HTTP interfaces.
What is the best way to do this?
For example, websockets might be a good fit yet I am unable to find any websocket client examples in netty..
I'm a netty newbie so would need some strong simple examples. It surely can't be so hard?!
Since you mentioned HTTP, you could look at the HttpStaticFileServer in the examples.
When established, a TCP connection is a Channel. To send your messages, you need to write them to a ChannelBuffer and call channel.write.
Of course, this does not cover message borders. The Telnet example shows a case, where the messages are delimited by the newline character.
well, i am developing a single server multiple-client program in java. My problem is can i use single stream for all the clients or do i have to create a seperate stream for each client?
please help
thank you
Typically you'd need a stream per client. In some cases you can get away with UDP and multicasting, but it doesn't sound like a great idea for a chat server.
Usually it's easy to get a stream per client with no extra work, because each client will connect to the server anyway, and a stream can easily be set up over that connection.
Yes, you can but I think it would be harder.
If you're using java.net.ServerSocket then each client accepted through:
Socket client = server.accept();
Will have it's own stream so you don't have to do anything else.
Is there a real need for a single stream for all clients or is just something you think it would help.
For the later it could cause more problems than those is solve.
Can you do it?
Yes, as Jon Skeet said, you can use multicasting.
Should you do it?
That depends on what you are using the streams for.
For most client server applications, you will need a stream per client to maintain independent communications. Of course, there are applications where using multicasting is the right approach, such as live video streaming. In such a case, you would not want to overwhelm your network while streaming the same data to multiple clients. Of course, even in this case there will typically be a single control channel of some sort between each client and server.