原文
原始链接: https://news.ycombinator.com/item?id=41150095
BEAM(Beyond Compile and Execute Machine)是用于运行 Elixir、Erlang 和 Gleam 等编程语言的虚拟机。 它起源于电信行业,用于处理长途电话等任务。 BEAM 允许高水平的并发性,与操作系统进程相比,进程的重量更轻。 这些进程通过消息传递进行通信,不需要异步/等待语法或多线程。 由于其分布式设计,BEAM 还支持自我修复特性,从而提高了容错能力。 与 Kubernetes 等平台相比,BEAM 集成了应用程序和编排逻辑,无需外部配置文件并降低了复杂性。 这使得开发和部署变得更加容易,尤其是在使用多种编程语言时。 此外,BEam 还提供内置工具来管理和监控应用程序,促进更好的组织和简化的工作流程。 总体而言,使用 BEAM 通过提供能够满足基础设施层和应用程序开发需求的单一平台来简化开发生命周期。
The BEAM is a virtual machine, I guess kinda like the JVM. So just like you can write Java or Kotlin or Clojure or a million other JVM languages, so too can you write Erlang or Elixir or Gleam (I like the look of Gleam)... And expect similar interoperability.
The BEAM has its roots in the telecom world. So while Sun Microsystems was doing the Java thing to make webservers or applets or whatever for the JVM, Ericcson was doing Erlang things to make things like long distance phone calls happen on the BEAM.
(I'm not a fan of Java, I just think it's a decent thing to compare with in this case)
The BEAM folks take a different approach to concurrency than is common elsewhere. BEAM processes are much more lightweight than OS processes, so while it might be insane to run a separate copy of your server for each user, it's less insane to run a separate BEAM process for each user.
BEAM processes interact through message passing. Of course most other processes do to, but only because the developer built it that way. With the BEAM it's built in, each process periodically checks its mailbox for a message which matches its criteria, and if there's no message, it sleeps until it is revisited by the scheduler. There's no async/await business. They're all single threaded and sequential. Instead, you achieve coordination by having many of them, some of which are in charge of starting/stopping/organizing others. (I guess they build structures out of these things called "supervision trees" but I don't precisely know what that is).
This has all grown up in a world where nodes are expected to be physically separate (like either end of a phone call) so you end up with a bit more fault tolerance than if each process is expected to be on the same machine.
In Kubernetes you've got this mountain of yaml which you craft to tell the container orchestrator how to treat your app. And then you've got your app itself which is probably not written in yaml. So I find it very jarring to switch between my dev hat and my ops hat.
And Kubernetes... That's Google's baby, right, so it makes sense that it doesn't feel the same as the underlying app. As a cloud provider, they need a rather high wall between the app and the infra. But I think it causes all kinds of problems. At least in my world, the apps are either in Python or Go, so when there's a problem someone will come along and solve it with yaml-glue to add an additional container which may or may not resemble the app which has the problem.
My brain struggles to hop from Python to Yaml to Go (and there's usually some bash in there too).
The BEAM, by contrast, expects processes to start and stop other processes. So your orchestration logic and your application logic are in the same language. You don't have to express your wishes in yaml and then navigate all of these superfluous layers (e.g. the container entrypoint script, port forwarding, in-cluster DNS, etc) to have your wish granted. That kind of communication is handled by the BEAM's inbuilt message passing system.
If I got to rebuild our stack from scratch I'd use Kubernetes as a cloud-provider-agnostic interface to get access to compute, but instead of expressing anything about the app in YAML, I'd handle all of that extra stuff (e.g. log scraping, metric aggregation, whatever hacky fix is needed today...), I'd handle it in the BEAM, right alongside my app.
People like to say "build security into the app" or "build observability into the app", but standard practice is to bolt on solutions that don't resemble the app at all. My (probably flawed) perspective is that if you scratch those itches within the BEAM, then you're going to end up with fewer superfluous layers of abstraction. Also fewer distinct niches that you now must find a specialist to fill when the old one quits. Also, you end up more in control of your app because since you more or less wrote the orchestrator, you're relying less on the cloud provider to be a reliable puppet master.
---
It's slow going, one class per semester, but I've been taking biology classes on the side. I sometimes think about making a break for it and trying to build something like farmbot but for driving a microscope, or a pipette, or maintaining the temperature/pH/etc in a bioreactor.
These are, for now, just dreams.
Sorry for the diatribe, but you did ask me to elaborate :)