Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1510656
  • 博文数量: 228
  • 博客积分: 1698
  • 博客等级: 上尉
  • 技术积分: 3241
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-24 21:49
个人简介

Linux

文章分类

全部博文(228)

文章存档

2017年(1)

2016年(43)

2015年(102)

2014年(44)

2013年(5)

2012年(30)

2011年(3)

分类: LINUX

2015-05-14 12:21:56

原文地址:haproxy主要代码 作者:深蓝苹果



  1. 主要代码:
  2. =======================================================================================
  3. haproxy.c
  4. 主要配置都由全局变量global保存(global的定义在include/types/global.h中,其中还声明了很多全局变量)
  5. * 捕获多个信号,包括
  6. SIGQUIT
  7. SIGUSR1
  8. SIGHUP
  9. SIGPIPE
  10. * 调整资源上线,包括
  11. rlim_max
  12. rlim_cur
  13. rlimit_memmax
  14. void run_poll_loop()
  15. 程序进入工作状态后的主循环,其内容
  16. int next;
  17. while (1) {
  18. /* 检查是否捕获了新signals,并处理它们 */
  19. signal_process_queue();
  20. /* 检查是否需要处理一些超时tasks */
  21. wake_expired_tasks(&next);
  22. /* 执行tasks */
  23. process_runnable_tasks(&next);
  24. /* 维护所有proxies.
  25. * 当proxies增多时,消耗增大,计划后续作为一个来task处理
  26. */
  27. maintain_proxies(&next);
  28. /* 不再接收新请求 & 已无当前监听 */
  29. if (!actconn && listeners == 0)
  30. break;
  31. /* The poller will ensure it returns around ?? */
  32. cur_poller.poll(&cur_poller, next);
  33. }
  34. memory.c
  35. 一开始会分配的内存,以list方式管理
  36. 内存不够时,可追加分配
  37. 但内存释放不是真正的释放,只是放入空闲list中,因此haproxy使用的内存量不会随着负载降低而减少
  38. proto_http.c
  39. HTTP协议解析
  40. task.c
  41. task管理
  42. 这里面的实现
  43. struct task *__task_wakeup(struct task *t)
  44. 根据t->nice,将task 移到执行队列中
  45. 这个任务不能之前已经在执行队列中,如果不确定,使用更安全的函数task_wakeup()
  46. void __task_queue(struct task *task)
  47. 不应由外面直接调用,应由task_queue()调用,因为调用前它会做几个小test
  48. void wake_expired_tasks(int *next)
  49. void process_runnable_tasks(int *next)
  50. int init_task()
  51. 初始化任务池
  52. session.c
  53. struct task *process_session(struct task *t)
  54. 回调的处理(类),会话处理的主要部分,输入单位是task(参考task.c)
  55. 这里面用了goto...
  56. resync_stream_interface: /* Check for connection closure */
  57. resync_request: /* Analyse request */
  58. resync_response: /* Analyse response */
  59. void session_free(struct session *s)
  60. 释放session及上下文,必须先删除该session再调用本函数
  61. void sess_set_term_flags(struct session *s)
  62. 根据session状态设置本session标志位
  63. void sess_change_server(struct session *sess, struct server *newsrv)
  64. 将一个已有的session转移到另一个server去提供服务
  65. int process_store_rules(struct session *s, struct buffer *rep, int an_bit)
  66. int sess_update_st_con_tcp(struct session *s, struct stream_interface *si)
  67. void sess_establish(struct session *s, struct stream_interface *si)
  68. 仅在SI_ST_CON向SI_ST_EST转移时可以调用
  69. int sess_update_st_cer(struct session *s, struct stream_interface *si)
  70. 当si->state == SI_ST_CER时调用,可能因为之前的connection已经释放
  71. 返回:
  72. SI_ST_CLO 重试已耗尽
  73. SI_ST_TAR 当重新连接之前,delay一阵
  74. SI_ST_ASS 建议连接同一server
  75. SI_ST_REQ 进行重新分配(到不同server)
  76. proxy.c
  77. 全局参数
  78. struct proxy *proxy = NULL; 当前所有的proxy链表
  79. (层次:proxy链表-->proxy-->server)
  80. int get_backend_server(const char *bk_name, const char *sv_name,
  81. struct proxy **bk, struct server **sv)
  82. 获取指定名称的backend和server并返回
  83. void listen_proxies(void)
  84. 重新激活监听
  85. --试图激活所有为PR_STPAUSED状态的监听
  86. --若监听失败,将停用该proxy
  87. --若监听数超过配置的最大连接数,将超出部分状态置为PR_STIDLE
  88. --若成功,状态置为PR_STRUN
  89. int session_set_backend(struct session *s, struct proxy *be)
  90. 将s的backend设置为be
  91. --如果s已经有backend(即s->flags & SN_BE_ASSIGNED),则什么都不做
  92. signal.c
  93. void __signal_process_queue()
  94. 调用所有pending signals的handler,且将计数器和队列长度清0
  95. -----------
  96. sigprocmask(SIG_SETMASK, &blocked_sig, &old_sig);
  97. //mask期间,任何SIGQUIT信号都会被阻塞,如果在mask期间收到任何键盘的quit信号,则此时会把这些信息存在内核的队列中,等待mask结束后,可能要处理此信号
  98. sigprocmask(SIG_SETMASK, &old_sig, NULL);
  99. -----------
  100. backend.c
  101. void recount_servers(struct proxy *px)
  102. 更新px的active 和 backup servers
  103. struct server *get_server_sh(struct proxy *px, const char *addr, int len)
  104. 为px找一个运行中的server(会在active和backup的server中查找)
  105. --若找到,返回该server
  106. --若未找到,返回null
  107. --仅使用最基本的hash方式
  108. --若px仅剩一个server,不用hash,直接用该server
  109. struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
  110. 为px找一个运行中的server(会在active和backup的server中查找)
  111. --与get_server_sh的区别是,使用对URI的hash
  112. -- In order to optimize cache hits, the hash computation ends at the question mark ??
  113. struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
  114. 为px找一个运行中的server(会在active和backup的server中查找)
  115. --根据url中的参数进行hash
  116. struct server *get_server_ph_post(struct session *s)
  117. 和get_server_ph类似,但根据body contents来hash
  118. struct server *get_server_hh(struct session *s)
  119. 和get_server_ph_post类似,但根据head来hash
  120. proto_http.c
  121. http协议处理
  122. int http_process_request(struct session *s, struct buffer *req, int an_bit)
  123. 处理当前请求
  124. --返回0 成功;返回1 数据不够/失败/抛弃该request(支持连接拒绝)
  125. --依赖buffers flags, 并会更新 s->req->analysers.
  126. lb_xxx的文件都是load balance的各种实现
  127. lb_chash.c 为一致性hash的实现
  128. lb_fwlc.c 为最少连接者先处理(Fast Weighted Least Connection)的实现
  129. lb_fwrr.c 为简单的轮询(Fast Weighted Round Robin)的实现
  130. lb_map.c 为基于映射的hash(Map-based load-balancing : RR and HASH)的实现
阅读(1779) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~