What is the appropriate architecture for building a multi-tenant client-server application?

I am developing an application that entails a single server and a large number of clients. I am using the Java Socket Programming API to accomplish this task. At the moment, I am considering the possibility of restructuring the entire project of my application, because I just do not think that it is structured in the most efficient way, and I would like to receive some recommendations on the optimal path.

Current implementation

I have one ServerSocket located on port 5000, and the stream containing the socket just works continuously and accepts any connection. Then it starts a new server thread (based on a synchronized table of available ports), which processes communication with this client, and then blocks again for ServerSocket.accept() .

Threads generated from this main thread also contain ServerSocket and are used as a means to handle multiple connections simultaneously.

Now the client thread simply connects to port 5000, receives the next available port as a response, then disconnects from port 5000 (by calling Socket.close() ) and reconnects to the port that the server said.

My question

Is this the most optimal way (or, even better, even reasonable?) To handle multiple clients on the same server? Or am I just opening ServerSocket on all available ports and just listening all the time? Perhaps something I haven't thought about yet?

Adding

I am trying to think in terms of very large client-server applications such as MMORPG or some kind of chat application in order to understand how much I can implement my implementation. For example, I try to ask myself: "Although this may work, would it be a good solution if there was a large user base in this application?" At the same time, it would be easier for me to understand the optimal nature of the solution if I could see how it will work on a large scale by, say, millions of users.

+4
source share
4 answers

I don’t understand why you will need to use a new ServerSocket every time the main one accepts the connection. Why don't you just use the socket returned by accept() (as described in the Java tutorial )?

In addition, instead of starting a new thread for each client, you should use a thread pool. This would avoid the constant creation of new threads and avoid starting too many threads and push your server to the knees.

This architecture is not the best to handle a huge number of users. Using asynchronous I / O is probably the best solution if you really need that kind of scalability, but I don't have much experience with this.

+6
source

When you think about server architecture, the first question is to estimate how much memory and pre-processing power is required for a single connection. The second is the number of simultaneous connections. After multiplication, we can decide if one machine is enough or if a cluster is needed.

Then we decide if we can provide a stream (about 128..512 Kbytes) for the connection. If possible, the classic single-threaded connection is OK. If we cannot, then an asynchronous architecture based on NIO or NIO2 is better suited.

After making basic decisions, we can choose the appropriate libraries and frameworks. To do everything from scratch is more interesting, but it will take so much time that the result may be of interest to anyone at the time of its achievement.

+3
source

I agree with your following suggestion because the only server on port 5000 is the bottleneck:

Or should I just just open ServerSocket on all available ports and just listen constantly?

I prefer the serverocket pool.

+1
source

Use JMS (in my case its ActiveMq) will reach the goal. You may have load balancing and easily crash

+1
source

Source: https://habr.com/ru/post/1443964/


All Articles