互联网架构基础知识
一、网站常见架构
-
负载层
-
页面缓存层
-
web层
-
数据层
二、运维法则
-
缓存为王
-
尽量在前端(缓存层)响应完成
-
应用和服务解耦
三、网站灰度发布的步骤
-
先下线需要下线的服务器(markdown)
-
停止服务(需要等待keepalive的时长后)
-
关闭监控(以免监控大量的报警)
-
替换程序(全量、增量)
- 一般情况下将多个版本软链至指定的目录,必要是可以回滚操作
-
启动服务
-
warmingup(预热)
- 对页面进行访问请求,进行缓存数据环节,以免大流量打跨服务器,冷数据的服务上线会导致雪崩(可能需要依赖一此程序进行访问预热)
-
测试
- 进行测试操作,以免有未发现的bug
-
加监控
-
上线
-
review
- 检查复审,查看日志
四、web常见术语
-
UV : User view
-
PV : Page view
衡量一个网站的稳定性和承载能力,一般比较好的网站每个UV平均15个PV
-
活动连接数
连接状态为Established,一般情况下,使用日PV/18(小时),可以计算一个粗略的活动连接数,在短链的情况下,活动连接数与QPS比较接近
-
QPS(并发)
连接状态为:time_wait close_wait,是NEW的请求
-
并发峰值
测量一个网站的重要指标,架构设计承载需要是最高并发峰值的5到10倍
代理的基础知识
代理的作用
-
1、web缓存
以提供加速
-
2、反向代理
以提高安全性和流量分发
-
3、内容路由
根据流量及内容类型等将请求转发至特定服务器
-
4、转码器
后端到代理服务器没有压缩,代理到客户端进行压缩
代理的重要性能指标
-
会话率
每秒建立新的连接速率
-
会话并发能力
-
数据率
数据传输率
LB实现方式
-
TCP层
- LVS
- haproxy
- nginx
-
应用层
- haproxy
- nginx
- ats
- apache
KV数据的常用算法
-
取模法
对K进行hash计算,有几台cache服务器就取模多少数值,可以将每次的请求分散至不同的服务器
* 缺点
添加和删除服务器,都会带来全部缓存失效
-
一致性hash算法
事先虚拟一个环,环上从零开始计数,到232个数值结束,其使用32位二进制表示,把每个服务器按照特定的方式计算(如IP地址进行hash计算),其hash的结果一定会在环上的0到232之间,服务器计算的结果就分散在此环之上。缓存数据时,对key进行hash计算,按顺时针找到离的最近的一个节点存放数据。如果其中一台cache server档机,只会影响此服务器上缓存的数据,不会让缓存全部失效
* 缺点:
hash环的偏斜(多个节点计算后,节点都在环上较近位置且在环的一侧位置),可以使用虚拟服务器方法解决(将一个节点虚拟成多个节点,再分散到环上)
Linux之HAProxy
一、HAProxy简介
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理 ,支持虚拟机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于高负载且需要持久连接或7层处理机制的web站点,这些站点通常又要会话保持或七层处理,HAProxy运行在时下的硬件上,完全可以支持数以万计的并发连接,并且它的运行模式使得它可以很简单安全的融合进你当前的架构中,同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动、单一进行模型,此模型支持非常大的并发连接数,多进行或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(user-space)实现所有这些任务,所以没有这些问题。 此模型的弊端是,在多核系统上,这些程序通常扩展性较差,这就是为什么它们必须进行优化以使每次个CPU时间片(Cycle)做更多的工作。
二、HAProxy主要版本:
1.4版本
其衍生于1.2版本,并提供额外的新特性,其中大多数是期待已久的
- 1、客户端侧的长连接(Client-side keep-alive)
- 2、TCP加速(TCP speedups)
- 3、响应池(response buffering)
- 4、RDP协议(remote desktop protocol)
- 5、基于源的粘性(Source-based stickiness)
- 6、更好的数据统计接口(a much better stats interfaces)
- 7、更详细的健康状态检测机制(more verbose health checks)
- 8、基于流量的健康评估机制(traffic-based health)
- 9、支持http认证
- 10、服务器管理命令行接口(server management from the CLI)
- 11、基于ACL的持久性(ACL-based persistence)
- 12、日志分析器
1.3版本
其衍生于1.2版本,并提供了额外的新特性
- 1、内容交换(Content switching):基于任何请求标准挑选服务器池
- 2、ACL:编写内容交换规则
- 3、负载均衡算法(load-balancing algorithms):更多的算法支持
- 4、内容检测(Content ipspection):阻止非授权协议
- 5、透明代理(transparent proxy):在Linux系统上允许使用客户端IP地址连入服务器
- 6、内核TCP拼接(kernel TCP splicing):无copy方式在客户端和服务端之间的转发数据以实现G级别的数据速率
- 7、分层设计(layered design):分别实现套接字、TCP、HTTP处理以提供更好的健壮性,更好的处理机制及便捷的演进能力
- 8、快速、公平调度器(fast and fair scheduler):为某些任务指定优先级可实现更好的Qos
- 9、会话速率限制(session rate limiting):适用于托管环境
三、支持的平台及OS
- x86、x86_64、Alpha、SPARC、MIPS及PARISC平台上的Linux 2.4
- x86、x86_64、ARM (ixp425)及PPC64平台上的Linux2.6
- UltraSPARC 2和3上的Sloaris 8/9
- Opteron和UltraSPARC平台上的Solaris 10
- x86平台上的FreeBSD 4.1-8
- 386, amd64, macppc, alpha, sparc64和VAX平台上的OpenBSD 3.1-current
若要获得最高性能,需要在Linux2.6或打了epoll补丁的Linux2.4上运行haproxy 1.2.5以上的版本,haproxy1.1l默认使用了polling系统为select(),其处理的文件数达数千个时性能便会急剧下降,1.2和1.3版本默认为poll(),在有些操作系统上可能会有性能方面的问题,但在Solaris上表现相当不错,HAProxy1.3在Linux2.6及打了epoll补丁的Linux 2.4上默认使用了epoll,在FreeBSD上使用Kqueue,这两种机制在任何负载上都能提供恒定的性能表现,在较新版本的Linux2.6(>=2.6.27.19)上,HAProxy还能够使用splice()系统调用在接口间无复制地转发任何数据,这甚至可达到10Gbps性能
HAProxy常规版本选择建议
- Linux 2.6.32及之后版本上运行HAProxy1.4
- 打了epoll补丁的Linux 2.4上运行HAProxy1.4
- FreeBSD上运行HAProxy1.4
- Solaris 10上运行Haproxy 1.4
四、HAProxy实现高性能的方法
-
1、单进程、事件驱动模型
显著降低了上下文切换的开销及内存占用
-
2、O(1)事件检查器(event checker)
允许其在高并发连接中对任何连接的任何事件实现即时探测
-
3、单缓冲(single buffering)机制
以不复制任何数据的方式完成读写操作,这会节约大量的CPU时钟周期及内存带宽
-
4、splice()系统调用机制
在2.6(>=2.6.27.19)Haproxy可以实现零复制转发(zero-copy forwarding),在Linux3.5及以上的OS中还可以实现零复制启动(zero-starting)
-
5、优秀的内存分配器
内存分配器在固定大小的内存池中实现即时内存分配,能够显著减少创建一个会话的时长
-
6、树形存储
侧重于使用作者多年前开发的弹性二叉树算法,实现了以O(log(N))的低开销来保持启动计时器命令、保持运行队列命令及管理轮询及最少连接队列
-
7、优化的HTTP首部分析机制
优化的首部分析功能避免了HTTP首部分析过程中重读任何区域
-
8、精心地降低了昂贵的系统调用
大部分工作在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等
所有的这些细微之处的优化实现了在中等规模负载之上依然有着相当低的CPU负载,甚至于在非常高的负载场景中,5%的用户空间占用率和95%的系统空间占用率也是非常普遍的现象,这意味着HAProxy进程消耗比系统空间消耗低20倍以上。因此,对OS进行性能调优是非常重要的。即使用户空间的占用率提高一倍,其CPU占用率也仅为10%,这也解释了为何7层处理对性能影响有限这一现象。由此,在高端系统上HAProxy的7层性能可轻易超过硬件负载均衡设备。
在生产环境中,在7层处理上使用HAProxy作为昂贵的高端硬件负载均衡设备故障故障时的紧急解决方案也时长可见。硬件负载均衡设备在“报文”级别处理请求,这在支持跨报文请求(request across multiple packets)有着较高的难度,并且它们不缓冲任何数据,因此有着较长的响应时间。对应地,软件负载均衡设备使用TCP缓冲,可建立极长的请求,且有着较大的响应时间。
配置HAProxy
安装haproxy
- yum install haproxy
配置程序及配置文件
/etc/haproxy/haproxy.cfg
/usr/sbin/haproxy
/etc/haproxy/haproxy.cfg
配置文件格式
-
global配置段
用于设定全局配置参数
-
proxy相关配置段
如defaults,listen,frontend和backend
时间格式
一此包含了值的参数表示时间,如超时时长,这些值一般以毫秒为单位,但也可以使用其它的时间单位后缀
-
us
: 微秒(microseconds),即1/1000000秒 -
ms
: 毫秒(milliseconds),即1/1000秒 -
s
: 秒(seconds) -
m
: 分钟(minutes) -
h
: 小时(hours) -
d
: 天(days)
示例:
global
daemon
maxconn 25600
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
default_backend servers
backend servers
server server1 127.0.0.1:8080 maxconn 32
配置了一个监听在所有接口的80端口上HTTP proxy服务,它转发所有的请求至后端监听在127.0.0.1:8000上的"server"
全局配置
global配置中的参数为进程级别的参数,且通常与运行的OS相关
-
进程管理及安全相关的参数
-
chroot <jail dir>
- 修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是要确保指定的目录为空目录且任何用户均不能有写权限
-
daemon
- 让Haproxy以守护进程的方式工作于后台
-
gid <number>
- 以指定的GID运行haproxy
-
group <group name>
- 同GID,不过指定的是组名
-
log <address <facility> [max level [min level]]
- 定义全局的syslog服务器,最多可定义两个
-
log-send-hostname [string]
- 在syslog信息的首部添加当前主机名,默认是使用当前主机名
-
nbporc <number>
- 指定启动的haproxy进程个数,默认只启动一个,一般只在单进程仅能打开少数文件描述符的场景才使用多进程模式
-
pidfile <file>
- pid文件
-
uid
- 以指定的UID身份运行进程
-
unlimit -n
- 设定每进程能够打开的最大文件描述符数据,默认情况下其会自动进行计算,不推荐修改此项
-
user
- 同UID,但使用用户名
-
stats socket /var/lib/haproxy/status
- 访问stats时,使用socket调用的文件
-
node
- 定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时使用
-
description
- 当前实例的描述信息
-
-
性能调整相关的参数
-
maxconn <number>
- 设定每个haproxy进程所接受的最大并发连接数,等同于ulimit -n
-
maxpipes <number>
- haproxy使用Pipe完成基于内核的TCP报文重组,用于设定每进行所允许使用的最大Pipe个数,每个pipe使用两个文件描述符
-
noepoll
- 在linux系统上禁用epoll机制
-
nokqueue
- 在BSD系统上禁用kqueue机制
-
nopoll
- 禁用poll机制
-
nosepoll
- 在linux禁用启发式epoll机制
-
nosplice
- 禁止在Linux套按字上使用内核tcp重组,这会导致更多的recv/send系统调用,不过在2.6.25-28系统的内核上,tcp重组功能有bug
-
spread-checks <0..50,in percent>
- 在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长
-
tune.bufsize <number>
- 设定buffer的大小,同样的内存条件下,较小的值可以让haproxy有能力接受更多的并发连接,较大的值可以让某些应用程序使用较大的cookie信息;默认为16384,其可以在编译时修改,不过强烈建议使用默认值
-
tune.chksize <number>
- 检查缓冲的大小,专用检测用户的请求首部信息,建议默认值
-
tune.maxaccept <number>
- 一次性一次交由多少个请求给进程
-
tune.maxpollevents <number>
- 设定一次系统调用可以处理的事件最大数,默认值取决于OS;其值小于200时可节约带宽,但会略微增大网络延迟,而大于200时会降低延迟,但会稍稍增加网络带宽的占用量;
-
tune.maxrewrite <number>
- 设定首部重写或追加而预留的缓冲空间,建议使用1024左右的大小,在需要使用更大的空间时,haproxy全自动增加其值
debug
: 调度模式quiet
: 静默模式
-
代理
代理相关的配置可以有如下配置段
-
defaults <name>
- 用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个defaults所重新设定
-
frontend <name>
- 用于定义一系列监听的套拼字,这些套按字可接受客户端请求并与之建立连接
-
backend <name>
- 用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器
-
listen <name>
- 通过关联“前端”和“后端”定义了一个完整的代理 ,通常只对TCP流量有效
所有代理的名称只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和:(冒号)。此外,ACL名称会区分字母大小写。
配置文件中的关键字参考
1、balance
- 用法
balance <algorithm> [arguments]
balance url_param <param> [check_post [<max_wait>]]
- 功能
- 定义负载算法,可用于defaults,listen,backend段
支持的算法类型:
- 动态:权重可动态调整,服务器自己调整
- 静态:调整权重不会实时生效,只有重启才会生效
调度算法
-
roundrobin
基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接
-
static-rr
基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制
-
leastconn
新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重
-
source
将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性
-
uri
对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性
-
uri-param
通过<argument>为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用hash-type修改此特性
-
hdr(name)
对于每个HTTP请求,通过<name>指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.magedu.com来说,仅计算magedu字符串的hash值)以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性
rdp-cookie
rdp-cookie(name)
示例1:
backend app
balance hdr(User-Agent)
server srv1 172.16.36.70:80 check
server srv2 172.16.36.71:80 check
server srv3 172.16.36.60:80 check
server srv4 172.16.36.61:80 check
示例2:
backend app
balance uri
hash-type consistent
server srv1 172.16.36.70:80 check
2、bind
-
用法
bind [<address>]:<port-range> [,...]
bind [<address>]:<port_range> [, ...] interface <interface>
-
功能
- 此指令仅能用于frontend和listen区段,用于定义一个或几个监听的套接字
frontend main
bind *:80
bind *:8080
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
3、mode
-
用法
mode {tcp|http|health}
-
功能
- 设定实例的运行模式或协议。当实现内容交换时,前端和后端必须工作于同一种模式(一般说来都是HTTP模式),否则将无法启动实例
tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;此为默认模式,通常用于SSL、SSH、SMTP等应用;
http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;
health:实例工作于health模式,其对入站请求仅响应“OK”信息并关闭连接,且不会记录任何日志信息;此模式将用于响应外部组件的健康状态检查请求;目前业讲,此模式已经废弃,因为tcp或http模式中的monitor关键字可完成类似功能
4、hash-type
- 用法
hash-type <method>
- 功能
- 定义用于将hash码映射至后端服务器的方法;其不能用于frontend区段;可用方法有map-based和consistent,在大多数场景下推荐使用默认的map-based方法
map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。
consistent:hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。
backend app
balance uri
hash-type consistent
server srv1 172.16.36.70:80 check
server srv2 172.16.36.71:80 check
server srv3 172.16.36.60:80 check
server srv4 172.16.36.61:80 check
-
5、log
- 用法
log global
log <address> <facility> [<level>][<minlevel>]
- 功能
- 为每个实例启用事件和流量日志,因此可用于所有区段。每个实例最多可以指定两个log参数,不过,如果使用了“log global”且"global"段已经定了两个log参数时,多余了log参数将被忽略
- 用法
-
6、maxconn
- 用法
maxconn <conns>
- 功能
- 设定一个前端的最大并发连接数,因此,其不能用于backend区段。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出“global”段中的定义。此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,再加上其它的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护40000-50000并发连接。如果为<conns>指定了一个过大值,极端场景下,其最终占据的空间可能会超出当前主机的可用内存,这可能会带来意想不到的结果;因此,将其设定了一个可接受值方为明智决定。其默认为2000
- 用法
-
7、default_backend
- 用法
maxconn <conns>
- 功能
- 在没有匹配的"use_backend"规则时为实例指定使用的默认后端,因此,其不可应用于backend区段。在"frontend"和"backend"之间进行内容交换时,通常使用"use-backend"定义其匹配规则;而没有被规则匹配到的请求将由此参数指定的后端接收。
- 用法
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -j .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
-
8、server
-
用法:
server <name> <address>[:port][param*]
-
功能:
- 为后端声明一个server,因此不能用于defaults和frontend区段
-
服务器或默认服务器参数
- backup : 设定为备用服务器,即sorry server
- check : 健康状态检测
- inter <delay> : 设定健康状态检测时的时间,默认为2000,单位为ms
- fall <number> : 从up-->down(soft state-->hard state),默认为3次
- rise <number> : 从down-->up的次数
- cookie <value> : 为server设定个cookie值,会话级别的cookie,基于cookie的原绑定方式,会在响应报文中的cookie头后添加相应的cookie值
- maxconn :此服务器接受的并发连接最大数值
- maxqueue : 请求队列的最大长度
- observer <mode> : 通过流量判断后端服务器的状态,默认为禁用,其支持4层和7层
- weight <number> : 默认为1,最大为256,0表示不被调用
- redir <prefix> : 启用重定向功能,所有发往此服务器的GET和HEAD请求,均以302响应,在prefix最后不能加/,且不能使用相对地址
server srv1 172.16.100.6:80 redir http://imageserver.zhenping.me check
-
-
9、opttion check
-
用法:
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
-
option httpchk <mothod> <uri> <version>
:不能用于frontend段
-
功能
- 健康状态检测方法定义
-
backend https_relay
mode tcp
option check OPTIONS * HTTP/1.1\r\nHost:\ www.zhenping.me
server apache1 172.16.36.70 check prot 80
对server172.16.36.70使用option check定义的方法进行检测,但可以使用80端口进行健康状态检测
-
10、capture request header
- 用法:
capture request header <name> len <length>
- 功能:
- 捕获并记录指定的请求首部最近 一次出现时的第一个值,仅能用于“frontend”和“listen”区段。捕获的首部值使用花括号{}括起来后添加进日志中。如果需要捕获多个首部值,它们将以指定的次序出现在日志文件中,并以竖线“|”作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境中使用的“Host”、上传请求首部中的“Content-length”、快速区别真实用户和网络机器人的“User-agent”,以及代理环境中记录真实请求来源的“X-Forward-For”。可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。
- 用法:
-
11、capture response header
- 用法
capture response header <name> len <length>
- 功能
- 捕获并记录响应首部,其格式和要点同请求首部
- 用法
-
11、stats enable
- 用法
stats enable
- 功能
- 启用基于程序编译时默认设置的统计报告,不能用于frontend段,
listen statistics #定义listen区段名称 bind *:9090 #定义监听端口 stats enable #启用stats stats hide-version #隐藏版本 stats refresh 10s #刷新时间 stats uri /haproxyadmin?stats #stats的URI地址 stats realm "HAProxy\ statistics" #stats的登陆提示信息 stats auth zhenping:123321 # 定义用户名和密码 stats admin if TRUE #如果用户验证成功,就给予admin权限
- 用法
-
12、option httplog
- 用法
option httplog [clf]
- 功能
- 启用记录HTTP请求,会话状态和计时器的功能,默认情况下,日志输入格式非常简陋,因为其仅包括源地址、目标地址和实例名称,而“option httplog”参数将会使得日志格式变得丰富许多,其通常包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部及cookie、“frontend”、“backend”及服务器名称,当然也包括源地址和端口号等
- 用法
-
13 option logasap
-
14 no option logasap
- 功能:
启用或禁用提前将http请求记入日志,不能用于frontend段
listen http_proxy 0.0.0.0:80 mode http option httplog option logasap log 172.16.100.9 local2
- 功能:
-
15、option forwardfor
- 用法:
option forwardfor [except <network>][header <name>][if-none]
- 功能
允许在发往服务器的请求首部中插入“X-Forwarded-For”首部,些参数定义后,需要在后端服务器的记录日志格式修改为记录X-Forwarded-For的信息,方可记录下客户端IP地址
if-none: 仅在此首部不存在时才将其添加至请求报文中。
frontend www mode http option forwardfor except 127.0.0.1/8
- 用法:
-
16、errorfile
- 用法:
errorfile <code> <file>
- 功能
- 在用户请求不存的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中
- <code> : 指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504
- <file>:指定用于响应的页面文件
errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http
- 用法:
-
17、errorloc和errorloc302
- 用法:
errorloc <code> <url>
errorloc302 <code> <url>
- 功能
- 请求错误时,返回一个HTTP重定向至某URL的信息;可用于所有配置段中。
- <code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
- <url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向
- 用法:
需要留意的是,这两个关键字都会返回302状态码,这将使得客户端使用同样的HTTP方法获取指定的URL,对于非GET方法的场景(如POST)来说会产生问题,因为返回客户的URL是不允许使用GET以外的其它方法的。如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端
-
18、errorloc303
- 用法:
errorloc303 <code> <url>
- 功能
- 请求错误时,返回一个HTTP重定向至某URL的信息给客户端,可用于所有配置段中
- <code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有400、403、408、500、502、503和504;
- <url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向
- 用法:
backend webserver
server 172.16.100.6 172.16.100.6:80 check maxconn 3000 cookie serv01
server 172.16.100.7 172.16.100.7:80 check maxconn 3000 cookie serv02
errorfile 403 /etc/haproxy/errorpages/sorry.htm
errorfile 503 /etc/haproxy/errorpages/sorry.htm
-
19、option http-server-close
-
20、no option http-server-close
- 功能:由客户端到服务端的连接设定,当HAProxy的保持连接开启的时候,需要把这项开起来,服务器主动断开连接,其是向报文中添加connection:close的头信息,客户端收到后,将发出断开连接请求
-
21、option http-pretend-keepalive
- 功能:当启用http-server-close或option forceclose代理服务器添加一个connect:close(就是短连接模式)的头部信息,转发至后端server,当后端的server收到报文后,无法识别或拒绝响应。所以需要代理 服务器就需要假装是保持连接模式,而不发送connection:close的信息头部,在使用了option forceclose,http-server-close的选项时,就应该启用http-pretend-keepalive选项
-
22 option httpclose
-
23 no option httpcolse
- 功能:启用或禁用被动http连接功能,是否允许服务端断开连接,跟http-server-close一样
-
24、option redispatch
-
25、no option redispatch
- 是否允许做重新调度,如果做了保持功能的情况下,被访问的主机坏了,是不是允许把请求调到其它主机
-
26、redirect
- 功能:做重定向
acl clear dst_port 80 acl secure dst_port 80 acl login_page url_beg /login acl logout url_beg /logout acl uid_given url_reg /login?userid=[^&]+ acl cookie_set hdr_sub(cookie) SEEN=1 redirect prefix https://zhenping.me set-cookie SEEN=1 if !cookie_set redirect prefix https://zhenping.me if login_page !secure redirect location http://www.zhenping.me if !login_page secure redirect location / clear-cookie USERID= if logout
-
27、reqadd
- 功能:向请求报文添加首部
acl is-ssl dst_port 81 reqadd X-Proto:\ SSL if is-ssl 如果是通过81访问的请求,就向请求首部添加X-Proto: SSL的首部信息
-
28、rspadd
- 向响应报文添加首部
rspadd Via:\ node1.zhenping.me
-
29、timeout http-keep-alive
- 用法:
timeout http-keep-alive 10s
- 功能:
- 开启haproxy的保持连接功能
- 用法:
-
30、option dontlognull
- 功能:不记录自己的健康状态检查的日志
配置案例
http服务器配置示例
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
option httpclose
option logasap
option dontlognull
capture request header Host len 20
capture request header Referer len 60
default_backend servers
frontend healthcheck
bind :1099
mode http
option httpclose
option forwardfor
default_backend servers
backend servers
balance roundrobin
server websrv1 192.168.10.11:80 check maxconn 2000
server websrv2 192.168.10.12:80 check maxconn 2000
负载均衡MySQL服务的配置示例
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
option httplog
option dontlognull
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 600
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend mysql
bind *:3306
mode tcp
log global
default_backend mysqlservers
backend mysqlservers
balance leastconn
server dbsrv1 192.168.10.11:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
server dbsrv2 192.168.10.12:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
ACL
Haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息做出转发决策,这大大增加了其配置弹性,其配置法则通常分为两步,首先先定义ACL,即定义一个测试条件,而后在条件得到满足时执行特定的动作,如阻止请求或转发至某特定的后端
-
定义ACL的语法格式
-
acl <aclname> <criterion> [flags] [operator] <value> ....
-
<aclname>
: ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl -
<criterion>
: 测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在<value>之前指定一个操作符[operator] -
[flags]
: 目前haproxy的acl支持的标志位有3个-
-i
: 不区分<value>中模式字符的大小写 -
-f
: 从指定的文件中加载模式 -
--
: 标志符的强制结束符,在模式中的字符串像标记符时使用
-
-
<value>
: acl测试条件支持的值有以下四类- 整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;
- 字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在其之前使用“--”标志位;
- 正则表达式:其机制类同字符串匹配;
- IP地址及网络地址
-
-
同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种:“与”(默认即为与操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)
-
常用的测试标准(criteria)
-
be_sess_rate <integer>
用于测试指定的backend上会话创建的速率(即每秒创建的会话数)是否满足指定的条件;常用于在指定backend上的会话速率过高时将用户请求转发至另外的backend,或用于阻止攻击行为。例如:
backend dynamic mode http acl being_scanned be_sess_rate gt 50 redirect location /error_pages/denied.html if being_scanned
-
fe_sess_rate <integer>
用于测试指定的frontend(或当前frontend)上的会话创建速率是否满足指定的条件;常用于为frontend指定一个合理的会话创建速率的上限以防止服务被滥用。例如下面的例子限定入站邮件速率不能大于50封/秒,所有在此指定范围之外的请求都将被延时50毫秒
frontend mail bind :25 mode tcp maxconn 500 acl too_fast fe_sess_rate ge 50 tcp-request inspect-delay 500ms tcp-request content accept if ! too_fast tcp-request content accept if WAIT_END
-
hdr(header) <string>
用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符。测试服务器端的响应报文时可以使用shdr()。例如下面的例子用于测试首部Connection的值是否为close
hdr(Connection) -i close
-
method <string>
测试HTTP请求报文中使用的方法
-
path_beg <string>
用于测试请求的URL是否以<string>指定的模式开头。下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头
acl url_static path_beg -i /static /images /javascript /stylesheets
-
path_end <string>
用于测试请求的URL是否以<string>指定的模式结尾。例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾
acl url_static path_end -i .jpg .gif .png .css .js
-
hdr_beg <string>
用于测试请求报文的指定首部的开头部分是否符合<string>指定的模式。例如,下面的例子用记测试请求是否为提供静态内容的主机img、video、download或ftp
acl host_static hdr_beg(host) -i img. video. download. ftp.
-
hdr_end <string>
用于测试请求报文的指定首部的结尾部分是否符合<string>指定的模式
url_beg
url_end
path_reg
url_reg
-
总结
balance的算法:
- roundrobin
- static-rr
- leastconn
- source
- uri
- url_param
- hdr(HEADER)
acl creterion的方法
- path
- path_beg
- path_end
- src
- src_port
- dst
- dst_port
- url_beg
- url_end
- url_reg
- path_reg
- hdr(Header)
动静分离示例:
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
option httpclose
option logasap
option dontlognull
capture request header Host len 20
capture request header Referer len 60
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .jpeg .gif .png .css .js
use_backend static_servers if url_static
default_backend dynamic_servers
backend static_servers
balance roundrobin
server imgsrv1 172.16.200.7:80 check maxconn 6000
server imgsrv2 172.16.200.8:80 check maxconn 6000
backend dynamic_servers
cookie srv insert nocache
balance roundrobin
server websrv1 172.16.200.7:80 check maxconn 1000 cookie websrv1
server websrv2 172.16.200.8:80 check maxconn 1000 cookie websrv2
server websrv3 172.16.200.9:80 check maxconn 1000 cookie websrv3