简体   繁体   English

Java中的套接字最佳实践

[英]Socket best practices in Java

Writing any kind of web server in Java (be it a webserver, RESTful webapp or a microservice) you get to use Sockets for dual channel communication between client and server. 用Java编写任何类型的Web服务器(无论是Web服务器,RESTful webapp还是微服务),您都可以使用Sockets在客户端和服务器之间进行双通道通信。 Using the common Socket and ServerSocket class is trivial, but since Sockets are blocking, you end up creating a thread for each request. 使用通用的SocketServerSocket类是微不足道的,但由于套接字是阻塞的,因此最终会为每个请求创建一个线程。 Using this threaded system, your server will work perfectly but won't scale very well. 使用此线程系统,您的服务器将完美地工作,但不会很好地扩展。 The alternative is using Streams by means of SocketChannel , ServerSocketChannel and Selector , and is clearly not as trivial as common Sockets. 另一种方法是通过SocketChannelServerSocketChannelSelector使用Streams,显然不像普通套接字那样简单。

My question is: which of these two systems are used in production ready code? 我的问题是:这两个系统中的哪一个用于生产就绪代码? I'm talking about medium to big projects like Tomcat, Jetty, Sparkjava and the like? 我在谈论像Tomcat,Jetty,Sparkjava等大中型项目? I suppose they all use the Stream approach, right? 我想他们都使用Stream方法,对吧?

To make a web server really scalable, you'll have to implement it with non-blocking I/O - which means that you should make it in such a way that threads will never get blocked waiting for I/O operations to complete. 为了使Web服务器真正具有可伸缩性,您必须使用非阻塞I / O来实现它 - 这意味着您应该以这样的方式实现它,即线程永远不会被阻塞,等待I / O操作完成。

Threads are relatively expensive objects. 线程是相对昂贵的对象。 For example, for each thread memory needs to be allocated for its call stack. 例如,对于每个线程,需要为其调用堆栈分配内存。 By default this is in the order of one or a few MB. 默认情况下,这是一个或几MB的顺序。 Which means that if you create 1000 threads, just the call stacks for all those threads will already cost you ~ 1 GB memory. 这意味着如果你创建了1000个线程,那么所有这些线程的调用堆栈就已经花费了大约1 GB的内存。

In a naïve server application, you might create a thread for each accepted connection (each client). 在天真的服务器应用程序中,您可以为每个接受的连接(每个客户端)创建一个线程。 This won't scale very well if you have many concurrent users. 如果您有许多并发用户,这将无法很好地扩展。

I don't know the implementation details of servers like Tomcat and Jetty, but they are most likely implemented using non-blocking I/O. 我不知道像Tomcat和Jetty这样的服务器的实现细节,但它们很可能是使用非阻塞I / O实现的。

Some info about non-blocking I/O in Tomcat: Understanding the Tomcat NIO Connector 有关Tomcat中非阻塞I / O的一些信息: 了解Tomcat NIO连接器

One of the most well-known non-blocking I/O libraries in Java is Netty . Java中最着名的非阻塞I / O库之一是Netty

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM