应用层主要处理网站应用的业务逻辑,因此有时也称作业务逻辑层,应用的一个显著特点是应用的无状态性。
所谓无状态的应用是指应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务实例(服务器)之间完全对等,请求提交到任意服务器,处理结果都是完全一样的。
不保存状态的应用给高可用的架构设计带来了巨大便利,既然服务器不保存请求的状态,那么所有的服务器完全对等,当任意一台或多台服务器宕机,请求提交给集群中其他任意一台可用机器处理,这样对终端用户而言,请求总是能够成功的,整个系统依然可用。
当 Web 服务器集群中的服务器都可用时,负载均衡服务器会把用户发送的访问请求分发到任意一台服务器上进行处理,而当某台服务器宕机时,负载均衡服务器通过心跳检测机制发现该服务器失去响应,就会把它从服务器列表中删除,而将请求发送到其他服务器上,这些服务器是完全一样的,请求在任何一台服务器中处理都不会影响最终的结果。
由于负载均衡在应用层实际上起到了系统高可用的作用,因此即使某个应用访问量非常少,只用一台服务器提供服务就绰绰有余,但如果需要保证该服务高可用,也必须至少部署两台服务器,使用负载均衡技术构建一个小型的集群。
集群环境下,Session 管理主要有以下几种手段:
Session 复制 应用服务器开启 Web 容器的 Session 复制功能,在集群中的几台服务器之间同步 Session 对象,使得每台服务器上都保存所有用户的 Session 信息,这样任何一台机器宕机都不会导致 Session 数据的丢失,而服务器使用 Session 时,也只需要在本机获取即可。
Session 绑定 Session 绑定可以利用负载均衡的源地址 Hash 算法(Nginx 中的 )实现,负载均衡服务器总是将来源于同一 IP 的请求分发到同一台服务器上(也可以根据 Cookie 信息将同一个用户的请求总是分发到同一台服务器上。这样在整个会话期间,用户所有的请求都在同一台服务器上处理,即 Session 绑定在某台特定服务器上,保证 Session 总能在这台服务器上获取。这种方法又被称作会话黏滞。
利用 Cookie 记录 Session 该方案会将 Session 信息全部放到 Cookie 中,而不是只放一个 session_id 作为 session 的键! 因此,利用 Cookie 记录 Session 存在一些缺点,比如:
受 Cookie 大小限制,能记录的信息有限;
每次请求都需要传输 Cookie,影响性能;
如果用户关闭 Cookie,访问就会不正常。
但是由于 Cookie 的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分应用需要记录的 Session 信息又比较小。因此事实上,许多网站都或多或少地使用 Cookie 记录 Session(存放 session 的键)。
Session 共享 利用独立部署的 Session 服务器(集群)统一管理 Session,应用服务器每次读写 Session 时,都访问 Session 服务器。 这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的 Session 服务器,然后针对这两种服务器的不同特性分别设计其架构。 对于有状态的 Session 服务器,一种比较简单的方法是利用分布式缓存、数据库等,在这些产品的基础上进行包装,使其符合 Session 的存储和访问要求。如果业务场景对 Session 管理有比较高的要求,比如利用 Session 服务集成单点登录(SSO)、用户服务等功能,则需要开发专门的 Session 服务管理平台。