优化 Web 写入性能

This commit is contained in:
tursom 2019-11-21 16:26:46 +08:00
parent 367b3067c0
commit 3993a8af1f
7 changed files with 309 additions and 275 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ gradlew
gradlew.bat
build
*/build/
gradle.properties

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlinVersion = '1.3.50'
ext.kotlinVersion = '1.3.60'
repositories {
mavenLocal()
@ -11,6 +11,7 @@ buildscript {
}
allprojects {
apply plugin: "maven-publish"
apply plugin: 'java'
apply plugin: 'kotlin'
@ -46,4 +47,23 @@ allprojects {
artifacts {
archives sourcesJar
}
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/tursom/TursomServer")
credentials {
println project.findProperty("gpr.user")
//username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
username = "tursom"
password = project.findProperty("gpr.key") ?: System.getenv("PASSWORD")
}
}
}
publications {
gpr(MavenPublication) {
from(components.java)
}
}
}
}

View File

@ -152,7 +152,7 @@ class StringRadixTree<T> {
while (node != null) {
var nodeLocation = 0
while (nodeLocation < node.length) {
if (node[nodeLocation] != context.get) return null
if (context.end || node[nodeLocation] != context.get) return null
nodeLocation++
}
if (context.end) return node.value

View File

@ -5,6 +5,7 @@ import cn.tursom.core.buffer.ByteBuffer
import cn.tursom.web.AdvanceHttpContent
import cn.tursom.web.utils.Chunked
import io.netty.buffer.ByteBuf
import io.netty.buffer.CompositeByteBuf
import io.netty.buffer.Unpooled
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.http.*
@ -41,11 +42,12 @@ open class NettyHttpContent(
val responseMap = HashMap<String, Any>()
val responseListMap = HashMap<String, ArrayList<Any>>()
override val responseBody = ByteArrayOutputStream()
//override val responseBody = ByteArrayOutputStream()
override var responseCode: Int = 200
override var responseMessage: String? = null
override val method: String get() = httpMethod.name()
val chunkedList = ArrayList<ByteBuffer>()
val responseBodyBuf: CompositeByteBuf = ctx.alloc().compositeBuffer()!!
override fun getHeader(header: String): String? {
return headers[header]
@ -88,27 +90,36 @@ open class NettyHttpContent(
}
override fun write(message: String) {
responseBody.write(message.toByteArray())
responseBodyBuf.addComponent(Unpooled.wrappedBuffer(message.toByteArray()))
//responseBody.write(message.toByteArray())
}
override fun write(byte: Byte) {
responseBody.write(byte.toInt())
val buffer = ctx.alloc().buffer(1).writeByte(byte.toInt())
responseBodyBuf.addComponent(buffer)
//responseBody.write(byte.toInt())
}
override fun write(bytes: ByteArray, offset: Int, size: Int) {
responseBody.write(bytes, offset, size)
responseBodyBuf.addComponent(Unpooled.wrappedBuffer(bytes, offset, size))
//responseBody.write(bytes, offset, size)
}
override fun write(buffer: ByteBuffer) {
buffer.writeTo(responseBody)
//buffer.writeTo(responseBody)
responseBodyBuf.addComponent(if (buffer is NettyByteBuffer) {
buffer.byteBuf
} else {
Unpooled.wrappedBuffer(buffer.readBuffer())
})
}
override fun reset() {
responseBody.reset()
responseBodyBuf.clear()
}
override fun finish() {
finish(responseBody.buf, 0, responseBody.size())
finish(responseBodyBuf)
}
override fun finish(buffer: ByteArray, offset: Int, size: Int) {
@ -132,13 +143,13 @@ open class NettyHttpContent(
fun finish(response: FullHttpResponse) {
val heads = response.headers()
addHeaders(
heads, mapOf(
heads,
mapOf(
HttpHeaderNames.CONTENT_TYPE to "${HttpHeaderValues.TEXT_PLAIN}; charset=UTF-8",
HttpHeaderNames.CONTENT_LENGTH to response.content().readableBytes(),
HttpHeaderNames.CONNECTION to HttpHeaderValues.KEEP_ALIVE
)
)
ctx.writeAndFlush(response)
}

View File

@ -16,7 +16,7 @@ class NettyHttpHandler(
try {
handler.handle(handlerContext)
} catch (e: Throwable) {
handlerContext.write("${e.javaClass}: ${e.message}")
handlerContext.finish("${e.javaClass}: ${e.message}")
}
}

View File

@ -20,7 +20,7 @@ interface HttpContent {
val body: ByteBuffer?
val clientIp: SocketAddress
val method: String
val responseBody: ByteArrayOutputStream
//val responseBody: ByteArrayOutputStream
val cookieMap: Map<String, Cookie>
val realIp
get() = getHeader("X-Forwarded-For") ?: clientIp.toString().let { str ->
@ -46,7 +46,9 @@ interface HttpContent {
fun write(buffer: ByteBuffer)
fun reset()
fun finish() = finish(responseBody.buf, 0, responseBody.count)
//fun finish() = finish(responseBody.buf, 0, responseBody.count)
fun finish()
fun finish(buffer: ByteArray, offset: Int = 0, size: Int = buffer.size - offset)
fun finish(buffer: ByteBuffer) {
finish(buffer.array, buffer.readOffset, buffer.readAllSize())
@ -189,11 +191,11 @@ interface HttpContent {
finish(302)
}
fun noCache() {
setResponseHeader("Cache-Control", "no-cache")
}
fun noCache() = cacheControl(CacheControl.NoCache)
fun noStore() = cacheControl(CacheControl.NoStore)
fun noStore() {
setResponseHeader("Cache-Control", "no-store")
fun finish(msg: String) {
write(msg)
finish()
}
}

View File

@ -15,7 +15,7 @@ class EmptyHttpContent(
override val body: ByteBuffer? = null,
override val clientIp: SocketAddress = InetSocketAddress(0),
override val method: String = "GET",
override val responseBody: ByteArrayOutputStream = ByteArrayOutputStream(0),
//override val responseBody: ByteArrayOutputStream = ByteArrayOutputStream(0),
override val cookieMap: Map<String, Cookie> = mapOf()
) : HttpContent {
override fun getHeader(header: String): String? = null