作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


接上一篇:fasthttp 中如何使用Transfer-Encoding: chunked 方式的流式内容输出

首先是找了一个库,封装了 linux 下的 sendfile 系统调用:github.com/hslam/sendfile

上代码:

  • go.mod 中:
replace (
github.com/valyala/fasthttp => github.com/ahfuzhang/compress v1.49.2
)
package main

import (
"bufio"
"bytes"
"fmt"
"io"
syslog "log"
"net"
"os"
"strconv"
"time" "github.com/hslam/sendfile"
"github.com/valyala/bytebufferpool"
"github.com/valyala/fasthttp"
) var fileToSend *os.File
var fileSize int64 func FasthttpHandler(ctx *fasthttp.RequestCtx) {
ctx.HijackSetNoResponse(true) // 不使用 fasthttp 框架的输出
//ctx.Hijack(func(c net.Conn) { // 这里会 go 出来一个协程执行 hijack 回调函数。 我改了一个版本,不配置就不会 go 出来协程
// log.Println("do nothing")
//})
//
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
buf.Reset()
buf.B = append(buf.B, "HTTP/1.1 200 OK\r\n"+
"Server: fasthttp\r\n"+
"Date: Thu, 26 Oct 2023 01:09:23 GMT\r\n"+
"Content-Type: text/plain\r\n"+
"Cache-Control: no-cache, no-store, must-revalidate\r\n"+
"Transfer-Encoding: chunked\r\n"+
"\r\n"...)
conn := ctx.Conn()
_, _ = conn.Write(buf.B) // 写 http 头
//
for i := 0; i < 9; i++ {
_, _ = conn.Write([]byte(fmt.Sprintf("%x\r\n%d \r\n", 1, i)))
}
//
_, _ = conn.Write([]byte(fmt.Sprintf("%x\r\n", fileSize, i)))
n, err := sendfile.SendFile(ctx.Conn(), int(fileToSend.Fd()), 0, fileSize) // 使用系统调用
if err != nil {
syslog.Fatalln(err)
}
_, _ = conn.Write([]byte("\r\n"))
syslog.Println("send count:", n)
// 写入结束信息
_, _ = conn.Write([]byte("0\r\n\r\n")
} func main() {
fileToSend, _ = os.Open("xxxx.file")
fileSize = 1024*2
//
syslog.SetFlags(syslog.Lshortfile | syslog.LstdFlags)
server := &fasthttp.Server{
Handler: FasthttpHandler,
}
syslog.Fatalln(server.ListenAndServe(":8089"))
}

相比直接从内存中 send 数据,实际测试中并未发现明显的性能提升,也可能是我只使用了 2kb 的数据,差异不明显。

希望对大家有用, have fun

fasthttp 中如何使用 linux 系统调用 `sendfile`的更多相关文章

  1. linux内核系统调用--sendfile函数

    在apache,nginx,lighttpd等webserver其中,都有一项sendfile相关的配置,在一些网上的资料都有谈到sendfile会提升文件传输性能,那sendfile究竟是什么呢?它 ...

  2. 如何在Linux中添加新的系统调用

    系统调用是应用程序和操作系统内核之间的功能接口.其主要目的是使得用户 可以使用操作系统提供的有关设备管理.输入/输入系统.文件系统和进程控制. 通信以及存储管理等方面的功能,而不必了解系统程序的内部结 ...

  3. [Linux]Linux系统调用列表

    本文列出了大部分常见的Linux系统调用,并附有简要中文说明. 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的 ...

  4. 常用的Linux系统调用命令

    常用的Linux系统调用命令   下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别.   一.进程控制 ...

  5. Linux系统调用(转载)

    目录: 1. Linux系统调用原理 2. 系统调用的实现 3. Linux系统调用分类及列表 4.系统调用.用户编程接口(API).系统命令和内核函数的关系 5. Linux系统调用实例 6. Li ...

  6. Linux系统调用列表

    转自Linux系统调用列表 一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtabl ...

  7. UNIX环境高级编程——Linux系统调用列表

    以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完 ...

  8. Linux系统调用列表(转)

    以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完 ...

  9. linux内核剖析(六)Linux系统调用详解(实现机制分析)

    本文介绍了系统调用的一些实现细节.首先分析了系统调用的意义,它们与库函数和应用程序接口(API)有怎样的关系.然后,我们考察了Linux内核如何实现系统调用,以及执行系统调用的连锁反应:陷入内核,传递 ...

  10. 网络常用的linux系统调用

    网络之常用的Linux系统调用 下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别. 一.进程控制 fo ...

随机推荐

  1. 智定义、易调整,火山引擎DataLeap助力企业轻松实现全流程值班管理

     更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   近日,火山引擎大数据研发治理套件DataLeap全新上线值班管理模块,企业可通过该模块体系化智能化创建值班计 ...

  2. 高性能 Jsonpath 框架,Snack3 3.2.57 发布

    Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表示,ONode也 ...

  3. 开放 LLM 排行榜: 深入研究 DROP

    最近,开放 LLM 排行榜 迎来了 3 个新成员: Winogrande.GSM8k 以及 DROP,它们都使用了 EleutherAI Harness 的原始实现.一眼望去,我们就会发现 DROP ...

  4. 压测工具 Locust

    一.认识Locust 定义 Locust是一款易于使用的分布式负载测试工具,完全基于事件,即一个locust节点也可以在一个进程中支持数千并发用户,不使用回调,通过gevent使用轻量级过程(即在自己 ...

  5. ChatExcel?

    大家好,我是章北海mlpy 最近在浅学LangChain,在大模型时代,感觉这玩意很有前途. LangChain是一个开源的应用开发框架,目前支持Python和TypeScript两种编程语言. 它赋 ...

  6. Navigation的用法

    一.Navigation的诞生 单个Activity嵌套多个Fragment的UI架构模式,已经被大多数的Android工程师所接受和采用.但是,对Fragment的管理一直是一件比较麻烦的事情.我们 ...

  7. Delete `␍`eslint(prettier/prettier)错误

    最佳实践: 现在VScode,Notepad++编辑器都能够自动识别文件的换行符是LF还是CRLF. 如果你用的是windows,文件编码是UTF-8且包含中文,最好全局将autocrlf设置为fal ...

  8. 一文看完String的前世今生,内容有点多,请耐心看完!

    写在开头 String字符串作为一种引用类型,在Java中的地位举足轻重,也是代码中出现频率最高的一种数据结构,因此,我们需要像分析Object一样,将String作为一个topic,单独拿出来总结, ...

  9. Synchronized的使用及原理总结

    本文为博主原创,未经允许不得转载 Synchronized的使用总结:   1.作用 原理 synchronized 的锁膨胀升级过程 对象的内存布局 锁的消除及逃逸分析 synchronized的方 ...

  10. python json.loads()、json.dumps()和json.dump()、json.load()区别

    json.loads().json.dumps()和json.dump().json.load()分别是两组不同用法 带s的用于数据类型的转换,不带s的用于操作文件. json.loads().jso ...