配置实例:
1 | #Global settings |
规划
1 | director: |
实验:
Keepalived + haproxy
Keepalived + nginx
这个地方只是最简单的,可自行参考《构建高可用Linux服务器》
配置实例:
1 | #Global settings |
规划
1 | director: |
实验:
Keepalived + haproxy
Keepalived + nginx
这个地方只是最简单的,可自行参考《构建高可用Linux服务器》
如果做负载均衡,建议使用haproxy;;
由于haproxy是单进程的程序,在处理高并发的时候会做的很好,当然由于单进程,在多CPU的场景中,就要对haproxy进行调整,以便能够有效利用多CPU;
HAProxy的配置处理3类主要参数来源:
一些包含了值的参数表示时间,如超时时长,这些值一般以毫秒为单位,但也可以使用其他的时间单位后缀。
下面的例子配置了一个监听在所有接口的80端口上HTTP proxy服务,它转发所有的请求至后端监听在127.0.0.1:8000上的”server”.
1 | global |
“global”配置中的参数为进程级别的参数,且通常与其运行的OS相关;
*进程管理及安全相关的参数
uid:以指定的UID身份运行haproxy进程
ulimit-n : 设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项;
*性能调整相关的参数
代理相关的配置可以如下配置段中。
“defaults”段用于为所有其他配置段提供默认参数,这配置默认参数可由下一个”defaults”所重新设定;
“frontend”段可用于定义一系列监听的套接字,这些套接字可接收客户端请 求并与之建立连接;
“backend”段用于定义一系列”后端”服务器,代理将会将对应客户端的请求转发至这些服务器
“listen”段通过关联”前端”和”后端”定义一个完整的代理,通常只对TCP流量有用;
所有代理的名称只能使用大写字母,小写字母,数字,中线,下划线,点号,冒号,此外,ACL名称会区分字母大小写;
balance
[ ]
balance url_param [check_post[max_wait]]
定义负载均衡算法,可用于”defaults”、”listen”和”backend”。
hash-type
定义用于将hash码映射至后端服务器的方法,其不恩能够用于frontend区段,可用方法有map-based和consistent,在大多数场景下推荐使用默认的map-based方法;
log global
log[ [ ]]
为每个实例启用时间和流量日志,因此可用于用于区段,每个实例最多可以指定两个log参数,不过,如果使用了”log global”且”global”段已经定义了两个log参数时,多余了log参数将被忽略;
maxconn
设定一个前端的最大并发连接数,因此,其不能用于backend区段,对于大型站点来说,可以尽可能调大此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出”global”段中的定义。此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,再加上其他的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间将能维护40000-50000并发连接。
如果为
default_backend
在没有匹配的”use_backend”规则时为实例指定使用的默认后端,因此,其不可应用于backend区段,在”frontend”和”backend”之间进行内容交换时,通常使用”use_backend”定义其匹配规则,而没有被规则匹配到的请求将有此参数指定的后端接收。
使用案例:
use_backend dynamic if url_dyn
use_backend static if url_css url_img extension_img
default_backend dynamic
server
:port
为后端声明一个server,因此,不能够用于defaults和frontend区段
服务器或默认服务器参数:
inter
:设定健康状态检查的时间间隔,单位为毫秒,默认为2000,也可以使用fastinter和downinter来根据服务器端状态优化此时间延迟;
rise:设定健康状态检查中,某离线的server从离线状态转至正常状态需要成功检查的次数;
fall:确认server从正常状态转换为不可用状态需要检查的次数;
server srv1 172.16.100.6:80 redir http://www.test.com check
检查方法:
option httpchk
option httpchk
opeion httpchk
option httpchk,不能用于frontend段,例如:
backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80
使用案例;
server first 172.16.100.7:1080 cookie first check inter 1000
server second 172.16.100.8:1080 cookie second check inter 1000
capture request header
len
捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于”frontend”和”listen”区段,捕获的首部值使用花括号{}括起来后添加进日志中。如果需要捕获多个首部值,他们将以指定的次序出现在日志文件中,并以竖线”|”作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境中使用的”Host”、上传请求首部中的”Content-length”、快速区别真实用户和网络机器人的”User-agent”,以及代理环境中记录真实请求来源的”X-Forward-For”。
capture response header
len
捕获并记录响应首部,其格式和药店同请求首部。
启用基于程序编译时默认设置的统计报告,不能用于”frontend”区段。只要没有别外的其他设定,他们就会使用如下的配置:
- stats uri : /haproxyadmin?stats
- stats realm : “HAProxy Statistics”
- stats auth : no authentication
- stats scope : no restriction
尽管”stats enable”一条就能够启用统计报告,但还是建议设定其他所有的参数,以免其依赖于默认设定而带来非期后果,下面是一个配置案例:
1 | backend public_www |
stats hide-version
启用统计报告并隐藏HAProxy版本报告,不能用于”frontend”区段,默认情况下,统计页面会显示一些游泳信息,包括HAProxy的版本号,然后,向所有人公开HAProxy的精确版本号是非常有风险的,因为他能帮助恶意用户快速定为版本的缺陷和漏洞,尽管”stats hide-version”一条就能够启用统计报告,但还是建议设定其他所有的参数,以免其依赖于默认设定而带来非期后果,具体请参照”stats enable”一节的说明。
stats realm
启用统计报告并高精认证领域,不能用于”frontend”区段,haproxy在读取realm时会将其视作一个单词,因此,中间的任何空白字符都必须使用反斜线进行转义,此参数仅在于”stats auth”配置使用时有意义。
尽管”stats realm “ 一条就能够启用统计报告,但还是建议设定其他所有的参数,以免其依赖于默认设定而带来非期后果,具体请参照”stats enable”一节的说明。
stats scope {
| “ . “}
启用统计报告并限定报告的区段,不能用于”frontend”区段,当指定此语句时,统计报告将仅显示其列举出区段的报告信息,所有其他区段的信息将被隐藏。如果需要显示多个区段的统计报告,此语句可以定义多次。需要注意的是,区段名称检测仅仅是以字符串比较的方式进行,他不会真检测指定的区段是否真正存在。
尽管”stats scope”一条就能够启用统计报告,但还是建议设定其他所有的参数,以免其依赖于默认设定而带来非其后果。下面是一个配置案例。
1 | backend private_monitoring |
stats auth
:
启用带认证的统计报告功能并授权一个用户账号,其不能用于”frontend”区段。
:授权进行访问的用户名; :此用户的访问密码,明文格式。
此语句将基于默认设定启用统计报告功能,并仅允许其定义的用户访问,其也可以定义多次以授权多个用户找好,尅结合”stats realm”参数在提示用户认证是给出一个领域说明信息,在使用非法用户访问统计功能时,其将会响应一个”401 Forbidden”页面。其认证方式为HTTP Basic认证,密码传输会以明文方式进行,因此,配置文件中也使用明文方式进行,因此,配置文件中也使用明文方式存储以说明其非保密信息故此不能相同于其他关键性账号的密码。
尽管”stats auth”一条就能够启用统计报告,但还是建议设定其他所有的参数,以免其依赖于默认设定而代理非期后果。
stats admin {if | unless}
在指定的条件满足时启用统计报告页面的管理级别功能,它允许通过web接口启用或禁用服务器,不过,基于安全的角度考虑,统计高博爱页面应该尽可能是只读的。此外,如果启用了HAProxy的多进程模式,启用此管理级别将有可能导致异常行为。
目前来说,POST请求方法被限制于金恩能够使用缓冲区域去保留部分之外的空间,因此,服务器列表不能过长,否则,此请求将无法正常工作,因此,建议一次仅调整少数几个服务器,下面是两个案例,第一个限制了仅能在本机打开报告页面时启用管理级别功能,第二个定义了仅允许通过认证的用户使用管理级别功能。
1 | backend stats_localhost |
option httplog [clf]
启用记录HTTP请求,会话状态和计时器的功能。
clf:使用CLF格式来代替HAProxy默认的HTTP格式,通常在使用仅支持CLF格式的特定日志分析器时才需要使用此格式。
默认情况下,日志输入格式非常简陋,因为其仅包含源地址、目标地址和实例名称,而”option httplog”参数将会使得日志格式变得丰富许多,其通常包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部及cookie、”frontend”、”backend”及服务器名称,当然也包括源地址和端口号等。
no option logasap
启用或禁用提前将HTTP请求记入日志,不能用于”backend”区段。
默认情况下,HTTP请求是在请求结束时金牛星记录一百年能就爱你勾起整体传输时长和字节数记入日志,由此,传较大的对象时,其记入日志的时长可能会略有延迟。”option logasap”参数能够在服务器发送complete首部时及时记录日志,只不过,此时将不记录整体传输时长和字节数。此情形下,捕获”Content-Length”响应首部来记录传输的字节数是一个较好选择。下面是一个例子.
1 | listen http_proxy 0.0.0.0:80 |
option forwardfor [except
] [header ] [if-none]
允许在发往服务器的请求首部中插入”X-Forwarded-For”首部。
if-none:仅在此首部不存在时才将其添加至请求报文中。
HAProxy工作于反向代理模式,其发往服务器的请求中的客户端IP均为HAProxy主机的地址而非真正客户端的地址,这会使得服务器端的日志信息记录不了真正的请求来源,”X-Forwarded-For”首部则可用于解决此问题,HAProxy可以向每个发往服务器的请求上添加此首部,并以客户端IP为其value。
需要注意的是,HAProxy工作于隧道模式,其仅检查每一个连接的第一个请求,因此,仅第一个请求报文被附加此首部,如果想为每一个请求都附加此首部,请确保同时使用了”option httpclose”、”option forceclose”和”option http-server-close”几个option。
下面是一个例子:
frontend www
mode http
option forwardfor except 127.0.0.1
errorfile
在用户请求不存在的页面时,返回一个页面文件给客户端而非有haproxy生成的错误代码,可用于所有段中;
:指定对HTTP的哪些状态码返回指定的页面,这里可用的状态码有200,400,403,408,500,502,503和504;
例如:
errorfile 400 /etc/haproxy/errorpages/400badreq.http
errorfile 403 /etc/haproxy/errorpages/403forbid.http
errorfile 503 /etc/haproxy/errorpages/503sorry.http
errorloc
errorloc302
请求错误时,返回一个HTTP重定向至某URL的信息,可用于所有配置段中。
:指定对HTTP的哪些状态码返回指定的页面,这里可用的状态码有200、400、403、408、500、502、503和504;
需要留意的是,这两个关键字都会返回302状态码,这将使得客户端使用同样的HTTP方法获取指定的URL,对于非GET的场景中(如POST)来说会产生问题,因为返回客户的URL是不允许使用GET以外的其他方法的。如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端。
errorloc 303
请求错误时,返回一个HTTP重定向至某URL的信息给客户端:可用于所有配置段中。
:指定对HTTP的那些状态码返回指定的页面,这里可用的状态码有400,403,408,500,502,504;
例如:
1 | backend webserver |
环境介绍:
192.168.122.14 node2.test.com memcached服务器
192.168.122.7 nfs.test.com LNMP环境
1 | [root@node2 ~]# tar xf libevent-2.0.22-stable.tar.gz |
1 | [root@node2 ~]# yum -y install cyrus-sasl-devel |
提供启动脚本和系统配置文件
1 | [root@node2 memcached-1.4.24]# useradd -r memcached |
测试
1 | telnet localhost 11211 |
这个时候已经完成memcached的安装;;
前提:已经完成LNMP平台的搭建
1 | [root@nfs ~]# tar xf memcache-2.2.7.tgz |
测试:
1 | <?php |
1 | service php-fpm restart |
1 | <?php |
1 | [root@nfs html]# vim /etc/php.ini |
新建php页面setsess.php,为客户端设置启用session:
1 | <?php |
新建php页面showsess.php,获取当前用户的会话ID:
1 | <?php |
1 | [root@nfs ~]# tar xf memadmin-1.0.12.tar.gz |
访问:
http://192.168.122.7/memadmin/index.php
添加memcached主机即可进行监控;;
需要说明:在前一节,Nginx配置使用memcached的缓存时,没有配置成功。额,也没看懂;;
1 | # vim /etc/rc.d/init.d/memcached |
1 | #!/bin/sh |
192.168.122.7 web php
192.168.122.220 mysql
1 | #tar xf nginx-1.9.2.tar.gz |
二、测试nginx
测试内容如下:
1 | #vim /etc/nginx/nginx.conf |
1 | yum -y install libxml2-devel bzip2-devel libcurl-devel libmcrypt-devel |
1 | [root@nfs php-5.6.12]# vim /etc/nginx/nginx.conf |
1 | [root@nfs pma]# unzip phpMyAdmin-4.4.14-all-languages.zip |
然后这两种方式都可;;
http://192.168.122.7/pma
https://192.168.122.7/pma
1 | [root@node1 ~]# cat /etc/rc.d/init.d/nginx |
Master MySQL服务器:192.168.122.220 node1.test.com node1
Slave MySQL服务器: 192.168.122.14 node2.test.com node2
MySQL Proxy服务器: 192.168.122.25 nfs.test.com nfs
1 | [root@nfs ~]# tar xf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local |
主机MySQL上执行命令如下:
1 | mysql> grant all on *.* to 'test'@'192.168.122.25' identified by 'redhat'; |
从机MySQL上执行命令如下:
1 | mysql> grant all on *.* to 'test'@'192.168.122.25' identified by 'redhat'; |
在这一步,如果前面已经配置了主从复制的话,没必要写两遍;
1 | cp -p /usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua /usr/local/mysql-proxy/share/doc/mysql-proxy/ |
mysql-proxy的配置文件:
1 | [root@nfs local]# vim /etc/sysconfig/mysql-proxy |
mysql-proxy的启动脚本:
1 | #!/bin/bash |
测试一
测试二:
测试三:进行监管
1 | if not proxy.global.config.rwsplit then |
1 | [mysqld] |
本文有参考《构建高可用Linux服务器》5.2.3,但是有一点没能明白的是本书第二步,故而改成如上所示;
以后可直接从25这个主机上操作,不需考虑后面主机;;;
MySQL Proxy
libevent 1.x or higher
lua 5.1.x or higher
glib2 2.6.0 or higher
pkg-config
libtool-1.5 or higher
MySQL 5.0.x or higher developer files
添加用户
1 | # useradd - r mysql-proxy |
安装
1 | #tar xf mysql-proxy-0.8.2.tar.gz -C /usr/local |
添加环境变量脚本
1 | #vim /etc/profile.d/mysql-proxy.sh |
mysql proxy的各配置参数请看官方文档:http://dev.mysql.com/doc/refman/
四、安装配置
1 | #mysql-proxy --daemon --log-level=debug --plugins="proxy" --log-file=/var/log/mysql-proxy.log --proxy-backend-addresses="172.16.100.106:3306" --proxy-read-only-backend-addresses="172.16.100.107:3306"; |
107:
mysql -uadmin -h 172.16.100.201 –port=4041 -p
admin
select * from backends; 用来查看有几个后端
会显示state是unknown状态;
mysql -u root -predhat -h 172.16.100.201 –port=4040 -e ‘create database hellodb’;
会发现状态变成了up,说明操作是在代理上操作的,写到了后端服务器上;
1 |
|
1 |
|
这个写的不错:
http://www.zhengdazhi.com/archives/923
关于这一个,可以直接参考The Next;;;
1 | [root@node1 ~]# egrep -v '^$|#' /etc/my.cnf |
1 | [root@node2 ~]# egrep -v '^$|#' /etc/my.cnf |
1 | mysql>GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.122.%' IDENTIFIED BY 'replpass'; |
如果遇到mysql -urepluser -h 192.168.122.220 -p
出现失败 repluser@node1.test.com 说明出现了域名解析,那么,
skip_name_reslove=ON即可;;;
1 | #On Master |
Master:
show global variables like “binlog_do_db”;
仅将指定数据库的相关修改操作记入二进制日志;
show global variables like “binlog_ignore_db”;
Slave:
replicate-do-db =
replicate-do-table =
replicate-ignore-db =
replicate-ignore-table =
replicate-wild-do-table =
replicate-wild-ignore-table =
关于replicate-wild-do-table可能带来的问题:
http://dinglin.iteye.com/blog/1207776
在进行过滤的时候,应该在Slave上进行定义过滤规则!!
由于这些变量是只读的,所以show没法看到;
例如:
#vim /etc/my.cnf
replicate-do-db = discuz
#service mysqld restart
mysql>show slave status\G
可以看到只复制主服务器discuz这个数据库;
GTID(Global Transaction Identifiers)
GTID:由服务器的UUID并结合事务ID标识出来的唯一身份符;
多线程复制:
从服务器使用:
slave-parallel-workers=#(线程数目最好和数据库数目相同)
0:表示禁用
提供的工具:
实现快速启动从服务器,能够快速检查已经保存的GTIDs,然后从那些没有执行的GTIDs事务中进行备份;
检查复制环境是否满足的工具
发现并显示复制的拓扑图
并显示主机名和端口号
master故障后,快速使slave提升为master;
管理工具
MySQL5.6引入的GTID(Global Transaction IDs)使得其复制功能的配置、监控及管理变得更加易于实现,且更加健壮;
要在MySQL5.6中使用复制功能,其服务配置段[mysqld]中至少应该定义如下选项:
binlog-format:二进制日志的格式,有row,statement和mixed几种类型:
需要注意的是,当设置隔离级别为READ-COMMITTED必须设置二进制日志格式为ROW,现在MySQL官方认为statement这个已经不再适合继续使用;但mixed类型在默认的事务隔离级别下,可能会导致主从数据不一致;
log-slave-updates、gitd-mode、enforce-gtid-consistency、report-port和report-host:用于启动GTID及满足附属的其他需求;
master-info-repository和reply-log-info-repository:启用此两项,可用于实现在崩溃时保证二进制及从服务器安全的功能;
sync-master-info:启用之后可保证无信息丢失;
slave-paralles-workers:设定从服务器的SQL线程数,0表示关闭多线程复制功能;
binlog-checksum、master-verity-checksum和slave-verity-checksum:启用复制相关的所有校验功能;
binlog-rows-query-log-events:启用之后可用于在二进制日志记录事件相关的信息,可降低故障排除的复杂度;
log-bin:启用二进制日志,这是保证复制功能的基本前提;
server-id:同一个复制拓扑中的所有服务器的ID号必须唯一;
report-host:
The host name or IP address of the slave to be reported to the master during slave registration,This value appears in the output of SHOW SLAVE HOSTS on the master server.
report-port:
The TCP/IP port number for connecting to the slave,to be reported to the master during slave registration.
master-info-repository:
The setting of this variable determines whether the slave logs master status and connection information to a FILE(master.info),or to a TABLE(mysql.slave_master_info)
relay-log-info-repository:
This option causes the server to log its relay log info to a file or a table.
log_slave_updates:
Whether updates received by a slave server from a master server should be logged to the slave’s own binary log ,binary logging must be enabled on the slave for this variable to have any effect;
enforce_gtid_consistency:强制GTID的一致性
1 | 一、简单主从模式配置步骤 |
1 | [mysqld] |
所有的服务器应该时间同步:
ntpdate ntp.api.bz
##这个在已经实现半同步的基础上实验的
1 | 在master.test.com操作: |
Keepalived+nginx:实现高可用
Tengine:这是阿里利用Nginx再次修改发布的产品;
varnish,squid
nginx:cache(disk)
httpd:cache(disk,memory)
nginx支持和memcached服务的缓存加速功能;
HTTP referer:支持反盗链
传统上基于进程或线程模型架构的web服务通过每进程或每线程处理并发连接请求,这势必会在网络和I/O操作时产生阻塞,其另一个必然结果则是对内存或CPU的利用率低下,生成一个新的进程/线程需要事先备好其运行时环境,这保罗为其分配堆内存和栈内存,以及为其创建新的执行上下文等,这些操作都需要占用CPU,而且过多的进程/线程还会带来线程抖动或频繁的上下文切换,系统性能也会由此进一步下降;
在设计的最初阶段,nginx的主要着眼点就是其高性能以及对物理计算资源的高密度利用,因此其采用了不同的架构模型。受启发于多种操作系统设计中基于“事件”的高级处理机制,nginx采用了模块化、事件驱动、异步、单线程及非阻塞的架构,并大量采用了多路复用及事件通知机制。在ngnix中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环(run-loop)机制进行处理,而每个worker可以并行处理数千个的并发连接及请求;
如果负载以CPU密集型应用为主,如SSL或压缩应用,则worker数目应与CPU数相同,如果负载以IO密集型为主,如响应大量内容给客户端,则worker数应该为CPU个数的1.5倍或2倍;
Ngnix会按需同时运行多个进程:一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等,所有进程均是仅含有一个线程,并通过“共享内存”的机制实现进程间通信。主进程以root用户身份运行,而worker、cache loader和cache manager均应以非特权用户运行;
主进程主要完成如下工作:
worker进程主要完成的任务包括:
cache loader进程主要完成的任务包括:
cache manager进程的主要任务:
1、缓存的失效及过期检验
Nginx的配置有着几个不同的上下文:main、http、server、upstream和location(还有实现右键服务反向代理的mail)。配置语法的格式和定义方式遵循所谓的C风格,因此支持嵌套,还有着逻辑清晰并易于创建、阅读和维护等优势;
Nginx的代码是由一个核心和一系列的模块组成,核心主要用于提供web server的基本功能,以及web和mail反向代理的功能,还用于启用网络协议,创建必要的运行时环境以及确保不同的模块之间平滑的进行交互。不过,大多数协议相关的功能和某应用特有的功能都是由nginx的模块实现的,这些功能模块大致可分为事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream和负载均衡几个类别,这些共同组成了nginx的http功能,时间模块主要用于提供OS独立的(不同的操作系统的时间机制有所不同)时间通知机制如kqueue或epoll等。协议模块则负责实现nginx通过http、tls/ssl、smtp、pop3以及imap与对应的客户端建立会话。
在nginx内部,进程间的通信是通过模块的pipeline或chain实现的:换句话说,每一个功能或操作都由一个模块实现。例如:压缩、通过FastCGI或uwsgi协议与upstream服务器通信,以及与memcached建立会话等;
sendfile:在内核直接完成文件封装发送给请求;
1 | #yum groupinstall "Development Tools" "Server Platform Libraries" |
1 | ./configure --prefix=/usr/local/php\ |
还有安装xcache;;;;
安装xcache3.2.0,如果使用php-5.6.7会出现两者无法结合的现象,可以使用php-5.6.11版本,编译安装xcache后,一切不需要动,直接service php-fpm restart即可,
然后phpinfo测试下即可;;;
nginx -t
service nginx testconfig 这两个可以检查配置文件是否正确;
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true