面试题答案
一键面试1. 负载均衡算法
- 轮询算法(Round - Robin):维护一个子进程索引,每次有新请求到来,按顺序依次将请求分配给子进程。例如,假设有三个子进程
child1
、child2
、child3
,第一个请求分配给child1
,第二个请求分配给child2
,第三个请求分配给child3
,第四个请求又分配给child1
,以此类推。 - 加权轮询算法(Weighted Round - Robin):为每个子进程分配一个权重值,权重反映了该子进程处理能力的相对大小。比如,处理能力强的子进程权重设为 3,处理能力较弱的子进程权重设为 1。在分配请求时,按权重比例分配。例如,一轮中处理能力强的子进程会被分配 3 次请求,处理能力弱的子进程会被分配 1 次请求。
- 最少连接数算法(Least Connections):记录每个子进程当前处理的连接数,每次将新请求分配给连接数最少的子进程。这样能动态地将负载分配到相对空闲的子进程上。
2. 实现思路
- 父进程职责:
- 初始化子进程:在 prefork 模型初始化阶段,父进程创建多个子进程。例如,使用
fork()
系统调用创建多个子进程,并通过管道或共享内存等 IPC 机制建立与子进程的通信通道。 - 负载均衡器:
- 对于轮询算法,父进程可以维护一个全局变量记录当前应分配请求的子进程索引,每次请求到来,更新该索引指向下一个子进程。
- 加权轮询算法实现时,父进程需要为每个子进程维护权重信息,在分配请求时按照权重比例进行分配。
- 最少连接数算法要求父进程维护每个子进程的连接数信息,可通过共享内存或定期从子进程获取连接数来更新,每次新请求到来,选择连接数最少的子进程进行分配。
- 故障检测与转移:父进程定期检测子进程状态,例如使用
waitpid()
函数以非阻塞方式等待子进程退出。如果检测到某个子进程异常退出(如通过WIFEXITED()
等宏判断),父进程重新创建一个新的子进程。同时,父进程需要调整负载均衡算法的相关数据结构,如在轮询算法中,将新子进程纳入轮询序列;在最少连接数算法中,为新子进程初始化连接数为 0。
- 初始化子进程:在 prefork 模型初始化阶段,父进程创建多个子进程。例如,使用
- 子进程职责:
- 处理请求:子进程通过与父进程建立的通信通道接收请求,处理完请求后,将结果返回给父进程或者直接返回给客户端(根据具体的架构设计)。
- 状态汇报:子进程定期向父进程汇报自己的状态,如当前处理的连接数等信息,以便父进程进行负载均衡决策。例如,可以通过管道向父进程发送连接数信息。