所有源码分析基于haproxy version 1.6.14
首先分析核心代码haproxy.c
/* Runs the polling loop */
void run_poll_loop()
{
int next;
tv_update_date(0,1);
while (1) {
/* Process a few tasks */
process_runnable_tasks();
/* check if we caught some signals and process them */
signal_process_queue();
/* Check if we can expire some tasks */
next = wake_expired_tasks();
/* stop when there's nothing left to do */
if (jobs == 0)
break;
/* expire immediately if events are pending */
if (fd_cache_num || tasks_run_queue || signal_queue_len || applets_active_queue)
next = now_ms;
/* The poller will ensure it returns around <next> */
cur_poller.poll(&cur_poller, next);
fd_process_cached_events();
applet_run_active();
}
}
简要说明
- process_runnable_tasks 处理可运行的任务
- signal_process_queue 处理信号队列,如果捕获了信号则需要处理
- wake_expired_tasks 处理超时任务
- cur_poller.poll 更新fd事件到缓存
- fd_process_cached_events 处理fd事件
函数分析
整体描述下函数的作用
process_runnable_tasks
取出队列中的任务,调用process_stream
函数处理,返回之后重新将task放入等待队列
主要任务
- 根据预设的规则设置一个backend
process_switching_rules
->stream_set_backend
- 根据相应的调度算法,选择后端服务器,并添加到队列中
sess_prepare_conn_req
->srv_redispatch_connect
->assign_server_and_queue
->assign_server
->chash_get_next_server
- 后端服务器请求已满,添加到proxy队列
pendconn_add
signal_process_queue
自身实现的信号处理机制,接收到信号之后输出到队列,然后在处理信号队列,保证所有请求处理完之后再关闭
wake_expired_tasks
唤醒超时任务,队列分为run queue/wait queue,该函数就是检查wait queue任务,并将其输出到run queue中,以便后续处理。
cur_poller.poll
获取所有活动的fd,并将其更新到cache中
主要函数
- _do_poll
- epoll_wait
- fd_may_recv
- fd_may_send
- fd_update_cache
fd_process_cached_events
处理fd事件,建立连接、数据收发等
主要函数
- conn_fd_handler
- si_conn_recv_cb
- raw_sock_to_pipe/ssl_sock_to_buf
- raw_sock_to_buf
- si_conn_send_cb
- si_conn_recv_cb