第八期 Scala Meetup 于上周六顺利结束,三位 Scala 资深使用者与 2000+ 在线用户分享了三大话题:
- Tubi 的 gRPC 演进之路
- Scala 与函数式编程
- 交互式笔记本中的 Scala
同时,应粉丝提问,大家也对“ Scala 入门和进阶路径、Akka 在分布式场景中的应用”等备受关注的问题进行了讨论。这里可下载演讲文稿。
欢迎关注比图科技公众号,了解 Scala 最新资讯及活动。也欢迎你在后台留言,申请加入 Scala 开发交流群!
Tubi 的 gRPC 演进之路
Tubi Scala Team & gRPC
来自 Tubi 的后端工程师张正来,首先介绍了 gRPC 诞生的背景和其主要相关特性。
gRPC 常应用于构建跨语言、跨平台的高性能微服务,其接口优先、传输高效以及兼容性良好等优秀特性令其成为云原生时代服务通信的事实标准,并且拥有谷歌背书,是 CNCF 的核心项目之一。
gRPC 主要有四种通信模式,可以根据业务的实际场景来灵活选择,分别是:
· 单向 RPC (unary/simple RPC)
· 服务端流式 RPC (server-side streaming RPC)
· 客户端流式 RPC (client-side streaming RPC)
· 双向流式 RPC (bidirectional streaming RPC)
正来还实机演示了一个简易的 gRPC HelloWorld 应用,并且对比了 gRPC 和其他通信框架的异同,列举了不同框架的 Pros & Cons,让我们对 gRPC 相比于其他框架比如 REST 和同为 RPC 框架的 Thrift 的特点有了很好的理解。
随后,正来给出了 Tubi 使用 gRPC 的理由,也相当于是 gRPC 优秀设计点的总结:
· 面向服务定义而非资源定义,适合各种业务需求(更便于领域建模)
· 强类型约束,降低开发和维护成本,提高工程师生产力(符合 Type Safe 的设计要求)
· 多语言支持,不同团队可以根据业务需要选择更合适的编程语言(可以使用更多的工具)
· 不同团队可以通过集中的 ProtoBuf 代码库轻松的共享服务定义(便于团队对服务进行维护和统一建模)
· ProtoBuf 高效的序列化性能和较小的序列化体积(在 Akka 中,集群间也是使用 Protobuf 序列化 Whisper 信息)
· 原生支持 stream 操作,大数据量传输更加高效(流式处理在业务场景下真的很重要)
· 性能好,可支持高吞吐低延迟服务
· 社区活跃、生态快速成熟
· Kubernetes 紧密集成,可以使用 HealthCheck,服务发现等功能
Tubi Akka-gRPC 迁移
Tubi 内部使用 Scala 构建的服务是重度依赖 Akka 框架的,在 Akka-gRPC 成熟后,由于其出色的性能和实用的特性,Tubi 团队开始把其 gRPC 服务由 gRPC runtime 迁移到 Akka-gRPC。
正来也给出了相应的 Performance Benchmark,迁移 Akka-gRPC 能让系统在高负载时具有更好的性能和稳定性,当前阶段的主要收益是可维护性的提升。
关于 Akka 更换 LICENSE 的影响,正来表示 Tubi 会和 Lightbend 继续合作并使用 Akka 的相关服务。
—— 以上分享来自 Ken
通过正来的分享,我了解到了 Tubi 具体的 Scala 应用是怎么样的,是比较实际的一场分享,感觉比自己光看理论要好很多。
—— 以上分享来自 Alpha
Scala 与函数式编程
@袁洋
先是介绍了由北京智源人工智能研究院孵化的同象项目—— AI + 中医的辅助诊断系统,为医生提供临床辅助诊断的帮助,优化效率和诊断正确率。在我看来,这是一个很有趣的应用点,而且是由 Scala 和 Typescript 开发的(看起来袁老师很注重 Type Safety)。
印象最深的是讲解项目整体架构时,给的标题是“范畴论理论支撑”,不知道是不是这里挖了一个小坑,引出后续演讲中,关于范畴论相关概念的分享。
随后袁老师讲解了函数式编程的相关概念,让我们理解了为什么要管理副作用,怎样是函数式编程的最佳实践。
函数式编程是严谨的,它更像是一个处理问题的框架,来帮助我们更科学、有效地构建业务和应用。我们需要先明确数据和它们的格式;再定义不同数据之间的转换逻辑,也就是实现转换操作的函数;最后根据业务的逻辑,把这些函数串起来。
根据我个人的经验,在实现转换操作函数这一环节,可以先根据业务逻辑的大框架把主要的函数先定义出来,再逐层解耦,最后会发现核心函数可以由若干个小函数组成。
这样做的好处是能够使写出的组件拥有更好的组合性和逻辑的可复用性;对于副作用,我们需要把它们尽量推到逻辑的外层,先要最大化核心的逻辑层,最后再集中处理副作用。
试想一下,如果我们的一段核心代码中有 70% 以上的内容是关于拥有副作用的函数的处理逻辑,在对代码逻辑进行理解时,这将产生极坏的阅读体验,并且会显得很啰嗦,因为我们看到的几乎都不是我们想要的。可以有的做法是先把核心逻辑打通,最后再集中管理副作用。
袁老师提到这样的开发范式和 AI 自动编程会有很好的相关性,其实不难发现,通过函数式编程的方法向 AI 描述他所需要解决的问题是清晰的,这样或许在未来能够看到更多的 AI 应用帮助开发者提升效率( CodePilot 和 chatGPT 就是很好的例子,非常强大!);程序员在能实现更多的价值的同时,也能让自己的工作变得更有意义,而不是机械地进行重复劳动。
接下来袁老师通过一个“盒子模型”,讲解了 Monad 以及 IO Monad 的概念。
袁老师的解释都很通俗易懂,最有趣的一个例子就是把 Monad 比作具体做某件事的事先计划,它也是一个盒子,里面装着要做的某件事和它的结果;但是计划的执行是充满变数的(拥有副作用,在不同的时间或者地点执行会有不同的结果);计划中的每个步骤都会产生一个新的盒子,但不会马上打开它,这个盒子里可能有副作用,但是我们同样知道里面可能有我们想要的东西,这使得我们可以以一种“假设”的状态完成我们的设计和实现,而最后去处理副作用。
计划的产生是纯函数,但计划的执行不是,我们通过 Monad,使得在设计时可以以纯函数的方式去实现,而同时保留对副作用的管理和控制能力。
最后,袁老师快速地过了一下 Cats Library 中的 Type Classes,并且介绍了智源团队开源的 Flag Boot 微服务开发库和对比 Spring Boot 框架的 Benchmark,期待 Flag Boot 能够越来越棒!
—— 以上分享来自 Ken
袁洋老师的分享对我很有启发,用了一个新的比喻来讲解 Monad,感觉很形象,更理解了 Monad。
——以上分享来自 Alpha
交互笔记本中的 Scala
李枫老师的分享,让我知道了原来 Scala 可以被应用于这么多领域,了解了很多有趣且实用的 Scala 库,之前在工作中没用到过。老师对编程的热情和对专业的执着也很感染我!
——以上分享来自 Z
李枫老师的分享内容比较多,感觉研究得也比较深入,对我来说,因为之前没接触过,理解起来有挑战,但很好的是,李枫老师也分享了自己这么多年积累下来的文档,后面可以慢慢理解。
关于如何学习 Scala,李枫老师的分享给我的印象非常深刻。尤其是需求产生了学习的动力这一点,这个需求可以是业务、工作发展需求,也可以是个人兴趣想要拓宽边界。
—— 以上分享来自隔壁正在施工
Scala 在 Tubi 的应用案例
使用 Scala 和 Akka-Stream 打造一个完全响应式广告服务系统
使用 Scala 和 akka-stream 处理广告竞价
Scala Meetup 往期推荐
【活动回顾】2022年6月
【活动回顾】2021年1月
【活动回顾】2020年9月
【活动回顾】2020年4月