Linux IPC之Socket网络编程服务器的负载均衡

导言:在设计高性能并发型服务器时,传统的为每一个客户端创建一个新的子进程(或线程)所带来的开销对服务器来说是个沉重的负担,因此本文考虑几种可选方案。

在服务器上预先创建进程或线程(进程池或线程池)

  • 服务器在启动阶段(即,在任何客户端请求到来之前)就立刻预先创建好一定数量的子进程(或线程),而不是针对每个客户端来创建一个新的子进程(或线程)。这些子进程构成了一种服务池(server pool),即,进程池或线程池。

  • 服务池中的每个子进程一次只处理一个客户端。在处理完客户端请求后,子进程并不会终止,而是获取下一个待处理的客户端继续处理。

  • 服务池的方式,需要服务器父进程必须对未占用的子进程加以监视,并且在服务器处于负载高峰期时,增加服务池的大小,而在负载低时,降低服务池的大小(因为过多的空余进程会降低系统的整体性能)。

  • 服务池中的子进程必须遵循某些协议,使得它们能以独占的方式选择一个客户端连接。(例如,在大多数UNIX实现中,让服务池中的每个子进程在监听描述符的accept()调用上阻塞就足够了。即,服务器父进程在创建任何子进程之前先创建监听套接字,然后每个子进程fork()调用中继承该套接字的文件描述符,当一个新的客户端连接到来时,只有其中一个子进程能完成accept()调用。但是,由于accpet()在一些老式的实现中并不是一个原子化的系统调用,因此可能需要通过一些互斥技术,例如,文件锁来支持,以确保每次只有一个子进程可以执行accpet()调用。)

在单个进程中处理多个客户端(I/O多路复用)

为了达到单个服务器进程来处理多个客户端,必须采用一种能允许单个进程同时监视多个文件描述符上I/O事件的I/O模型。例如,使用Linux的epoll。

在设计单进程服务器时,服务器进程必须做一些通常由内核来处理的调度任务,我们可以依靠内核来确保每个服务器进程能公平地访问到服务器主机的资源,但当我们用单个服务器进程来处理多个客户端时,服务器进程必须自行确保一个或多个客户端不会独占服务器,从而使其他的客户端处于饥饿状态。

服务器集群

使用多个服务器系统(即,服务器集群,server farm)来支持客户端的并发高负载。

  • DNS

构建服务器集群最简单的一种方式是使用DNS,将同一个域名映射到多个服务器的IP,然后DNS服务器对域名解析请求以轮询的方式返回不同的服务器IP地址。

问题:DNS的方式(循环轮询)优势是成本低且易实施,但是也存在一些问题。一个是DNS缓存的问题,导致切换可能不能立即生效。另外一个是,循环轮询不能达到很好的负载均衡,因为后端的服务器配置可能不同,资源利用率可能无法达到最大化。

  • 亲和性

在多台服务器的设计中,另一个需要考虑的因素是,服务器亲和性(server affinity),即,确保来自同一个客户端的请求序列能够全部定向到同一台服务器上,这样由服务器维护的任何有关客户端状态的信息都能够保持准确。

  • 服务器负载均衡(server load balancing)

由一台负载均衡服务器(主备容灾),将客户端请求路由到服务器集群中的其中一个成员上。此方式的优点是:

  1. 消除了由DNS缓存所引起的问题,因为服务器集群只对外提供了一个单独的IP地址,即,负载均衡服务器的IP地址。
  2. 负载均衡服务器结合一些算法来衡量或计算服务器负载,可能根据服务器集群的成员所提供的量值,并智能地将负载分发到集群中的各个成员之上。
  3. 负载均衡服务器也会自动检测集群中的失效成员,或者新增加的服务器成员。
  4. 负载均衡服务器可能还会提供对服务器亲和力的支持。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值