2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

与 Henrik Feldt 谈论 Suave 1.0

  • 2016-01-29
  • 本文字数:3471 字

    阅读完需:约 11 分钟

在经过几年时间的开发之后, Suave 1.0 终于于近期正式发布了。InfoQ 与 Suave 的维护者,同时也是 qvitoo 的 CEO Henrik Feldt 进行了一次访谈,以深入地了解这个框架的功能以及它的开发历史。

InfoQ:Suave 的开发是怎样启动的?

HF:Suave 的第一次代码提交是大约 6 年前由 Ademar Gonzales 开始的。我大约在 2 年前加入了这一项目,当时我正在寻找一个合适的 web 服务器,它应当符合我的用例的需求,能够在 Windows 及 Linux 上通过 puppet 部署由 F#编写的微服务。当时,Suave 的开发已经停滞了几年的时间,但我喜欢它的代码库,因为它非常容易理解。

当时的 Suave 有一些稳定性方面的问题,但 Ademar 给予了我非常积极的响应,每次我编写了一个单元测试或是 repository 的时候,他都能快速地修复其中的问题,而且经常是连夜回复。

因此,我们之间的合作具有很高的生产力。从我的角度来看,初次的互动是非常积极的。大约两个月之后,在经过了大量的测试之后,我们将其发布到生产环境中。随后我们克服了一些小小的障碍,在一周之后部署了修正代码。Suave 的表现正如它的名字一样:非常平滑(smooth)

InfoQ:如何创建一个能够处理几百个路由(route)的大规模 Suave 应用,同时又能够保持它的可维护性呢?

HF:我常用的做法是让每个路由的前缀对应着一个不同的 F#模块,记录在 Filters.pathStars 中。如此一来,在开发过程中,我就能够轻易地对 App.fs 文件进行扫描,以找到我想要改动的前缀。App.api 是一个庞大的“选择”列表,任何互不相关的关注点,例如登录功能都可以通过“context”功能以加入这个路由列表中。

对于每个模块,例如帐号(Accounts)模块来说,会通过 Accounts.api 列出所有谓词 + 路径的组织(以及其他过滤器)。在这个“选择”列表中的每一行将负责为调用者生成一个响应,哪怕发生了校验失败的情况(通过“bindReq”实现)。

在 App.api 中的前缀 / 位置列表中的最下方部分是文件模块的使用,因此如果某个 API 的路由找不到匹配,至少该请求可能会对应一个静态文件。对于 qvitoo 来说,如果该文件也找不到,那么请求也将始终能够匹配并返回 index.html。因为我们使用了 React.JS 以及 react-router,因此 react-router 需要负责应用的深度链接与导航,并找到正确的页面。

这种结构能够让我们以一种非常灵活的方式添加更多的路由。在 Suave 中不需要担心可维护性的问题,因为这个库不会干扰你的行为,让你能够自由地加以选择。

另外一种方式是通过类似于 generator://github.com/rayokota/generator-angular-suave 这样的工具自动生成路由。此外,我认为将来在这方面可能会用到一些元编程技术(例如 camlp4)。

InfoQ:Suave 最适合于什么样的场景?

当然是构建 web 应用了!你可以构建各种应用,包括 API、微服务以及一个大型的 web 网站。你也可以把它当作一个服务端类型的 F#或 C#的 CLR 应用,作为访问你的 CLR 客户端的入口。你也可以在 TopShelf Windows 服务中通过它暴露 /health 功能,并结合使用 Logary,它能够让运维工作显得更简单。

InfoQ:为了运行 Suave 应用,在服务器上要进行什么配置?

HF:你需要安装 Mono 或者.NET,然后运行 fsx 文件或是 exe 文件,仅此而已!

主要的麻烦在于,如何在没有登录的情况下,保证你的服务器始终在运行这个可执行文件。

如果你的服务器是 Windows 环境,那么可以选择 TopShelf(我们在 GitHub 上的库中有一个示例),或者运行 winsw 并直接指向你的控制台应用。Suave 本身是非常稳定的,因此你可以在很长的时间内运行这些微服务,并且无需任何人工的介入。

在 qvitoo 中,我们的开发工作都在 OS X 上完成,并且在 CentOS、Ubuntu 以及 CoreOS 的某些扩展等操作系统中进行预发布和实际部署。当我们运行 Linux 系统时,所要做的就是在你所选择的进程管理器中保持一个入口。我们所选择的是 systemd,因此对于 qvitoo.com,我们编写了一个 qvitoo.service 文件,如下所示:

复制代码
[Unit]
Description=Logibit Qvitoo
Wants=bus-org.freedesktop.NetworkManager.target
After=bus-org.freedesktop.NetworkManager.target
[Service]
EnvironmentFile=/etc/sysconfig/qvitoo
User=qvitoo
ExecStart=/opt/qvitoo/start
Restart=always
RestartSec=5

在我看来,Suave 如今所受到的关注是因为 Suave 非常容易上手。

当然,你也可以部署至 Heroku 中,这是一种十分简便的方法,因此你完全无需管理服务器的问题。如果乐意的话,你也可以选择使用 Azure。

InfoQ:在这次主要的发布之前,在过去几年中还有哪些亮点吗?

这个项目有以下几个里程碑:

  • 将首个版本 0.0.2 发布为 NuGet 包。
  • 设计了产品的文档以及 suave.io 网站,这起到了非常大的作用,人们开始对这一项目感兴趣。
  • 对于公共 API 实现了完全的文档化,各种 HTTP 的组合完全按照 HTTP RFC 实现了文档化。
  • 通过 Ademar 设计的 monadic socket builder,让产品的稳定性得到了很大的改进。
  • 0.10 版本开始支持服务端事件发送(Server Sent Events)。
  • 大约在 0.16 版本开始,人们对此项目的兴趣逐渐上升,人们开始在推文中提到 Suave。
  • 从 0.19 版本开始支持加密的强会话状态,并支持在 cookie 中保存状态。
  • 0.20 版本对 API 进行了大量的重新组织,让这些 API 更受欢迎,并且易于理解。
  • 0.21 修复了在过载的情况下出现末端缓冲区溢出的状况。
  • 从 0.25 版本开始,这一项目得到了 Don Syme 的关注,他为我们免费提供了一次 API 的审查,并且通过一个内容丰富的 pull request 改进了许多小地方。
  • 0.26 版本开始支持 Razor。
  • 0.27 版本开始支持 WebSocket!
  • 0.32 版本开始支持 OWIN,从此能够支持来自于社区的大量用例。
  • 0.33 版本创建了 LibUV 这个 tcp factory。
  • 1.0 版本使 API 稳定了下来,并且通过托管代码实现了 TLS(来自于框架)。

InfoQ:对于 Suave 的性能,你是否能够提供一些数据?

HF:qvitoo 采取了事件溯源的领域驱动设计(DDD)及命令查询职责分离(CQRS)系统,运行在先进的硬件上,写操作的延迟通常在毫秒级以下,而读操作也差不多同样快,性能上的延迟主要取决于对于其他子系统的 IO 操作。

我们还没有对 Suave 进行过基准测试,在第 1 个版本发布之前,我们的主要目标是发布一个优秀的功能性 API,它需要做到易用与易于上手。我们希望 Suave 能够在高吞吐量的网站与服务中得到更广泛的应用,我们将看到更多对于性能方面的贡献。

我在运行 OS X 的笔记本上进行过一些测试,它每秒种能够运行 5600 次 Hello
World。按照我们的假设,如果我们能够转换到其他异步框架,例如 Hopac 上,那么将能够获得指数级的吞吐量性能提升,因为它的内存分配比起 F#中的 async 实现要少。而如果在对关键路径中进行的对象分配能够做得更好,那么还有可能获得指数级的提高。

如果某位读者觉得这是一个有趣的挑战,那不妨来尝试一下贡献代码。我们会频繁并快速的合并各种 pull
request,并对合并的要求提供大量的反馈,这会使得贡献代码的过程更有趣,而且新人也能够很容易上手。

InfoQ:你对于今后的发展是否有一个路线图呢?

HF:我们准备支持 HTTP2。另外,我们也在讨论如何通过更少的内存分配实现 1 至 2 个数量级的性能提高。我们或许会转为使用 Hopac,它在异步性能上的表现比起 F#中内置的异步功能更出色。

F#团队提供了一个支持 CoreCLR 的 pull request,等到 CoreCLR for F#方面的工具比较稳定之后,我们就打算合并这个 pull request。

另外,如果所有的 F# HTTP 客户端都能够使用相同的 SocketOp 编程模型,也将有一定的实用性,它非常适合于对由 Suave 开发的网站与 API 进行单元测试与集成测试时。

作为一门编程语言,F#正在逐渐成熟的过程中。如果 Suave 能够通过 F#进行编译,那么或许由 Suave 开发的网站或许能够在编译后运行在 Mirage 这种 exo kernel(也叫做云操作系统)中?甚至也许能够将 Suave 网站编译为原生代码,在不依赖于类库的情况下运行。

我们乐意为在 Alpine Linux 上通过 Mono 或 CoreCLR 进行部署提供一个良好的用例。经过几个月之前开始的工作,Mono 已经开始了测试 repo。一个 Suave 服务的部署包大约有 5MiB(约等于 5MB)用于操作系统,30MiB 用于 CoreCLR,还有 5MiB 用于服务本身。

InfoQ:你还有什么要补充的吗?

HF:如果你是一位熟练的开发者,并且有兴趣在工作中使用一些令人振奋的技术,例如 F#、Suave、AI 以及 web,那么你或许很适合在 qvitoo 工作。请发送邮件至 hi@qvitoo.com。

如果你想要更多地了解如何编写 Suave 代码,以及通用的 F#代码,你可以订阅 F# TV ,这也是对 Suave 的开发与维护的一种帮助。

查看英文原文: Interview with Henrik Feldt on Suave 1.0

2016-01-29 18:001707
用户头像

发布了 428 篇内容, 共 199.1 次阅读, 收获喜欢 39 次。

关注

评论

发布
暂无评论
发现更多内容

没有Linux服务器,该如何学习Linux呢?

Simon郎

大数据 Linux java;

【优化技术专题】「线程间的高性能消息框架」深入浅出Disruptor的使用和原理

码界西柚

Disruptor LinkedBlockingQueue ArrayBlockingQueue 9月日更

简单五步:给你的 Golang 应用加一个 GUI ( Electron 驱动)

baiyutang

UI 跨平台 Go 语言 GUI 9月日更

Vue进阶(幺零七):arr.forEach() 跳出循环

No Silver Bullet

Vue 9月日更

什么是事务数据库?,Java程序员面试题集大全

Java 程序员 后端

三大「价值流」搞定技术型管理

蔡建斌

管理 技术管理 精益 引航计划 内容合集

用IoT放羊养牛,不出门也能知道它们的动向

华为云开发者联盟

物联网 华为云 iotda 畜牧业 华为云物联网平台

三面美团、四面阿里成功斩下offer,下血本买的

Java 程序员 后端

使用Git分布式控制系统,怒斩腾讯和阿里的Offer

Java 程序员 后端

架构训练营 模块7 - 王者荣耀商城异地多活架构设计

sophiahuxh

快速上手Apache POI

卢卡多多

POI Apache POI 9月日更

如何PWA构建现代离线应用程序

devpoint

Service Worker 9月日更

三面蚂蚁惨败,面试官要求手写算法,从外包公司到今日头条offer

Java 后端

编程基础:CPU资源监控

正向成长

CPU调度

性能测试中标记请求参数实践

FunTester

性能测试 接口测试 压力测试 FunTester 标记参数

设计模式类型

一个大红包

9月日更

MySQL + Keepalived 双主热备搭建

Se7en

一文说清BIO、NIO、AIO不同IO模型演进之路

慕枫技术笔记

后端 引航计划

三面滴滴Java岗,Java程序员校招蚂蚁金服

Java 程序员 后端

手撸二叉树之二叉搜索树的最小绝对差

HelloWorld杰少

数据结构与算法 9月日更

全球国家简码信息表

入门小站

工具

循环神经网络LSTM RNN回归:sin曲线预测

华为云开发者联盟

RNN 循环神经网络 LSTM LSTM RNN回归

如何选择收银机主板?

双赞工控

安卓主板

带你读AI论文丨用于细粒度分类的Transformer结构—TransFG

华为云开发者联盟

细粒度 映射 Transformer TransFG 差异性图片

如何从零搭建起一支技术团队

石云升

团队管理 管理 引航计划 内容合集 9月日更

测试模型中理解压力测试和负载测试

FunTester

性能测试 接口测试 压力测试 FunTester 负载测试

KVM虚拟机常用管理命令

玏佾

kvm 虚拟主机

计算机工业的生态链(三)

姬翔

9月日更

世界的尽头是铁岭,互联网的尽头是它

艾小仙

什么是Spring-Cloud、需要掌握哪些知识点,Java面试常问的算法题

Java 程序员 后端

网络攻防学习笔记 Day132

穿过生命散发芬芳

网络模型 9月日更

与Henrik Feldt谈论Suave 1.0_.NET_Pierre-Luc Maheu_InfoQ精选文章