使用 Netty 寫一個 HTTP Server
前一段時間需要寫一個 HTTP Server,之前用 Akka 實現了一個,但是 Netty 更能支撐高併發,連 Spark 2.0 也把 Akka 換成了 Netty 進行網路傳輸,所以現在再擼一個 Netty 的 Server。
閒話少說,直接開搞,首先將 Netty 加入 sbt:
"io.netty" % "netty-all" % "4.1.25.Final"
我們需要定義兩個組 bossGroup
和 workerGroup
,這個兩個組實際上是兩個執行緒組,負責的不同。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,具體的過程是:
- 定義兩個執行緒組:
bossGroup
和workerGroup
- 準備一個繼承自
ChannelInitializer
服務處理初始化類,這個類設定超時編解碼以及具體處理 HTTP 請求的類 - 定義一個服務啟動類
ServerBootstrap
,設定執行緒組和 handler - 把服務啟動類繫結到某個埠號,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