我担任后端工程师已超过 8 年,我见证了技术的来来去去,但有一点始终不变;就是该技术建立的第一个原则。我指的并不是工具、框架甚至语言。这些不断发展和变化,但构建这些工具的基础设施很少发生变化。
例如,知道如何设置 Apache 或 IIS 是一回事,了解这两个 Web 服务器之间的共性和差异是另一回事。
在这篇文章中,我探讨了后端工程的一些基础知识,它们是我们使用的一切的基础。您可以选择对所有这些基础知识有基本的了解并成为一名万事通的后端工程师,或者选择更深入的垂直领域并成为该领域的专家。没有对错之分,全看是什么打动了你。
成为更好的后端工程师的方法从来都不是一帆风顺的。事实上,它很混乱,充满了只有你必须经历的反复试验和试验。没有一本书、没有课程、没有 YouTube 视频或媒体文章可以教你关于后端工程的一切。你必须自己去体验。
如果您是一名对后端工程感兴趣的应届毕业生,您可能会发现这些基础知识中的一个或多个很有趣,并决定继续学习。
最好的方法是弄脏你的手。让我们开始吧。
通信协议
通信协议将前端连接接到后端。了解协议的工作原理对于工程师来说是一项很好的技能,尤其是当他们想要构建一个有弹性的后端应用程序时。
我们在后端使用和喜爱的几乎所有协议都构建在 TCP 或 UDP 之上。这就是为什么了解这两者之间的差异有助于工程师做出正确选择的原因。例如,TCP 是一种基于流的面向连接的协议,而 UDP 是一种基于消息的无连接协议。TCP 以连接建立和重新传输为代价提供可靠的传送。虽然 UDP 启动速度更快但不能保证交付。在这两个协议之上构建的任何东西都必须遵守它们的基本属性。TCP并不比UDP好,UDP也不比TCP好。这完全取决于您要构建的内容。
往上看,HTTP 协议最初是建立在 TCP 之上的,因为我们想要可靠地发送请求和响应。随着网络的发展和资源的丰富,一个连接不足以同时发送多个请求。因此浏览器开始建立越来越多的连接,每个请求的连接设置成本变得如此之高。
HTTP/2 引入了应用程序级流,因此可以在同一链接上发送多个请求。后来 HTTP/2 发展起来,不得不用 HTTP/3 在 UDP 之上重写,以解决 TCP 线头问题。一切都是有原因的,TCP 的基本特性是这一举动的罪魁祸首。这并不意味着 TCP 不好,网络已经以 TCP 的方式不再适用发展。如果我们不知道 TCP 是如何工作的,我们就不会改进 HTTP 协议。
同样重要的是要知道使用任何协议都会带来成本,尤其是在构建 API 时。了解该成本将帮助您做出更明智的决策。例如,使用 HTTP/2 可能会给您带来更多的 HTTP 请求吞吐量,但应用程序组装流所需的工作会对 CPU 造成负担,这是 Lucidchart 在艰难的过程中学到的东西。
有时后端架构需要实时双向通信协议来构建聊天、游戏应用程序或仅在两个服务之间进行通信。可以使用 WebSockets、GRPC 或原始 TCP/UDP 等协议。如果您知道协议的工作原理以及优点和缺点,您就会知道何时使用它。
最终,学习通信协议对于后端工程师来说很重要,并且可以根据需要深入了解任何协议。也许有一天你会写一个 RFC 来提议一个新的协议。
网络服务器
Web 服务器变得越来越重要,因为后端基础设施依赖于 HTTP Web 通信。Web 服务器提供基于 HTTP 协议的静态或动态内容。如果您构建 Web API,您可以使用您选择的语言启动您自己的 Web 服务器,或者使用 Gin、Express 或 Django 等 Web 框架。
现代 Web 服务器同时支持 HTTP/1.1 和 HTTP/2。HTTP/3 作为其较新的协议正在慢慢获得支持。使用适当的协议配置 Web 服务器对于后端应用程序的性能和弹性至关重要;而这一切都取决于环境。例如,您是否期望来自同一个客户端的多个并发请求?还是您希望请求较少但来自许多客户?基于此,您可以选择多路复用 HTTP/2 或普通简单的 HTTP/1.1。
Web 服务器的内部架构也可能不同。Web 服务器可以是单线程或多线程的。它们可以有一个线程或多个侦听器线程。可以通过多种方式在线程之间接收和分配客户端连接。如果您选择现成的 Web 服务器,您将受困于它的架构。如果您从头开始构建自己的架构,则可以选择适合您的架构。
此外,Web 服务器可以设置堆栈中的任何位置。例如,CDN 是一个 Web 服务器,它充当缓存并与原始后端 Web 服务器通信以获取内容。API 网关是一种 Web 服务器,用于对用户进行身份验证并提供来自后端 Web 服务器的 API 响应。
现成的 Web 服务器的示例有 Apache Tomcat、Apache httpd 和 Nginx。后者既可以充当 Web 服务器,也可以充当代理。您可以通过侦听 TCP 端口并了解如何使用 HTTP 协议,以任何语言构建您自己的 Web 服务器,您当然可以使用为您完成大部分工作的 HTTP 库。
数据库工程
数据库工程是一个广阔的研究领域。数据库的核心思想很简单;允许多个用户以持久的方式一致地存储和检索数据。这就是为什么理解 ACID 的四个属性:原子性、一致性、隔离性和持久性是数据库工程的基础。
人们必须明白,没有什么是一成不变的,遵循这些属性并不是必须的。例如,关系数据库是完全 ACID 并且需要模式,而 MongoDB 是作为基于文档的数据库构建的,具有基本的原子性(文档级别)并且没有模式。Redis 通过默认牺牲持久性来构建一个静态的高性能缓存。
没有索引的数据库系统是不完整的,其核心 B+树是首选的数据结构。数据在表格、文档或图表中的组织方式最终都会成为文件系统页面。了解如何获得大部分磁盘 I/O 读取是数据库工程的核心。
如果你对数据库工程感兴趣,那么你可以专攻的领域很多。你可以选择一个数据库,然后对它了如指掌。您可以构建更好的索引技术(LSM 是一个很好的例子)。您可以构建专门用于特定工作负载的新数据库系统。
代理
代理在工程界越来越受欢迎,尤其是随着微服务的引入。代理的主要目的是它接收来自客户端的请求并将请求转发到后端服务器。代理向目标服务器隐藏原始客户端的网络层身份。
有两个级别的代理:第 4 层和第 7 层代理。第 4 层代理工作在传输层,而第 7 层代理工作在应用层。每一层都提供不同的功能,可以用于不同的目的。第 7 层代理要求代理了解应用程序协议,而第 4 层代理可与任何应用程序协议一起工作,因为它工作在传输层(TCP 或 UDP)。
您可能听说过可互换使用的正向代理和反向代理。正向代理和反向代理都接收来自客户端的请求并将请求转发到后端。在正向代理中,客户端明确请求特定的后端服务器,代理完成此请求。转发代理必须在客户端网络代理部分配置才能工作。在反向代理中客户端并不知道最终的后端服务器,对于客户端来说最终的目的地就是反向代理。客户端不知道后端有更多的服务器。
代理的常见用例是缓存、API 网关、身份验证、负载平衡等等。例如,内容分发网络 (CDN) 是一个向源后端发送请求的反向代理。Fiddler 或 MITM 是在客户端配置的代理,所有请求首先发送给它们。服务网格本质上是代理和反向代理。
我说的是所有请求,但实际上只是代理配置为支持的请求。这里我们主要指的是 HTTP 代理,因此所有 HTTP 请求都会被转发。
代理的例子有 Nginx、HAProxy 和 Envoy。代理是后端工程中最有趣的主题之一,可以专门学习和改进它们。由于 Nginx 的某些限制, Cloudflare 最近放弃了他们的主要反向代理 Nginx,并构建了自己的代理。
消息系统
随着我们转向互联系统和服务,消息系统变得越来越重要。随着服务开始相互通信,耦合和依赖性增加,这增加了构建可伸缩后端应用程序的复杂性。消息系统旨在消除这种耦合
消息系统的核心支持一种称为发布-订阅的功能,其中客户端可以发布消息,其他客户端可以订阅以使用此内容。构建发布和消费方式的选择取决于消息传递系统。比如 Kafka 采用long-polling模型,RabbitMQ 采用push模型,两者各有利弊。
消费消息还会带来一个有趣且难以解决的问题。您如何确保消费者只阅读一次消息?这些保证使消息传递系统设计复杂化。
消息系统是一项真正有趣的技术,它是后端工程的基础。您可能会对这个领域感兴趣。
消息格式
消息格式与通信协议密切相关;它们描述了正在发送的消息的线内格式。它们通常分为人类可读和非人类可读两种类型。例如 XML、JSON 和协议缓冲区。
当客户端向后端发送消息时,它需要将消息从语言数据结构序列化为在线消息格式。当后端收到消息时,它需要将消息从这种格式反序列化为语言数据结构。
这就是为什么让 Javascript 客户端使用 JSON 作为消息格式与 C# 后端通信绝对没问题。javascript 的本机 JSON 对象将在线路中转换为 JSON 字节字符串,然后 C# 后端将字节字符串反序列化为表示字典的 C# 结构。了解与序列化和反序列化消息格式相关的成本很重要。
XML 是最初设计为人类可读的消息格式之一。然而,计算机难以处理 XML,因此创建了协议缓冲区格式以使消息格式更小且更友好。协议缓冲区变得非常流行,旨在解决高带宽消息的问题。协议缓冲区最小化有效负载,因此可以发送更少的字节。它还加快了序列化和反序列化过程。
专注于消息格式也是一种选择。您可以发明下一个消息格式,它可能成为未来 50 年为我们服务的标准。
安全
安全性是软件工程领域的一个重要课题。安全有许多不同的方面。您可以使用加密或 TLS 保护通信。您可以使用防火墙规则和适当的网络配置来防止网络入侵。您可以研究常见的软件漏洞并防止拒绝服务攻击。作为一名软件工程师,熟悉不同类型的安全风险以及如何减轻它们非常重要。
一种类型的安全风险是中间人攻击。这是攻击者拦截两方之间的通信并试图窃听或修改正在交换的数据的地方。为防止此类攻击,使用传输层安全性 (TLS) 对通信方进行加密和身份验证非常重要。
另一种安全风险是拒绝服务攻击。这是攻击者试图阻止合法用户访问服务的地方,方法是通过向服务发送大量请求或通过发送特殊有效负载来寻找使后端崩溃的方法。为防止此类攻击,重要的是要有防火墙或第 7 层 DDOS 保护层来阻止非法请求。Cloudflare 有很好的服务来检测 DDOS 流量。这当然可以通过第 7 层检查来实现。
当然,很难总结所有可能的安全攻击。有客户端安全攻击,如 XSS(跨端脚本),有服务器端安全攻击,如 SQL 注入。
安全性是软件工程领域的一个重要课题。安全有很多方面。作为一名软件工程师,熟悉不同类型的安全风险以及如何减轻它们非常重要。
结论
总之,作为后端工程师,探索不同的技术,找到自己感兴趣的地方,自己的优势在哪里,很重要。不要害怕尝试和构建一些很酷的东西,即使它使用的是一种可能被认为非常规的语言。
我们在本文中讨论的是我认为将始终保留在这里的一些基础知识,了解它们可以使您成为更好的工程师。
随着您获得更多的经验和专业知识,请专注于加深您在特定领域的知识,以便以您在该领域的技能而闻名。最后,跟随您的兴趣在快速发展的软件工程世界中取得成功非常重要。
永远记住,没有什么是一成不变的,你可以改变任何事情。设计或构建应用程序的方法没有对错之分,这完全取决于您要做什么。您可能会遇到我们今天拥有的技术为您所用的情况。但你也可能会走到死胡同,可能需要发明一些以前从未发明过的东西。
刚刚阅读了 Homa 论文,该协议试图完全取代基本协议 TCP,因为数据中心工作负载完全不适合 TCP。
附注
ACID 学习推荐 http://gk.link/a/11Rwm 或 http://gk.link/a/11RvS
Nginx 学习推荐 http://gk.link/a/11Rw0
Kafka 学习推荐 http://gk.link/a/11Rw2
欢迎点赞,关注,转发,祝你在职业生涯中一切顺利。