Http, comet, WebSocket of e-commerce system system notes

Features of Http Protocol

1. Simplex communication, the server cannot push information to the client

2. Request-response mode

3 Stateless

Due to the above characteristics of http, the traditional mode Web system works in the way that the client sends a request and the server responds. This method does not meet the needs of many real-world applications, such as:

  • Monitoring system: background hardware hot swap, LED, temperature, voltage changes;
  • Instant messaging system: other users log in and send information;
  • Real-time quotation system: the content of the background database changes;

These applications all require that the server can transmit updated information to the client in real time without the client making a request. There are some solutions for "server push" technology in real applications. This article divides these solutions into two categories: one requires installing plug-ins on the browser side, transmitting information based on sockets, or using RMI and CORBA to make remote calls; The other type does not require the browser to install any plug-ins and is based on HTTP long connections.

When applying "server push" to a web program, the first consideration is how to receive and process information on the browser with limited functions:

  1. How the client receives and processes information, whether it needs to use sockets or use remote calls. Whether the client presents to the user an HTML page or a Java applet or Flash window. If you use sockets and remote calls, how to modify the display of HTML in combination with JavaScript.
  2. The information format of the communication between the client and the server, and what kind of error handling mechanism is adopted.
  3. Whether the client needs to support different types of browsers such as IE and Firefox, and whether it needs to support both Windows and Linux platforms.

Comet

One is to control the client's page to continuously make ajax requests, which should be well implemented. js timer can be implemented, and each request will respond to the client if there is updated data on the server side. However, this will cause serious pressure on the server. If there are too many online users, which server can bear the request every one or two seconds, this is definitely not realistic, or it is the most helpless way to achieve it.

So comet appeared. Comet technology is a general term for server push technology, but it is not a specific implementation method. Below I will talk about two implementation methods, which are based on the implementation of HTTP long connections.

The first method is called long-polling, which also uses ajax. To put it simply, the client sends a request using ajax, and the server will definitely open a thread, which will monitor the data to be requested from time to time. Whether there is a change, if there is a change, output the latest message to the client and close the link. After the client receives the message processing, it requests the server again. This cycle is repeated, so it is called long polling. One is naturally much better, it does not require constant ajax requests from the client, relieves a certain pressure on the server, and can be regarded as real-time.

The main difference between polling and long polling is how long the server takes to respond. Long polling typically maintains a connection for an extended period of time—usually seconds, but could be a minute or more. When an event occurs on the server, the response is sent and immediately closed, and polling restarts immediately .

The advantage of long polling over normal polling is that data is sent from the server to the client as soon as it is available. The request may wait a long time without any data being returned, but as soon as there is new data, it will be sent to the client. So there is no delay. If you've ever used a web-based chat program, or any program that claims to be "real-time", it most likely uses this technology

The other is the streaming method, which is similar to the long polling method, except that the streaming method is that after the client requests the server and establishes a link, the server will never close the link (until timeout, power failure or Other special cases) output to the client every time there is data, unlike long polling, which has to close the connection after each output to the client

Comet implementation bottleneck solution - server servlet thread blocking problem

At this point, you may think of another problem, that is, every time the client makes a request, a thread must be opened on the server side to monitor whether the data has changed. Even if the data will not change for a long time, this thread will still be Blocked here, the resources cannot be released, and the thread has nothing to do here. If there are too many users and too many threads, it will naturally cause the server's resources and memory to be insufficient. This is a problem, but since there is a problem, there is a solution.

现在有很多 Web 服务器是用 Java 构建的。一个原因是 Java 有一个丰富的本地线程模型。因此实现典型的每个连接一个线程的模型便非常简单。该模型对于 Comet 不大适用,但是,Java 对此同样有解决的办法。为了有效地处理 Comet,需要非阻塞 IO,Java 通过它的 NIO 库提供非阻塞 IO。两种最流行的开源服务器 Apache Tomcat 和 Jetty 都利用 NIO 增加非阻塞 IO,从而支持 Comet。然而,这两种服务器中的实现却各不相同。我们来看看 Tomcat 和 Jetty 对 Comet 的支持

目前有两种解决方法,第一种是利用Tomcat 和 Jetty这两种开源服务器对NIO的支持 代码实现和添加服务器支持可以参考http://www.ibm.com/developerworks/cn/web/wa-cometjava/,第二种则是Java 1.6 出来的Servlet3.0,Servlet3.0可以实现真正的异步处理,就是新开一个线程用于处理复杂业务,而servlet线程本身则继续往下执行直到结束之后,再返回servlet容器,待到另一条线程业务处理完之后,再向客户端输出结果。但是使用servlet3.0,需要tomcat7和以上才支持,servlet3.0的实现百度就有好多,就不在此多赘述了。只谈理论

NIO原理

IO

NIO

Core differences: Core differences:
Stream oriented processing Uses buffers
Blocking in processing Non blocking in processing
Good for: Good for:
High data volume with low simultaneous open file descriptor counts

(eg: less client connections with more data chunks per connection)

Less data volume with high simultaneous open file descriptor counts

(eg: More connections with smaller / infrequent “chunks” of data)

A quick glance at the summary of the Java NIO API reveals to us the core abstractions one should be familiar with when working with Java NIO. These are:

  • Buffers       : A container to hold data for the purposes of reading and or writing.
  • Channels   : An abstraction for dealing with an open connection to some component that is performing some kind of IO operation at a hardware level.
  • Charsets    : Contains charsets, decoders and encoders for translating between bytes and unicode.
  • Selectors   : A means to work with multiple channels via one abstraction.

Streams versus blocks

The most important distinction between the original I/O library (found in java.io.* ) and NIO has to do with how data is packaged and transmitted. As previously mentioned, original I/O deals with data in streams, whereas NIO deals with data in blocks.

stream-oriented I/O system deals with data one byte at a time. An input stream produces one byte of data, and an output stream consumes one byte of data. It is very easy to create filters for streamed data. It is also relatively simply to chain several filters together so that each one does its part in what amounts to a single, sophisticated processing mechanism. On the flip side, stream-oriented I/O is often rather slow.

block-oriented I/O system deals with data in blocks. Each operation produces or consumes a block of data in one step. Processing data by the block can be much faster than processing it by the (streamed) byte. But block-oriented I/O lacks some of the elegance and simplicity of stream-oriented I/O.

Three easy steps

Our first step is to get a channel. We get the channel from the FileInputStream:

1
2
FileInputStream fin = new FileInputStream( "readandshow.txt" );
FileChannel fc = fin.getChannel();------- IO是单向的,input或者output,在建立连接后,通过创建channel获取一个双向的通道,channel是双向的

The next step is to create a buffer:

1
ByteBuffer buffer = ByteBuffer.allocate( 1024 );

And, finally, we need to read from the channel into the buffer, as shown here:

1
fc.read( buffer );

Writing to a file

Writing to a file in NIO is similar to reading from one. We start by getting a channel from a FileOutputStream:

1
2
FileOutputStream fout = new FileOutputStream( "writesomebytes.txt" );
FileChannel fc = fout.getChannel();

Our next step is to create a buffer and put some data in it -- in this case, the data will be taken from an array called messagewhich contains the ASCII bytes for the string "Some bytes." (The buffer.flip() and buffer.put() calls will be explained later in the tutorial.)

1
2
3
4
5
6
ByteBuffer buffer = ByteBuffer.allocate( 1024 );
 
for (int i=0; i<message.length; ++i) {
      buffer.put( message[i] );
}
buffer.flip();

Our final step is to write to the buffer:

1
fc.write( buffer );

如果IO是系统的瓶颈,那么可以利用多线程充分使用cpu资源。

{
 ExecutorService executor = Excutors.newFixedThreadPollExecutor(100);//线程池

 ServerSocket serverSocket = new ServerSocket();
 serverSocket.bind(8088);
 while(!Thread.currentThread.isInturrupted()){//主线程死循环等待新连接到来
 Socket socket = serverSocket.accept();
 executor.submit(new ConnectIOnHandler(socket));//为新的连接创建新的线程
}

class ConnectIOnHandler extends Thread{
    private Socket socket;
    public ConnectIOnHandler(Socket socket){
       this.socket = socket;
    }
    public void run(){
      while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){死循环处理读写事件
          String someThing = socket.read()....//读取数据
          if(someThing!=null){
             ......//处理数据
             socket.write()....//写数据
          }

      }
    }
}

上面的代码是经典的单连接单线程模型。其实这也是所有使用多线程的本质:利用多核,当IO阻塞系统的时候,可以充分利用CPU的资源。这个模型如果单机线程数1000,其实ok的。不过这个模型主要的问题是严重依赖线程,线程是非常昂贵的资源,因为一个线程大约占用内容512k-1M,而且线程数过大,创建和销毁成本也高,线程之间切换也有一定的成本。

如果面对十万级,百万级连接,传统的BIO模型无能为力

NIO:利用一个线程管理selector,selector监听多个channel。减少了线程的数据,监听了更多的socket。理论上可以用一个线程处理所有的socket请求

NIO一个重要的特点是:socket主要的读、写、注册和接收函数,在等待就绪阶段都是非阻塞的,真正的I/O操作是同步阻塞的(消耗CPU但性能非常高)



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325401847&siteId=291194637