1. 程式人生 > >使用 Netty 寫一個 HTTP Server

使用 Netty 寫一個 HTTP Server

前一段時間需要寫一個 HTTP Server,之前用 Akka 實現了一個,但是 Netty 更能支撐高併發,連 Spark 2.0 也把 Akka 換成了 Netty 進行網路傳輸,所以現在再擼一個 Netty 的 Server。

閒話少說,直接開搞,首先將 Netty 加入 sbt:

"io.netty" % "netty-all" % "4.1.25.Final"

我們需要定義兩個組 bossGroupworkerGroup,這個兩個組實際上是兩個執行緒組,負責的不同。bossGroup 負責獲取客戶端連線,接收到之後會將該連線轉發到 workerGroup 進行處理。

// if there are multiple `ServerBootstrap`, we should set more than one thread
val bossGroup = new NioEventLoopGroup(1)
val workerGroup = new NioEventLoopGroup()

然後通過一個啟動服務類 ServerBootstrap 進行初始化啟動:

val http = new ServerBootstrap()
  .group(bossGroup, workerGroup)
  .channel(classOf[NioServerSocketChannel])
  .childHandler(new
HttpServerInitializer(writer))

其中 HttpServerInitializer 是我們自定義實現的一個服務初始化器,繼承了 ChannelInitializer 類,這個類通過 ChannelPipieline 設定初始化鏈,包括超時時間、編解碼和處理 HTTP 請求的設定。

class HttpServerInitializer(private val writer: EventWriter) extends ChannelInitializer[SocketChannel] {
  private val logger = Logger(this.getClass)

  override
def initChannel(ch: SocketChannel) { logger.debug("Initialize http server channel.") ch.pipeline.addLast( new ReadTimeoutHandler(1), new HttpRequestDecoder(8192, 8192, 8192), new HttpResponseEncoder(), new HttpServerHandler(writer) ) } }

這裡的 HttpServerHandler 就是主要的 HTTP 請求處理類,類似於 Spring 中的攔截器,包含處理請求、轉發的相關功能:

class HttpServerHandler(private val writer: EventWriter)
  extends SimpleChannelInboundHandler[Object] {
  private val logger = Logger(this.getClass)

  private def forwardMessage(req: HttpRequest) {
    if (req.decoderResult.isSuccess) {
      val uri = req.uri
      logger.debug(s"Forward message, url=$uri")
      writer.putEvent(System.currentTimeMillis, uri)
    } else {
      logger.error(s"Request decode failure, result=${req.decoderResult}")
    }
  }

  override def channelReadComplete(ctx: ChannelHandlerContext) {
    ctx.flush
  }

  override def channelRead0(ctx: ChannelHandlerContext, msg: Object) {
    if (msg.isInstanceOf[HttpRequest]) {
      logger.debug("Flush and finish requests.")
      val response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT, Unpooled.EMPTY_BUFFER)
      ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE)
      forwardMessage(msg.asInstanceOf[HttpRequest])
    }
  }

  override def exceptionCaught(ctx: ChannelHandlerContext, error: Throwable) {
    logger.error(s"Http handle error, error=$error")
    ctx.close
  }

}

注意這裡是通過 channelRead0 處理請求並給客戶端返回,我在這裡的處理是不論什麼內容進來,都給客戶端返回一個 NO_CONTENT,而實際的處理會進行轉發,這樣是為了防止阻塞,首先給客戶端返回結果,然後具體的一些耗時操作放在 forwardMessage 內。

上面的內容就是一些初始化啟動類,準備好這些以後我們需要把初始化伺服器繫結到服務埠,這個埠用來接收 HTTP 請求:

val f = http.bind(port).sync().channel()
logger.info(s"Start server, port=$port")
f.closeFuture().sync()

如果接收 HTTP 請求的時候出錯,我們還需要釋放資源:

bossGroup.shutdownGracefully()
workerGroup.shutdownGracefully()

以上完整實現了一個 HTTP Server,具體的過程是:

  1. 定義兩個執行緒組: bossGroupworkerGroup
  2. 準備一個繼承自 ChannelInitializer 服務處理初始化類,這個類設定超時編解碼以及具體處理 HTTP 請求的類
  3. 定義一個服務啟動類 ServerBootstrap,設定執行緒組和 handler
  4. 把服務啟動類繫結到某個埠號,HTTP Server 啟動

完整程式碼見 producer,我是通過 Netty 的 HTTP Server 接收 GET 請求,處理之後將訊息傳送到 AWS Kinesis(類似於 Kafka)中。

相關推薦

使用 Netty 一個 HTTP Server

前一段時間需要寫一個 HTTP Server,之前用 Akka 實現了一個,但是 Netty 更能支撐高併發,連 Spark 2.0 也把 Akka 換成了 Netty 進行網路傳輸,所以現在再擼一個 Netty 的 Server。 閒話少說,直接開搞

一個類SpringBoot的HTTP框架:幾十行程式碼基於Netty搭建一個 HTTP Server

> 本文已經收錄進 : [https://github.com/Snailclimb/netty-practical-tutorial](https://github.com/Snailclimb/netty-practical-tutorial) (Netty 從入門到實戰:手寫 HTTP Serve

windows服務呼叫Owin一個http API 報錯 呼叫的目標發生了異常。

在使用owin開發windows服務的時候,在部署的時候報如下錯誤: 2016-07-02 11:39:48:  讀取配置資訊失敗:呼叫的目標發生了異常。   在 System.RuntimeMethodHandle.InvokeMethod(Object tar

python3.6一個http介面服務,給別人呼叫

# -*- coding:utf-8 -*- # -*- created by: mo -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler)

Linux上快速啟動一個HTTP server

我們可以利用python來快速啟動一個httpserver。 # 8999是伺服器監聽的埠號 python -m SimpleHTTPServer 8999 python一共提供了三種Web伺服器

用vetr.x一個HTTP介面介面卡, 對接各種形式介面

用vetr.x寫一個HTTP介面介面卡, 對接各種形式介面 專案地址:https://github.com/hjx601496320/transmit 業務說明 在日常開發工作中,我們經常會遇到要和各種第三方除錯介面的情況,如果是簡單的幾個介面還好,程式碼寫起來很快就寫好了。但是如果在某一種業務情況下,比如支

一個HTTP框架:兩個類實現基本的IoC功能

> [jsoncat](https://github.com/Snailclimb/jsoncat): 仿 Spring Boot 但不同於 Spring Boot 的一個輕量級的 HTTP 框架 國慶節的時候,我就已經把 jsoncat 的 IoC 功能給寫了,具體可以看這篇文章《手寫“Spring

曹工雜談:花了兩天時間,一個netty實現的http客戶端,支援同步轉非同步和連線池(1)--核心邏輯講解

# 背景 先說下寫這個的目的,其實是好奇,dubbo是怎麼實現同步轉非同步的,然後瞭解到,其依賴了請求中攜帶的請求id來完成這個連線複用;然後我又發現,redisson這個redis客戶端,底層也是用的netty,那就比較好奇了:netty是非同步的,上層是同步的,要拿結果的,同時呢,redis協議也不可能

http-server:一個簡單的零配置命令行的http服務器

.gz 例如 選項 輸出 csharp ava 開發 日誌 art 首先簡介一下http-server: http-server是一個簡單的零配置命令行http服務器,他對於生產使用來說足夠強大,他是簡單和可刪節足以用於測試,足夠簡單易用,而且可用於本地開發 1、首先

繞過010Editor網絡驗證(用python做一個仿真http server真容易,就幾行代碼)

headers redirect 如果 table 本地 align cnn 破解版 resp 010Editor是一款非常強大的十六進制編輯器,尤其是它的模板功能在分析文件格式時相當好用!網上現在也有不少010Editor的破解版,如果沒錢或者舍不得花錢買授權的話,去官方

Tinyhttpd - 超輕量型Http Server,使用C語言開發,全部代碼只有502行(包括註釋),附帶一個簡單的Client

net 事件驅動 免費 好評 lua ansi c tor 這一 通過 - 2. Tinyhttpd tinyhttpd是一個超輕量型Http Server,使用C語言開發,全部代碼只有502行(包括註釋),附帶一個簡單的Client,可以通過閱讀這段代碼理解一個 Htt

python3 使用http.server模塊 搭建一個簡易的http服務器

test class ont elf resp his local and height from http.server import HTTPServer, BaseHTTPRequestHandler import json data = {‘result‘:

使用http-server開啟一個本地服務器

完成後 前言 -s html ble 目標 start 本地服務 hit 前言 在寫前端頁面中,經常會在瀏覽器運行HTML頁面,從本地文件夾中直接打開的一般都是file協議,當代碼中存在http或https的鏈接時,HTML頁面就無法正常打開,為了解決這種情況,需要在在本地

走通HTTP server

int clas 靜態 sockfd split tin itl sets exceptio HTTP server 2.0   1 接收客戶請求   2 解析客戶端請求   3 組合數據,形成HTTP response   4 將數據發送給客戶端 升級 :   1 多線程

從零一個Java WEB框架(二)Server層 優化

該系列,其實是對《架構探險》這本書的實踐。本人想記錄自己的學習心得所寫下的。 從一個簡單的Servlet專案開始起步。對每一層進行優化,然後形成一個輕量級的框架。 每一篇,都是針對專案的不足點進行優化的。 專案已放上github 上一篇地

一個簡單的零配置命令行HTTP服務器 - http-server (nodeJs)

sil call pan sts 退出 nod package 分享圖片 htm http-server 是一個簡單的零配置命令行HTTP服務器, 基於 nodeJs. 如果你不想重復的寫 nodeJs 的 web-server.js, 則可以使用這個. 安裝 (全局安裝

一個簡單的零配置命令列HTTP伺服器 - http-server (nodeJs)

http-server 是一個簡單的零配置命令列HTTP伺服器, 基於 nodeJs. 如果你不想重複的寫 nodeJs 的 web-server.js, 則可以使用這個. 安裝 (全域性安裝加 -g) :  npm install http-serv

利用netty自己手一個tomcat

基於javaee基礎上執行的一個web容器 http  伺服器 socktet上支援 TCP/IP HTTP FTP 接受客戶端的一個http url請求,對應後臺有一個servlet netty屬於協議層,底層框架。 request  response 4.0版本 pu

利用Libev一個簡單的client和server程式

#ifndef _COMMON_H_ #define _COMMON_H_ #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> #inclu

Tomcat Server處理一個http請求的過程

查詢資料的時候先這個,有點用,摘錄下來 假設來自客戶的請求為:  http://localhost:8080/wsota/wsota_index.jsp 1) 請求被髮送到本機埠8080,被在那裡偵聽的Coyote HTTP/1.1 Connector獲得  2) Conn