Java Socket Server Essentials
To implement a production level java socket server, what are the potential gotchas that I have to be aware of?
For now I have got a basic code structure using the ServerSocket
and Socket
classes of core java.net
package. The server waits for a client and spawns a new thread for it.
A few things that I have thought of with my limited knowledge and experience is:
- Client disconnection detection and releasing client resources.
- Connection pooling, is this necessary or should I stick to the existing design.
- Server monitoring, logging and error recovery etc.
- Go with ready made framework like Apache Mina..??
What does your experience have to say?...
I think it depends on your use cases. But some thoughts:
Ready-made frameworks are a good way to go. As you've discovered, there are a lot of things to think about here. See below. Some possibilities (which implement very different strategies) are Jini (discovery-based recovery-oriented-computing framework) or queuing systems (which offer a distinct client/server decoupling and transactionality - JMS and/or AMQP-based)
Pooling is a major issue. It will prevent your server grinding to a halt in the face of too many clients. Can you use the Java ExecutorService ?
How can you monitor this server ? Can you use JMX and JConsole ? If you can, I would suggest this is a good first-step approach.
What happens if your server shuts down ? Will your clients have the ability to automatically reconnect ? Retry their outstanding requests ? Is it a good idea to retry a request (i.e. is it idempotent) ?
What are you transporting between the client and server ? Are they serialised Java classes ? If so, have you ensured that a simple recompile of a server doesn't require a recompile of the clients (via serialVersionUid
s). If you're transporting Strings and converting to byte arrays (a common scenario) do the client and server use the same character encoding ? If you're confused about encodings then read this and (possibly) enforce the same client/server encoding via the confusingly named file.encoding
property.
As ever with distributed computing, consider Peter Deutsch's Fallacies of Distributed Computing.
I'd be inclined to simply use a existing library to do all that for you. Perhaps the 2 main ones are Apache MINA and JBoss Netty, the latter is (reportedly) quicker and not prone to causing out of memory errors. A MINA send is asynchronous onto a queue which is flushed by another thread, it's therefore quite possible to get OoM even if you're careful. They have a JIRA about this IIRC.
Alternatively use HornetQ which is built on top of Netty but also provides a JMS facade in the client api hence you can run an inprocess messaging server which you can interact as per JMS. Quite convenient really.
精彩评论