2024年 RubyConf China day one
jane
01 Dec 2024
后篇:2024年 RubyConf China day two
目录
主题一、陈金洲 — Rails + Next.js:一种提升开发者和用户体验的开发架构范式
主题二、李亚飞 — 十倍性能提升,原生 Ruby 异步编程机制的思考与应用
主题三、杨淼 — SDB: a New Ruby Stack Profiling Tool
主题四、袁晓峰 — 下一个十年的 Modern Monolith
主题五、李枫 — Metasploit 与 Ruby
主题六、李振楠 — 构建基于LLM的语音机器人
主题七、丁盛豪 — A.I.-Generated Interactive Narrative Design in Ruby
主题一、陈金洲 — Rails + Next.js:一种提升开发者和用户体验的开发架构范式
背景
- 很多上市公司 (如 GitHub、Shopify 等) 已经在使用现代前端技术
- Writebook 开发遵循了 Rails 一贯美学:
- 极少的外部依赖使得代码和升级可控
- 大量使用 Concern,更易维护
- delegated_type 做多态关联,无需使用 STI
- 使用 active_record 回调记录编辑历史 -> 无需使用第三方库(paper_trail)
- 使用 Current 线程安全地访问当前用户 -> 最佳实践
- 手写注册登录逻辑
- Writebook 在用户体验和开发体验上存在不足
为什么需要 Next.js
- 提升开发体验:
- 组件化开发
- 完善的 IDE 支持
- 活跃的社区支持
- 提升用户体验。浏览器的能力越来越强,然后消费者的最终用户对于用户体验的要求越来越高
- 用户体验 = 设计 + 响应速度
- 速度: 预加载页面 + 数据
- 数据:首次加载 + 乐观更新
Rails + Next.js 架构导致前后端分离,要怎么整合
- 使用 Next.js 的 rewrites 功能转发请求到 Rails 后端
- 取消这类请求的 CSRF 校验(Next.js 本身没有 CSRF 功能,其实是将这个问题暴漏给前端)
- 认证授权的实现
- 数据获取:使用 React-Query 实现数据的获取和乐观更新
- 实时通讯:整合 ActionCable,将请求转到 /cable.json
- 文件上传的处理
部署方案
- 使用 Kamal 同时部署 Rails 和 Next.js
Next.js 是一个非常非常好的 UI 框架的一个选择。
主题二、李亚飞 — 十倍性能提升,原生 Ruby 异步编程机制的思考与应用
背景
- 大模型时代带来的挑战:
- 传统同步编程模式在处理大模型调用时性能瓶颈明显
- 传统方式 QPS 只有5左右,需要大量机器支撑
- 传统线程方式提升性能有限(最多2-3倍)
- 2020年 Ruby 社区推出 Fiber (纤程) 概念,使 Ruby 速度提高3倍
主流的异步编程实现方案
- Event Loop(事件循环) :
- 代表: Node.js
- 特点: 使用 Task 和 Promise 作为并发单元
- 通信方式: 共享内存
- Actor模型 :
- 特点: 强制消息传递,不允许共享内存
- 适合大规模并发场景
- 但编程模型较反直觉
- Fiber机制 :
- Ruby社区采用的方案
- 介于Event Loop和Actor之间
- 兼顾易用性和性能
性能提升效果
- Fiber方案: 可达20倍性能提升
- 特别适合 IO 密集型应用
Fiber的挑战
- 错误处理复杂、调试困难、并发支持有限、学习曲线陡峭
- 可使用封装工具:Async、Concurrency
实际应用场景
- 异步 HTTP 请求
- 并行文件存取
- LLM 调用
调试解决方案
- 使用日志追踪
- 异步处理封装 (try/catch)
- 后台任务监控
- 设置超时机制,避免资源耗尽
核心原则
在保证架构质量的前提下,尽可能简单、清晰地表达业务逻辑,同时平衡性能需求。
参考资料:
https://www.reddit.com/r/ruby/comments/1b4h3jo/when_would_you_use_a_ractor_vs_async_ruby_vs/
https://thoughtbot.com/blog/my-adventure-with-async-ruby
https://www.youtube.com/watch?v=0p31ofu9RGk( India 2023 async ruby )
https://brunosutic.com/blog/async-ruby(Mark24 Chinese version:https://ruby-china.org/topics/43394)
主题三、杨淼 — SDB: a New Ruby Stack Profiling Tool
传统栈分析器的工作原理和局限
- 扫描 -> label symbolizer -> 分析
- 扫描栈以获取每个方法大概延迟
- symbolizer: 把方法转化成方法名
- 劣势:
- 频繁 symbolization 会增加负载
- GVL 机制导致执行分析器程序时,阻塞了应用
新栈分析器(SDB)实现特点
- 使用不同的策略:放弃使用GVL,降低应用阻塞
- 增加 sampling rate 采样率(100/s 到 1000/s),获取较全数据
- SDB 会将数据放到log文件中,在本地进行 symbolization,避免占用线上CPU
SDB 优势
- 降低应用阻塞率
- 减少CPU使用率
SDB 劣势
- 有数据冲突问题,不过由于 SDB 的目的是查询运行缓慢的方法,短期数据冲突对结果影响不大,所以不打算解决这个问题
- 现还处于试验阶段,只支持 ruby 3.1.5
- 不太好用:第一是它要用 EPPF, 需要做一些基建;第二是它还不够友好,比如整个分析流程还没自动化,不像 Vernier 那样有比较友好的展示页面。
主题四、袁晓峰 — 下一个十年的 Modern Monolith
Rails 是一个单体架构(Monolith)
- 尽可能长时间地保持事情尽可能简单,而Majectic monolith正是做到了这点。
- Rails Monolith 主流/官方方案:Rails 7.0 引入 Hotwire 作为默认方案,并废弃了 Webpacker。
Hotwire 介绍
- 技术组合 :Hotwire 由 Turbo、Stimulus 和 Strada 组成。Turbo 本身也是由多个组件构成。
- 服务端渲染 :Hotwire 通过服务端渲染将 HTML 返回给客户端,而不是传统的 JSON 数据。
- 核心原则 :简洁、降低复杂度、快速构建
更多信息可参考 xfyuan 的博客。
Hotwire 的劣势
- 虽然 Rails 提供了前端功能,但在 MVC 的“V”层仍做得不够好。
- 由于代码紧密耦合,导致数据流不够清晰和可预测。
解决方案:学习前端的组件化
- 组件化 :通过组件化,可以实现隔离性、可测试、可重用和可扩展的特性。
- 使用 Hotwire + ViewComponent 架构 :
- ViewComponent :将视图组件作为 Ruby 对象进行封装,每个组件的 CSS 和 JS 文件都是作用域隔离的,避免了全局污染。
- 页面实时更新 :组件可以使页面在不刷新整个页面的情况下,实时更新数据。
- 单独测试组件 :每个组件可以单独进行单元测试。
- 预览功能 :可集成
ApplicationViewComponentPreview
类进行预览。
Rails Modern Monolith 方案
- 无论是官方方案(Hotwire)也好,还是增强性方案 (ViewComponent) 也好,都存在自己的适用范围。
- 当 Hotwire 无法满足需求时,可以结合使用 Rails + Inertia.js ,但这并不等同于前后端完全分离。
- Inertia.js :并不是一个独立框架,可以与任意熟悉的前端框架(如 Svelte、Vue等)结合使用。通过服务器首次返回整个 HTML 文件,之后仅返回 JSON 数据,使得页面无需刷新即可更新。
可结合使用工具
- CSS :使用 TailwindCSS,一种功能强大的实用工具类框架。
- 构建工具 :使用 Vite ,它对 CSS 和 JS 构建提供开箱即用的支持,适合构建复杂的前端页面。
- 部署 :Kamal 部署工具。
主题五、李枫 — Metasploit 与 Ruby
渗透测试概述
- 渗透测试 :渗透测试是通过模拟黑客攻击,自动发起攻击以检测系统的安全性。
一些关于黑客领域的电视剧:《MR.ROBOR》。
Metasploit 使用 Ruby 开发的原因
- Metasploit 的开发者是 Ruby 的爱好者,Ruby 语言的简洁和灵活性使其成为开发该框架的理想选择。
Metasploit 核心组件
- MSFconsole :Metasploit 的控制器,提供交互式命令行界面,允许用户管理各种攻击和漏洞利用。
- Meterpreter :一种后渗透工具,允许在渗透测试过程中通过网络动态扩展功能。它是一种动态可扩展的 Payload,可以在运行时进行功能扩展。
- Modules :各种攻击的软件模块,Metasploit 提供的攻击模块可以帮助测试人员模拟不同的攻击场景。
Metasploit 配置要求
- Metasploit 3 配置要求如下(这个版本已有半年没有维护):
- 4.5GB RAM
- 65GB 硬盘空间
未来发展:GraalVM 的潜力
- GraalVM 支持 :Metasploit 很有可能在未来与 GraalVM 实现更好的兼容性,提升其性能和可扩展性。
- 目前 GraalVM 的内存使用较高,但这预计会在未来得到优化。
主题六、李振楠 — 构建基于LLM的语音机器人
应用场景
- 语音机器人在电话中筛选候选人,帮助自动化招聘流程。
语音机器人的构建
- 核心模块 :
- ASR(语音识别技术) :将语音转化为文本。
- TTS(Text-to-Speech,文本转语音) :将文本转化为语音。
- 谈话礼仪 :确保机器人在与人对话时遵循适当的交互规则,如何时听、何时说,如何应对长时间的沉默,如何处理用户主动挂机等。
- 分而治之的设计 :
- 将整个对话流程分成多个模块,如:
- Start :启动对话。
- Wait :等待候选人说完或者机器发完语音。
- Listen :监听用户说话。
- Think and Speak :大模型处理信息并回应。
- Push :如果用户很长一段时间没有说话,推动对话向前发展。
- Hang Up :结束对话。
- 将整个对话流程分成多个模块,如:
处理时区问题
- 在处理时区信息时,LLM 目前存在一定的难度,特别是跨时区的会话需要额外注意。
错误修复与调优
- 错误观测与修复 :
- 重放现场 :记录和回放错误场景,以便分析和修复。
- 调整输入 :比如调整 system 参数。
- 建立测试集 :构建 Good Cases 和 Bad Cases 测试集,不断验证机器人。
- 100% 通过率是遥不可及的追求。
语音延迟问题
- 降低首字节延迟,只要LLM和音频的生成速度高于播放速度,并且网络通畅,用户就不会感知到延迟
未来展望
- 多模态语音机器人 :
- 结合 ASR 、TTS 和 LLM ,推动语音机器人向更加智能和人性化的方向发展。
- 超低延迟 :进一步优化响应时间,减少用户等待。
- 打断支持 :使机器人能够更自然地应对被打断的对话场景。
- 情感与态度响应 :机器人可以根据对方的情感和态度做出响应,提升交互的自然度和有效性。
Q & A 总结
- 大模型和业务场景的平衡与取舍 :随着新模型的快速发展,存在模型不断更新和优化的压力,尤其是在实时性和计算资源方面。尽管新模型带来新的解决方案,但不同层次的模型仍具有其独特价值,尤其在成本和实现的权衡中,某些方案可能能长期使用,甚至在未来成本降低后,仍具备实际应用价值。
- TTS 吞字问题 :引入延迟流式处理,以解决错字的情况。
- 私有化部署与数据安全问题 :客户对数据安全和隐私的担忧,尤其是在美国市场,涉及PII(个人身份信息)的保护。部分公司通过与大厂合作、签署合规协议,采用私有端点来确保数据的安全性和合规性。
主题七、丁盛豪 — A.I.-Generated Interactive Narrative Design in Ruby
叙事设计的挑战与问题
- 分支与随机化 :
- 在叙事设计中,分支和随机化是非常重要的元素,它们决定了故事的展开方式和玩家的选择影响。
- 经济模型 :
- 经济模型在叙事设计中通常用来平衡资源和奖励系统,确保玩家的决策有实际影响,并推动故事发展。
- 叙事失调 :
- 叙事失调是指故事内容的混乱,例如一开始讲述一个情节,接着突然切换到另一个不相关的故事线,再过一段时间又回到原来的情节。这种失调会导致故事的主线不清晰,影响用户体验。
软件工程解决叙事问题
- 软件工具与语言 :
- 例如 Ink 语言 ,作为一种叙事编程语言,帮助设计师更好地控制和组织故事,避免叙事失调。
- 例如 Ink 语言 ,作为一种叙事编程语言,帮助设计师更好地控制和组织故事,避免叙事失调。
叙事设计的关键要素
- Control(可控性) :
- 确保叙事中的每个选择都可以被有效地控制,以使故事有清晰的进展。
- Adaptive(适应性) :
- 故事设计需要根据玩家的行为进行适应和调整,保持互动的自然性和流畅性。
- Interlocked(连锁反应) :
- 故事元素之间需要相互连接,产生连锁反应,确保玩家的每个决策都影响后续发展。
- Responsiveness(智能响应能力) :
- 故事和游戏需要有智能的响应能力,根据玩家的选择做出合适的反应。
完成故事旅途的步骤
- Interface(用户交互) :
- Transactional Embedding(事务嵌入) :
- 使用 pgvector 技术判断话题之间的相似性,帮助提升叙事的连贯性。
- Model Distillation(模型提炼) :
- 通过对故事模型的提炼,提取核心情节和决策点,使叙事更加简洁高效。
- Transactional Embedding(事务嵌入) :
- Storylet( **一种原子性的叙事内容模块,用来组装成完整的叙 )** :
- 构建 DSL
- Storyflow( **用来验证最终叙事结构的可行性,确保故事流程顺畅且连贯 )** :
- 数据逻辑:哥德尔不完备定理 :
- 在叙事设计中,可以利用 哥德尔不完备定理 来验证数据逻辑的复杂性,确保系统的推理能力不受限制。
- 备选方案:Logica :
- 如果传统的逻辑推理方法太慢,可以使用 Logica 作为备选方案来提升系统的响应速度。
- 数据逻辑:哥德尔不完备定理 :
技术挑战与优化
- 测试的挑战 :
- 叙事设计中的测试非常困难,需要通过像 Glyph 这样的工具进行辅助,以帮助进行自动化测试和验证。
- 性能优化 :
- 在叙事设计系统中,升级到 Rails 8 ,并使用 Solid Cache 来优化缓存管理,减少配置难度,同时提高系统性能。
Tags
rubyconf
China