写点什么

与 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:001394
用户头像

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

关注

评论

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

工赋开发者社区 | 定了!就在7月30日!

工赋开发者社区

技术分享 工业 峰会

浅谈云原生边缘计算框架演进

谐云

7月月更

Spark统一内存划分

矛始

spark 统一内存

MySQL精品学习资源合集 | 含学习教程笔记、运维技巧、图书推荐

墨天轮

MySQL 数据库 学习笔记 运维技术

模块八作业 - 消息数据 MySQL 表设计

Elvis FAN

如何组装一个注册中心

捉虫大师

注册中心 7月月更 后端启示录

洋葱集团携手OceanBase实现分布式升级,全球数据首次实现跨云融合

OceanBase 数据库

Spark数据格式UnsafeRow

矛始

spark 内存 UnsafeRow

[ Kitex 源码解读 ] 服务发现

baiyutang

Go 微服务架构 kitex CloudWeGo

2022 云原生编程挑战赛火热报名中!看导师如何拆解 Serverless 赛题?

阿里巴巴云原生

阿里云 Serverless 云原生编程挑战赛

极大似然估计

矛始

概率 极大似然估计

图的遍历的定义以及深度优先搜索和广度优先搜索(一)

乔乔

7月月更

机器视觉在服务机器人中的应用

优必选科技

机器人

基础到高级涵盖11个技术,Alibaba最新出品711页Java面试神册真香

程序员小毕

Java 面试 程序人生 JVM 中间件

基础+框架+数据库+系统设计+算法,2022阿里最新Java面试突击手册我粉了

Java永远的神

Java 数据库 spring 面试 JVM

B站713事故后的多活容灾建设|TakinTalks大咖分享

TakinTalks稳定性社区

故障 稳定性保障

kudu设计-tablet

矛始

kudu tablet

有一说一,阿里P7的薪资待遇是真的香

程序员小毕

Java 程序员 程序人生 后端 架构师

RocketMQ—(总结)一篇就搞懂RocketMQ

IT巅峰技术

3分钟创建Serverless Job 定时获取新闻热搜

云端explorer

Serverless Job 新闻热搜 场景搭建

菜鸟 CPaaS 平台微服务治理实践

阿里巴巴云原生

阿里云 微服务 云原生 CPaaS 菜鸟

深圳云管平台厂商哪家好?有哪些功能?咨询电话多少?

行云管家

云计算 云管平台

就这一次!详细聊聊分布式系统的那些技术方案

Java全栈架构师

程序员 面试 分布式 系统设计 架构师

如何通过学会提问,成为更加优秀的数据科学家

Baihai IDP

AI 数据科学 职业发展

融云直播 SDK 玩法翻新,入围信通院「实时互动创新应用优秀案例」

融云 RongCloud

直播 sdk

6种方法帮你搞定SimpleDateFormat类不是线程安全的问题

华为云开发者联盟

高并发 开发

兆骑科创海外高层次人才引进平台,创业赛事活动路演

兆骑科创凤阁

高层次人才引进平台

2022最新最全Java面试八股文(整整1685页,14个技术栈,20余万字)

Java全栈架构师

Java spring 面试 JVM 消息中间件

一文讲清楚SpringBoot六种读取配置方式

王小凡

Java 程序员 Sprint Boot

面试OPPO,16道题甩过来,我人傻了

Java永远的神

Java 程序员 面试 分布式 项目

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