• 状态
  • 有状态
  • 无状态
  • 池化

https://blog.csdn.net/qq_30154571/article/details/89017817 - 有状态|无状态服务

无状态架构

  • 大多数现代软件都是以无状态的方式进行架构的-扩展是大型服务一个必不可少的因素

  • 无状态的可扩展性更强,当你有更多的流量时,很容易通过扩展通过增加 更多的服务器来服务更多用户。

  • 开发者犯的错误更少,不用考虑内存泄漏(由于每次请求都会创建和销毁all)的问题。

  • 创建无状态应用更简单,开发人员不必过多考虑如何管理应用层的状态

  • 无状态设计是可扩展的。所有的状态都保存在外部存储中

  • 数据库和缓存是有状态的,并附加了持久化的存储

  • 应该根据应用需求选择单体或者微服务。

  • 有些状态可以在应用内部存储和重用;其他一些状态可以作为外部状态。

  • 无状态响应如 HTTP响应总是可以被大多数缓存服务器如 Varnish或 Nginx 和 CDN缓存

    1
    2
    3
    4
    可以将系统的工作负载分派给负载均衡器,然后将工作负载平均分配给多个相同的无状态服务器以扩大或缩小系统的规模。 
    对于这种类型的系统,可以使用多种负载平衡算法。
    如果服务器大小不同,则采用加权轮询; 如果每个服务器的性能都不相同并且请求的资源消耗没有太大变化,可以选择连接最少。
    根据系统的要求,也可以使用其他的负载均衡算法。

    问题

  • 有些状态不能在不同请求之间共享。这些可共享状态的构建可能非常昂贵,比如从数据库中获取变量或者从远程服务器中获取变量。在无状态设计中,这些变量在每个请求中都要反复创建和销毁。

  • 外部存储可能无法随着进程数量的增加而扩展。建立过多的数据库连接可能会明显降低性能。我们可能需要一个中间层代理来限制与数据库的最大连接数,但这也会降低整体性能,因为有一个中间层成本。

summary

  • 扩展性
  • 在外部保存状态而导致性能下降
    1
    2
    3
    4
    通过对系统的一个组件进行不同的域划分,有状态组件也可以被看作是无状态组件。
    如果组件保持状态仅是高速缓存数据,则可以将一个有状态系统视为无状态组件。 正确而明智地管理状态是将系统性能提高10倍至100倍的关键。
    这种做法适用于许多现代软件架构,例如微服务。
    在这种情况下,每个组件都独立执行特定的功能,它们之间通过网络通信(如HTTP、gRPC等)进行数据交换。每个组件都可以独立扩展和部署,系统的整体负载由这些分散的组件共同承担,从而提高了系统的可伸缩性、可维护性和可用性。
    1
    2
    在分布式系统中,如果组件仅使用高速缓存暂时存储数据,并且在组件之间没有严格的数据共享需求,可以将其视为近似无状态组件。缓存的作用是提高性能,而不是永久存储状态。
    如果组件依赖高速缓存来存储重要状态信息,那么它实际上仍然是有状态组件。该组件需要缓存中的数据来恢复状态,以便在应用程序中正确执行操作。
    1
    2
    3
    4
    5
    6
    7
    将有状态组件拆分为无状态组件可以带来许多优点,但在实际操作时需要注意以下事项:

    这种做法可能增加了组件之间的通信开销。
    需要对每个组件进行独立的管理和维护。
    部署和配置可能较为复杂。
    组件之间的依赖关系可能导致系统脆弱性。
    系统的整体复杂性可能会提高。

无状态模型

无状态模型的一个问题是它浪费了资源来重建上下文来服务每个请求。这可能包括建立新的连接到远程服务和从数据库中获取数据。这些过程可能有多轮。
在无状态模型中,有很多资源被浪费在建立执行上下文和建立依赖数据来处理实际的请求逻辑

  • 问题:
  1. 我们不重用可重用的变量,是否在浪费资源?
  2. 我们每次请求都会从数据库中请求相同的没有变化的数据吗?
  3. 我们是否在请求当前请求没有使用的数据?
  4. 我们是否可以将远程数据缓存到本地?
  5. 我们是否可以使用异步 I/O 而不是阻塞 I/O 来节省进程数量?
  6. 我们是否可以将重任务推迟,将它们送入队列,另外执行

性能问题

性能问题也是我们互联网项目中最难解决的问题。第一步总是要找出整个系 统的瓶颈,避免局部优化
。通过对状态复用的优化,我们可以看到 性能上的重大提升。性能问题与如何管理本地或远程的状态以及访问状态的 成本有关。