<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • http服務器是什么,服務器組成部分介紹


    做了多年web開發,http真是熟悉的陌生人(經常在用,但是從頭到尾理清楚真的是很有難度的),其實http概述和netty中的http應用真有必要說下,一起聊聊netty實現tomcat的功能,請求服務的功能。

    http概述,Netty實現高性能的HTTP服務器

    (一)Http協議概述

    • 1.什么是Http協議

    HTTP是一個屬于【應用層】的面向對象的協議,由于其簡捷、快速的方式,適用于分布式超媒體信息系統。

    • 2.HTTP協議的主要特點

    支持客戶/服務器模式。

    簡單快速

    客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與

    服務器聯系的類型不同。由于HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。

    靈活

    HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

    無連接

    無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。

    無狀態

    HTTP協議是無狀態協議。無狀態是指協議對于事務處理沒有記憶能力。缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。從HTTP協議來講是無狀態的,其實在應用的時候,很多情況通過回話的方式還是有狀態的。

    (二)Http協議交互過程

    協議交互本質是指協議兩端(客戶端、服務端),互聯網上沒有協議是混亂的,正如如果現實中沒有法律也會打亂一樣。

    1.傳輸數據

    傳輸數據一般基于TCP/IP 實現,體現到開發語言上就是我們所熟悉的Socket 編程。

    2.交換數據

    交換數據本質是指,兩端(客戶端、服務端)能各自識別對方所發送的數據。那么這就需要制定一套【報文編碼】格式,雙方以該格式編碼數據發送給對方。

    Http 對應的Request 與Response報文

    http概述,Netty實現高性能的HTTP服務器
    http概述,Netty實現高性能的HTTP服務器

    注: 我們可以通過抓包工具(fiddler)可以直接看到該報文格式。

    報文約定好以后兩端都需要對其進行解碼和編碼操作

    http概述,Netty實現高性能的HTTP服務器

    3.Http協議內容組成

    請求方法

    方法描述GET請求指定的頁面信息,并返回實體主體。HEAD類似于get請求,只不過返回的響應中沒有具體的內容,用于獲取報頭POST向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。PUT從客戶端向服務器傳送的數據取代指定的文檔的內容。DELETE請求服務器刪除指定的頁面。CONNECTHTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。OPTIONS允許客戶端查看服務器的性能。TRACE回顯服務器收到的請求,主要用于測試或診斷。

    部分請求頭

    請求頭說明Host接受請求的服務器地址,可以是IP:端口號,也可以是域名User-Agent發送請求的應用程序名稱Connection指定與連接相關的屬性,如Connection:Keep-AliveAccept-Charset通知服務端可以發送的編碼格式Accept-Encoding通知服務端可以發送的數據壓縮格式Accept-Language通知服務端可以發送的語言

    部分響應頭

    響應頭說明Server服務器應用程序軟件的名稱和版本Content-Type響應正文的類型(是圖片還是二進制字符串)Content-Length實體報頭域用于指明實體正文的長度,以字節方式存儲的十進制數字來表示響應正文長度Content-Charset響應正文使用的編碼Content-Encoding響應正文使用的數據壓縮格式Content-Language響應正文使用的語言

    部分響應狀態

    狀態碼說明200響應成功302跳轉,跳轉地址通過響應頭中的Location屬性指定(JSP中Forward和Redirect之間的區別)400客戶端請求有語法錯誤,不能被服務器識別403服務器接收到請求,但是拒絕提供服務(認證失?。?04請求資源不存在500服務器內部錯誤

    http概述,Netty實現高性能的HTTP服務器

    (二)基于Netty 實現Http協議過程分析

    源碼:https://github.com/limingios/netFuture/tree/master/源碼/『互聯網架構』軟件架構-io與nio線程模型reactor模型(上)(53)/nio

    Http協議分為三部分:

    1.遠程數據傳輸

    2.報文編解碼

    3.業務處理

    但如果是開發基于Http普通應用,完全沒有必要重復造輪子,,我們只需實現業務即可?,F比較成熟的中間件有:Tomcat、Jetty、Jboos。這些中間有個缺點是較重,如果需要輕量實現可采用:netty 或JDK自還http 實現JDK Http源碼參見:com.sun.net.httpserver.HttpServer

    • netty 實現http

    源碼:nio/http中。

    1.初始ServerBootstrap

    2.通過ChannelInitializer 初始 pipeline

    3.基于SimpleChannelInboundHandler HttpServer處理類

    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.ServerSocketChannel;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;
    import io.netty.handler.codec.http.*;
    import io.netty.util.concurrent.Future;
    import io.netty.util.concurrent.GenericFutureListener;
    import java.net.ContentHandler;
    import java.util.concurrent.ThreadFactory;
    /**
    * Created by idig8.com
    */
    public class HttpSimpleServer {
    //open 啟動服務
    public void openServer() {
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.channel(NioServerSocketChannel.class);
    EventLoopGroup boss = new NioEventLoopGroup(1);
    EventLoopGroup work = new NioEventLoopGroup(8);
    bootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
    ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());
    ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536));
    ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());
    ch.pipeline().addLast("http-server", new HttpServerHandler());
    }
    });
    bootstrap.group(boss, work);
    try {
    ChannelFuture future = bootstrap.bind(8080).sync();
    System.out.println("服務啟動:8080");
    future.channel().closeFuture().sync();
    } catch (InterruptedException e) {
    e.printStackTrace();
    } finally {
    boss.shutdownGracefully();
    work.shutdownGracefully();
    }
    }
    private static class HttpServerHandler extends SimpleChannelInboundHandler {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
    FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=UTF-8");
    String html = "<!DOCTYPE html>n" +
    "<html lang="en">n" +
    "<head>n" +
    " <meta charset="UTF-8">n" +
    " <title>hello idig8.com</title>n" +
    "</head>n" +
    "<body>n" +
    "hello idig8.comn" +
    "</body>n" +
    "</html>";
    response.content().writeBytes(html.getBytes("UTF-8"));
    ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
    }
    public static void main(String[] args) {
    HttpSimpleServer simpleServer = new HttpSimpleServer();
    simpleServer.openServer();
    }
    }
    http概述,Netty實現高性能的HTTP服務器

    實現過程分析

    1. 建立連接讀取消息流
    2. 解碼Request
    3. 業務處理
    4. 編碼Response
    5. 返回消息關閉連接

    Channel 與 ChannelPipeline

    1.Channel:

    a. ServerSocketChannel

    b. SocketChannel

    2.pipeline:一個pipeline 當中包含了多個ChandlerHandler,而且是有順序的

    3.ChandlerHandler

    a. HttpRequestDecode:解碼請求

    b. HttpResponseEncode :編碼返回結果

    在 Netty 中每個 Channel 都有且僅有一個 ChannelPipeline 與之對應, 它們的組成關系如下:

    http概述,Netty實現高性能的HTTP服務器

    一個 Channel 包含了一個 ChannelPipeline, 而 ChannelPipeline 中又維護了一個由 ChannelHandlerContext 組成的雙向鏈表. 這個鏈表的頭是 HeadContext, 鏈表的尾是 TailContext,并且每個 ChannelHandlerContext 中又關聯著一個 ChannelHandler

    bootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
    ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());
    ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536));
    ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());
    ch.pipeline().addLast("http-server", new HttpServerHandler());
    }
    });

    HttpRequest 在netty 當中的表示結構

    http概述,Netty實現高性能的HTTP服務器

    HttpResponse在netty 當中的結構

    http概述,Netty實現高性能的HTTP服務器

    PS:說了下http協議和如何通過netty完成http服務。

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费