服务器架构网络服务需要面对两个挑战

发布时间:2021年11月13日 阅读:513 次

服务器架构网络服务需要面对两个挑战

服务器架构网络服务需要面对两个挑战

第一个问题是核心挑战,要编写出能够正确处理请求并构造合适响应的代码。

第二个挑战是如何将网络代码部署到随系统自动启动的Windows服务或者是Unix守护进程中,将活动日志持久化存储。并且在无法连接到数据库或者后端存储区时发出警告,为其提供完整的保护,以防止所有可能的失败情形,或是确保其在失败时快速重启。

这篇文章直重点说第一个问题。然后会介绍服务器部署,然后把重点放在如何构建网络服务器软件上。

首先,我们可以很自然的把网络服务器分为三大类。

第一类就是简单的单线程服务器(比如UDP服务器和TCP服务器),在这里会详细说明这类服务器的局限性,即同一时刻只能为一个客户端服务,此时其他客户端只能等待。即使为一个客户服务,这时候CPU也可能处于近乎空闲的状态。

第二类就是解决局限性的一个方案,使用多个线程或者进程,每个线程或者进程内都运行一个单线程服务器。

第三类就是与第二类刚好相对的另一种解决方案,在自己的代码中使用异步网络操作来支持多路复用,而不直接使用操作系统提供的多路复用。

然后我们说一下服务器部署,我们可能会把网络服务部署到单台机器上,也可能部署到多台机器上。要使用单台机器上的服务,客户端只要接到该机器的IP地址即可,而要使用运行在多台机器上的服务,就需要更加复杂的方法。

一种方法是将这个服务的某个实例的地址或者主机名返回给客户端(比如与客户端运行在同一机房中服务实例),但是这种方法没有提供冗余性,如果服务的这一个实例宕机了,那么通过主机名或者IP地址硬编码链接这个服务实例的客户端都无法继续链接。

另外一种更加健壮性的方法就是,当要访问某个服务时候,令DNS服务器返回运行这个服务的所有IP地址,如果客户端无法连接到第一个地址的话,可以连接到第二个地址,然后第三个。工业界一般会在服务前配置一个负载均衡器,客户端直接连接到负载均衡器,然后由负载均衡器将链接请求转发到实际的服务器。如果某台服务器宕机了,那么负载均衡器会将转发至该服务器的连接请求予以停止。直到这个服务器恢复服务为止。这样服务器的故障对于大量的用户来说是不可见的。

大型的互联网服务中结合了这两个方法:每个机房中都配置了一个负载均衡器与服务器群,而公共的DNS名会返回与用户距离最近的机房中的负载均衡器的IP地址。

无论服务器架构多么简单或者多么复杂,都需要使用某种方式在物理或者虚拟机器上运行我们的Python服务器代码,这一个过程叫做部署。

对于部署来说,比较旧式的技术观点就是,为每个服务器程序都编写服务所提供的所有功能:通过两次fork()创建一个Unix守护进程(或者是将自己注册为一个Windows服务),安排进行系统级的日志操作,支持配置文件以及提供启动、关闭和重启的相关机制。可以使用已经解决了相关问题的第三方库来完成服务器程序的编写,也可以在自己的代码中重新实现这些功能。

另外一种方法就是。提倡只是先服务器程序必备功能的最小集合。它将每个服务实现为普通的前台程序,而不是将其实现为守护进程。这样的程序从环境变量(Python中的sys.environ字典)而不是系统级的配置文件中获取所需要的配置选项。他通过环境变量中指定的选项链接到任意的后端服务,并且直接将日志信息输出到屏幕,甚至直接使用Python自己提供的print()函数。另外,这个方法通过打开并且监听环境配置指定的任意端口来接受网络请求。

服务器架构网络服务需要面对两个挑战

现在有一些大型的平台服务提供商提供了托管这种程序的功能。他们将应用程序的几十个甚至几百个副本配置在一个公共域名和TCP负载均衡器下,然后将所有输出的日志聚集起来进行分析。这些提供商允许我们直接提交代码。但是更多的提供商,更希望我们提供代码、Python解释器以及所需要的依赖打包入一个容器内。(说到这里,可能你会想起Docker)。我们可以在自己的笔记本电脑上对这个容器进行测试,然后将其部署到生产环境中,从而能够确认,生产环境中运行的Python代码与测试环境中运行的代码使用的是完全相同的镜像。无论是用哪种方法,都无需在单个服务中提供多个功能,服务中所有的冗余和重复都可以让平台来处理。


Tag:服务器 架构 网络 服务 需要 面对 挑战
相关文章

发表评论: