码迷,mamicode.com
首页 > 系统相关 > 详细

Linux 学习

时间:2016-01-09 18:47:24      阅读:1626      评论:0      收藏:0      [点我收藏+]

标签:学习linux

序列

随机数

stat

cp /etc/skel/. /test/ -rf

cp -Rvp

vim

0 $ gg G gg=G

命令行快捷键

Ctrl + u 删除当前到行首

Ctrl + k 删除当前到行尾

Ctrl + a 跳转行首

Ctrl + e 跳转行尾

Ctrl + s  解救-->Ctrl + q

v V

Ctrl + shift + c 复制

Ctrl + shift + v 粘贴

ntpdate pool.ntp.org

rdate IP



wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo

wget http://mirrors.yun-idc.com/epel/6/x86_64/epel-release-6-8.noarch.rpm

wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm


yum -y groupinstall "Additional Development" "Development tools" "Desktop Platform Development" "Server Platform Development"

yum -y install vim-common vim-enhanced

vim /etc/sysconfig/selinux

chkconfig --list|awk ‘{print $1}‘


for i in `chkconfig --list|awk ‘{print $1}‘`;do chkconfig $i off;done

for i in sshd network rsyslog libvirtd;do chkconfig $i on;done


vim /etc/sysconfig/network-scripts/ifcfg-eth0 

vim /etc/ssh/sshd_config

UseDNS no

GSSAPIAuthentication no


yum -y install sysstat


sar

解决:

Cannot open /var/log/sa/sa30: No such file or directory

sar -o 1 2

sar -n DEV


yum -y install strace

yum -y install lsof


gdb

ldd 

lsof

ps

pstack

strace

ipcs

top

free

vmstat

iostat

sar

readelf

objdump

nm

size

wget

scp


mount -o remount,rw /


Linux 释放内存

echo 3 > /proc/sys/vm/drop_caches 


开机-BIOS-mbr-grub-内核-init-inittab-sysinit-fstab-rc.local-登录


find命令

crontab

分 时 日 月 周


nfs 服务建立步骤


复制隐藏文件

cp -Rvp /aaa/. /bbb


for i in `chkconfig --list|awk ‘{print $1}‘`;do chkconfig $i off;done

for i in sshd network rsyslog;do chkconfig $i on;done


快速启动:(删除)

rhgb quiet


yum -y install xinetd

chkconfig xinetd on


简单时间服务器:37 端口

time-dgram

time-stream

disable         = no

------------------------------------------------------------------------------------------------------------------

托管ssh到xinetd前:

[root@localhost ~]# netstat -ntulp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   

tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1238/sshd           

tcp        0      0 :::37                       :::*                        LISTEN      1355/xinetd         

tcp        0      0 :::873                      :::*                        LISTEN      1355/xinetd         

tcp        0      0 :::22                       :::*                        LISTEN      1238/sshd           

udp        0      0 0.0.0.0:68                  0.0.0.0:*                               1158/dhclient       

udp        0      0 :::37                       :::*                                    1355/xinetd   


[root@localhost ~]# which ssh

/usr/bin/ssh

[root@localhost ~]# which sshd

/usr/sbin/sshd

[root@localhost ~]# cat /etc/xinetd.d/rsync 

# default: off

# description: The rsync server is a good addition to an ftp server, as it \

#       allows crc checksumming etc.

service rsync

{

        disable = no

        flags           = IPv6

        socket_type     = stream

        wait            = no

        user            = root

        server          = /usr/bin/rsync

        server_args     = --daemon

        log_on_failure  += USERID

}

对比和rsync差别

[root@localhost ~]# cat /etc/xinetd.d/ssh 

# default: off

# description: The rsync server is a good addition to an ftp server, as it \

#       allows crc checksumming etc.

service ssh

{

        disable = no

        socket_type     = stream

        flags           = IPv6

        protocol        = tcp

        wait            = no

        user            = root

        server          = /usr/sbin/sshd

        server_args     = -i

        log_on_failure  += USERID

}


[root@localhost ~]# netstat -ntulp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   

tcp        0      0 :::37                       :::*                        LISTEN      1234/xinetd         

tcp        0      0 :::873                      :::*                        LISTEN      1234/xinetd         

tcp        0      0 :::22                       :::*                        LISTEN      1234/xinetd         

udp        0      0 0.0.0.0:68                  0.0.0.0:*                               1160/dhclient       

udp        0      0 :::37                       :::*                                  



log_type            = FILE /var/log/servicelog

port = 2222 需要先修改里面的端口号:/etc/services 对应端口号


[root@localhost ~]# cat /etc/xinetd.d/ssh 

# default: off

# description: The rsync server is a good addition to an ftp server, as it \

#       allows crc checksumming etc.

service ssh

{

        disable = yes

        socket_type     = stream

        flags           = IPv6

        protocol        = tcp

        wait            = no

        user            = root

        server          = /usr/sbin/sshd

        server_args     = -i

        log_on_failure  += USERID

        log_type        = FILE /var/log/ssh_xinetd.log

}


-------------------------------------------------------------------------------------------------------------------------

事务:作为单个逻辑工作单元执行的一系列操作

ACID:

原子性:事务不可再分

一致性:前后状态一直

隔离性:未提交不可见

持久性:一提交永久有效

隔离级别:

未提交读

已提交读

可重复读

串行化


主索引(主键索引):primary key

要求依赖的数据关键字不能重复同时不能为null。

唯一索引(约束):unique index

要求依赖的数据关键字不能重复

普通索引:index

任何数据都可以充当索引的关键字。

全文索引:fulltext index

获取关键字的方式不是使用整个字段的值,而是在数据中提取关键字来完成。


Checking if your kit is complete...

Looks good

Warning: prerequisite DBD::mysql 3 not found.

Warning: prerequisite DBI 1.46 not found.

Writing Makefile for percona-toolkit



yum provides "*/DBI"

yum -y install perl-Class-DBI-mysql



Cobar、tddl、Amoeba、以及目前很火的Mycat


strace, netstat, perf, trace, dstat, iostat, top, sar, dig等。

-------------------------------------------------------------------------------------------------------------------------

日志

例如ssh:

SyslogFacility AUTHPRIV

#LogLevel INFO


日志设备 日志级别

vim /etc/rsyslog.conf 

# The authpriv file has restricted access.

authpriv.*                                              /var/log/secure


综上所述:ssh 日志 /var/log/secure

------------------------------------------------------------------------------------------------------------------------------


date +%F_%H_%M_%S

修改ssh日志存放:

Starting sshd: /etc/ssh/sshd_config line 37: unsupported log facility ‘FILE‘

                                                           [FAILED]

  改为local0-local7

Unspecified GSS failure:已解决GSSAPIAuthentication no

1.sshd 是独立服务

vim /etc/ssh/sshd_config

SyslogFacility local0


vim /etc/rsyslog.conf 

local0.*                                                /var/log/ssh.log


分别重启上述服务:service sshd restart service rsyslog restart


2.sshd 托管到xinetd

log_type        = FILE /var/log/ssh_xinetd.log

重启service xinetd restart


man xinetd.conf

                        SYSLOG  syslog_facility [syslog_level]

                               The log output is sent  to  syslog  at  the

                               specified facility. Possible facility names

                               include:  daemon,  auth,  authpriv,   user,

                               mail,  lpr, news, uucp, ftp local0-7.  Pos-

                               sible level names  include:  emerg,  alert,

                               crit,  err,  warning,  notice, info, debug.

                               If a level is  not  present,  the  messages

                               will be recorded at the info level.


                        FILE  file [soft_limit [hard_limit]]

                               The  log  output  is appended to file which

                               will be created if it does not  exist.  Two

                               limits  on  the size of the log file can be

                               optionally specified.  The first limit is a

                               soft  one;  xinetd  will  log a message the

                               first  time  this  limit  is  exceeded  (if

                               xinetd  logs to syslog, the message will be

                               sent at the  alert  priority  level).   The

                               second  limit  is a hard limit; xinetd will

                               stop logging for the affected  service  (if

                               the  log  file  is  a common log file, then

                               more than one service may be affected)  and

                               will  log  a  message about this (if xinetd

                               logs to syslog, the message will be sent at

                               the alert priority level).  If a hard limit

                               is not specified, it defaults to  the  soft

                               limit  increased  by  1% but the extra size

                               must be within the parameters LOG_EXTRA_MIN

                               and  LOG_EXTRA_MAX  which default to 5K and

                               20K  respectively  (these   constants   are

                               defined in xconfig.h).


log_type        = SYSLOG local0 info

然后

vim /etc/rsyslog.conf 

local0.*                                                /var/log/ssh.log


-------------------------------------------------------------------------------------------------------------

时区时间:

/etc/sysconfig/clock 和 hwclock 相关


时区存放目录:/usr/share/zoneinfo/

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  或者做软连接


强制覆盖:

[root@localhost ~]# alias 

alias cp=‘cp -i‘

alias l.=‘ls -d .* --color=auto‘

alias ll=‘ls -l --color=auto‘

alias ls=‘ls --color=auto‘

alias mv=‘mv -i‘

alias rm=‘rm -i‘

alias which=‘alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde‘

[root@localhost ~]# \cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 


交互式:

[root@localhost ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 

cp: overwrite `/etc/localtime‘? y


克隆eth0 eth1

[root@localhost ~]# ifconfig -a

eth0      Link encap:Ethernet  HWaddr 00:50:56:36:1E:AC  


vim /etc/udev/rules.d/70-persistent-net.rules 

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:56:36:1E:AC",

 ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

 

vim /etc/sysconfig/network-scripts/ifcfg-eth0 

修改完毕

日志集中化管理:

Starting system logger: -r option only supported in compatibility modes 0 to 2 - ignored


主服务器:(集中化管理端)

vim /etc/rsyslog.conf

$ModLoad imtcp

$InputTCPServerRun 514

$template RemoteLogs,"/var/log/%FROMHOST-IP%/%PROGRAMNAME%.log" *

*.* ?RemoteLogs

& ~


客户端:

vim /etc/rsyslog.conf

*.* @@10.10.10.174:514


关于rsync

pull :拉

push :推


       Access via remote shell:

         Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]

         Push: rsync [OPTION...] SRC... [USER@]HOST:DEST


       Access via rsync daemon:

         Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]

               rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]

         Push: rsync [OPTION...] SRC... [USER@]HOST::DEST

               rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

  

拉:

rsync -avlR rsync://10.10.10.174/test /tmp 不用输密码 test代表模块名

rsync -avlR 10.10.10.174::test /tmp 不用输密码

rsync -avlR 10.10.10.174:/tmp/epel-release-6-8.noarch.rpm /tmp 要输密码 这儿是任意路径



rsync -avlR 176test.log 10.10.10.174:/tmp 要输密码有权限任意目录都能传 感觉和scp差不多

rsync -avlR 176test.log 10.10.10.174::test ERROR: module is read only test代表模块名 解决:read only = no 不用输密码

rsync -avlR 176test.log rsync://10.10.10.174/test ERROR: module is read only test代表模块名 解决:read only = no 不用输密码

注意传上来变成nobody

独立服务

/usr/bin/rsync --daemon --config=/etc/rsyncd.conf 

托管到超级服务



模块相关

*mod*


编译最新内核


无人值守PUSH 多个版本


kernel panic - not syncing: Attempted to kill init!

可能grub.conf 出问题找不到根文件系统 ,网上推荐enforcing=0 kernel 末尾添加

grub fstab inittab 很重要的文件


防火墙iptables :

1.先做允许后做拒绝

2.lo 环回网卡很重要 默认要允许

3.DDOS 类攻击 封禁 IP

SYN Flood防御

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_synack_retries = 2


man iptables

封IP:

iptables -I

解封IP:

iptables -D


service iptables save

iptables-save > 文件


CLOSED:无连接是活动的或正在进行

LISTEN:服务器在等待进入呼叫

SYN_RECV:一个连接请求已经到达,等待确认

SYN_SENT:应用已经开始,打开一个连接

ESTABLISHED:正常数据传输状态

FIN_WAIT1:应用说它已经完成

FIN_WAIT2:另一边已同意释放

ITMED_WAIT:等待所有分组死掉

CLOSING:两边同时尝试关闭

TIME_WAIT:另一边已初始化一个释放

LAST_ACK:等待所有分组死掉


LINUX下DDOS SYN攻击的防范

  防范也主要从两方面入手,一是sysctl的自身的关于syn方面的配置,二是防火墙策略上。

  sysctl -w net.ipv4.tcp_syncookies=1 # tcp syncookie,默认关闭

  sysctl -w net.ipv4.tcp_max_syn_backlog=1280 # syn队列,默认1024,》 1280可能工作不稳定,需要修改内核源码参数

  sysctl -w net.ipv4.tcp_synack_retries=2 # syn-ack握手状态重试次数,默认5,遭受syn-flood攻击时改为1或2

  sysctl -w net.ipv4.tcp_syn_retries=2 # 外向syn握手重试次数,默认4

  以上四处是网上经常提到的几个地方,当然还有未提到的也可以通过下列命令查看。

  [root@web3 nginx]# sysctl -a|grep syn

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 60

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent = 120

  net.ipv4.tcp_max_syn_backlog = 1024

  net.ipv4.tcp_syncookies = 1

  net.ipv4.tcp_synack_retries = 5

  net.ipv4.tcp_syn_retries = 5

  fs.quota.syncs = 25

  如未受到攻击,上面的参数不建议修改。据说有增加主机的不稳定性的风险。

  防火墙策略:

  #缩短SYN- Timeout时间:

  iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT

  iptables -A INPUT -i eth0 -m limit --limit 1/sec --limit-burst 5 -j ACCEPT

  #每秒最多3个syn封包进入:

  iptables -N syn-floodiptables -A INPUT -p tcp --syn -j syn-flood

  iptables -A syn-flood -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j RETURNiptables -A syn-flood -j REJECT


DDoS deflate

wget http://www.inetbase.com/scripts/ddos/install.sh

wget http://www.inetbase.com/scripts/ddos/uninstall.ddos



标准的TCP三次握手过程如下:


1、客户端发送一个包含SYN标志的TCP报文,SYN即同步(Synchronize),同步报文会指明客户端使用的端口以及TCP连接的初始序号;


2、服务器在收到客户端的SYN报文后,将返回一个SYN+ACK(即确认Acknowledgement)的报文,表示客户端的请求被接受,同时TCP初始序号自动加1;


3、客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加1。


内核参数查看:

sysctl -a


iptables 支持7层协议

"/usr/lib/xtables/"; fi;

make[1]: Leaving directory `/usr/src/iptables-1.4.21/extensions‘

Making install in iptables

make[1]: Entering directory `/usr/src/iptables-1.4.21/iptables‘

make[2]: Entering directory `/usr/src/iptables-1.4.21/iptables‘

 /bin/mkdir -p ‘/usr/sbin‘

  /bin/sh ../libtool   --mode=install /usr/bin/install -c xtables-multi ‘/usr/sbin‘

libtool: install: /usr/bin/install -c .libs/xtables-multi /usr/sbin/xtables-multi

make  install-exec-hook

make[3]: Entering directory `/usr/src/iptables-1.4.21/iptables‘

if test -z ""; then /sbin/ldconfig; fi;

/usr/bin/install -c -dm0755 "/usr/bin";

for i in iptables-xml; do ln -s -f "/usr/sbin/xtables-multi" "/usr/bin/$i"; done;

for i in iptables iptables-restore iptables-save; do ln -s -f xtables-multi "/usr/sbin/$i"; done;

for i in ip6tables ip6tables-restore ip6tables-save; do ln -s -f xtables-multi "/usr/sbin/$i"; done;

make[3]: Leaving directory `/usr/src/iptables-1.4.21/iptables‘

 /bin/mkdir -p ‘/usr/share/man/man1‘

 /usr/bin/install -c -m 644 iptables-xml.1 ‘/usr/share/man/man1‘

 /bin/mkdir -p ‘/usr/share/man/man8‘

 /usr/bin/install -c -m 644 iptables.8 iptables-restore.8 iptables-save.8 ip6tables.8 ip6tables-restore.8 ip6tables-save.8 iptables-extensions.8 ‘/usr/share/man/man8‘

 /bin/mkdir -p ‘/usr/lib/pkgconfig‘

 /usr/bin/install -c -m 644 xtables.pc ‘/usr/lib/pkgconfig‘

make[2]: Leaving directory `/usr/src/iptables-1.4.21/iptables‘

make[1]: Leaving directory `/usr/src/iptables-1.4.21/iptables‘

make[1]: Entering directory `/usr/src/iptables-1.4.21‘

make[2]: Entering directory `/usr/src/iptables-1.4.21‘

make[2]: Nothing to be done for `install-exec-am‘.

make[2]: Nothing to be done for `install-data-am‘.

make[2]: Leaving directory `/usr/src/iptables-1.4.21‘

make[1]: Leaving directory `/usr/src/iptables-1.4.21‘



iptables -t nat -I POSTROUTING 1 -s 172.16.0.0/16 -j MASQUERADE

iptables -t filter -I FORWARD 1 -s 172.16.0.0/16 -j ACCEPT

iptables -t filter -I FORWARD 1 -d 172.16.0.0/16 -j ACCEPT

重启下iptables

iptables -t filter -A FORWARD -m layer7 --l7proto qq -j REJECT

iptables -A FORWARD -m time --timestart 08:00 --timestop 12:00 -j REJECT


开启ftp

iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -m state --state NEW -p tcp --dport 21 -j ACCEPT



mv iptables-1.4.21.tar.bz2 l7-protocols-2009-05-28.tar.gz netfilter-layer7-v2.22.tar.gz /usr/src/

tar -xf linux-2.6.28.10.tar.bz2 

ln -sv linux-2.6.28.10 linux

tar -xf netfilter-layer7-v2.22.tar.gz 

cd linux

patch -p1 < ../netfilter-layer7-v2.22/kernel-2.6.25-2.6.28-layer7-2.22.patch 

cp ../kernels/2.6.18-194.el5-x86_64/.config .

清理编译内核 (make clean)

make mrproper

make menuconfig

make

make modules_install

make install


重启新内核编好了

vim /etc/grub.conf


cp /etc/rc.d/init.d/iptables iptables.sysv

cp /etc/sysconfig/iptables-config .

rpm -e iptables iptables-ipv6 iptstate --nodeps

tar -xf iptables-1.4.21.tar.bz2 

cd netfilter-layer7-v2.22

cd iptables-1.4.3forward-for-kernel-2.6.20forward/

cp * /usr/src/iptables-1.4.21/extensions/

./configure --prefix=/usr --with-ksource=/usr/src/linux

make && make install

ls /usr/sbin | grep iptables

ls -l /usr/lib/xtables/

cp iptables.sysv /etc/rc.d/init.d/iptables

cp iptables-config /etc/sysconfig/

chkconfig --add iptables

service iptables start

tar -xf l7-protocols-2009-05-28.tar.gz 

cd l7-protocols-2009-05-28

make install

iptables -A FORWARD -m layer7 --l7proto qq -j DROP


tcpdump -i 网卡 协议(tcp udp icmp) dst|src port 端口号 -n|-vv


mangle 应用于LVS

cat /proc/sys/net/ipv4/conf/eth0/arp_ignore 


man route 查看应用 添加默认静态路由


traceroute


系统内核调优参数:


#sysctl.conf config 2014-03-26 

net.ipv4.ip_forward = 0 

net.ipv4.conf.default.rp_filter = 1 

net.ipv4.conf.default.accept_source_route = 0 

kernel.sysrq = 0 

kernel.core_uses_pid = 1 

net.ipv4.tcp_syncookies = 1 

kernel.msgmnb = 65536 

kernel.msgmax = 65536 

kernel.shmmax = 68719476736 

kernel.shmall = 4294967296 

net.ipv4.tcp_max_tw_buckets = 10000 

net.ipv4.tcp_sack = 1 

net.ipv4.tcp_window_scaling = 1 

net.ipv4.tcp_rmem = 4096        87380   4194304 

net.ipv4.tcp_wmem = 4096        16384   4194304 

net.core.wmem_default = 8388608 

net.core.rmem_default = 8388608 

net.core.rmem_max = 16777216 

net.core.wmem_max = 16777216 

net.core.netdev_max_backlog = 262144 

net.core.somaxconn = 262144 

net.ipv4.tcp_max_orphans = 3276800 

net.ipv4.tcp_max_syn_backlog = 262144 

net.ipv4.tcp_timestamps = 0 

net.ipv4.tcp_synack_retries = 1 

net.ipv4.tcp_syn_retries = 1 

net.ipv4.tcp_tw_recycle = 1 

net.ipv4.tcp_tw_reuse = 1 

net.ipv4.tcp_mem = 94500000 915000000 927000000 

net.ipv4.tcp_fin_timeout = 1 

net.ipv4.tcp_keepalive_time = 15 

net.ipv4.ip_local_port_range = 1024    65535 


处理恶意登录:

1./etc/hosts.deny 

2.iptables




拒绝sshd暴力破解各种不好用:

DenyHosts

fail2ban

考虑写脚本iptables 和 hosts.deny

[root@localhost ~]# cat deny.sh 

#!/bin/bash

for i in $(grep "Failed password" /var/log/secure|egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}"|sort -nr|uniq -c|awk ‘$1>3{print $2}‘)

do

        grep "$i" /etc/hosts.deny

        if [ $? -ne 0 ];then

                echo "sshd:$i">>/etc/hosts.deny

        fi


done


监控流量工具:iftop


MySQL

安装Percona-Server-5.5.46-rel37.6-Linux.x86_64.ssl101.tar.gz

通用二进制版:

groupadd mysql

useradd -r -g mysql mysql

cd /usr/local/

tar -xf Percona-Server-5.5.46-rel37.6-Linux.x86_64.ssl101.tar.gz 

ln -sv Percona-Server-5.5.46-rel37.6-Linux.x86_64.ssl101 mysql

mkdir -pv /data1/logs

mkdir -pv /data1/data

mkdir -pv /data1/tmp

chown -R mysql.mysql /data1

chown -R root.mysql .

./scripts/mysql_install_db --defaults-file=/usr/local/mysql/etc/my.cnf &

/usr/local/mysql/bin/mysqld_safe --defaults-file=/usr/local/mysql/etc/my.cnf &


cp /usr/local/mysql/support-files/mysql.server /etc/rc.d/init.d/mysqld

chkconfig --add mysqld

chkconfig mysqld on

service mysqld start


表读锁:还能读 不能写

表写锁:不能读 不能写

   Account Management

   Administration

   Compound Statements

   Data Definition

   Data Manipulation

   Data Types

   Functions

   Functions and Modifiers for Use with GROUP BY

   Geographic Features

   Help Metadata

   Language Structure

   Plugins

   Procedures

   Storage Engines

   Table Maintenance

   Transactions

   User-Defined Functions

   Utility

   

主从复制:

1.主 二进制日志

2.主 授权 replication slave

3.flush tables with read lock

4.unlock tables


从:建议开启二进制日志

1.stop slave

2.change master to

3.start slave


级联从:log_slave_updates


半同步


MySQL二进制日志statement row mixed


Linux MySQL优化

1.CPU 最大性能模式

2.不要swap vm.swappiness=0

innodb_flush_method=O_DIRECT

numactl –interleave=all 启动mysqld 这就是在关闭numa 特性 推荐在grub.conf 中关闭

或者numa=off

3.磁盘算法deadline noop(ssd) elevator=deadline /etc/grub.conf

4.最好使用xfs 文件系统

5.推荐使用Read committed  binlog格式使用mixed或是Row

6.主从双1 普通双0 sync_binlog innodb_flush_log_at_trx_commit


安装percona-toolkit-2.2.16

Checking if your kit is complete...

Looks good

Warning: prerequisite DBD::mysql 3 not found.

Warning: prerequisite DBI 1.46 not found.

Writing Makefile for percona-toolkit



yum provides "*/DBI"

yum -y install perl-Class-DBI-mysql

perl Makefile.PL install

make

make install


安装mysql-utilities-1.5.6 (python > 2.6)

python setup.py install 


Usage: mysqlserverinfo --server=user:pass@host:port:socket --format=grid

mysqlserverinfo --server=admin:admin@10.10.10.174:3306 --format=vertical


Usage: mysqldbcompare --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1:db2

mysqldbcompare --server1=admin:admin@10.10.10.174:3306 --server2=admin:admin@10.10.10.173:3306 mydb:mydb


mysqldbcopy --source=user:pass@host:port:socket --destination=user:pass@host:port:socket orig_db:new_db

mysqldbcopy --source=admin:admin@10.10.10.174:3306 --destination=admin:admin@10.10.10.173:3306 mydb:mycopy


Usage: mysqldbexport --server=user:pass@host:port:socket db1, db2, db3

Usage: mysqldbimport --server=user:pass@host:port:socket db1.csv db2.sql db3.grid


Usage: mysqldiff --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1.object1:db2.object1 db3:db4


Usage: mysqlauditadmin --server=user:pass@host:port --show-options 

Usage: mysqlauditgrep [options] AUDIT_LOG_FILE 


Usage: mysqlserverclone --server=user:pass@host:port:socket --new-data=/tmp/data2 --new-port=3310 --new-id=12 --root-password=root

Usage: mysqldiskusage --server=user:pass@host:port:socket db1 --all

Usage: mysqlindexcheck --server=user:pass@host:port:socket db1.table1 db2 db3.table2



pt 工具集:

yum install -y perl-Time-HiRes

pt-duplicate-key-checker --host=localhost --user=root --databases=mydb


pt-online-schema-change

pt-online-schema-change --user=root --host=localhost --alter="add column time timestamp" D=mydb,t=mytable --execute               


pt-show-grants

pt-index-usage

pt-pmp

pt-visual-explain

pt-config-diff


pt-config-diff h=10.10.10.174 h=10.10.10.173 --user=admin --password=admin

pt-config-diff /usr/local/mysql/support-files/my-huge.cnf /usr/local/mysql/support-files/my-small.cnf


pt-variable-advisor

pt-variable-advisor --user=root localhost




pt-deadlock-logger 死锁

pt-deadlock-logger h=localhost --iterations 1


pt-mext

pt-mext -- mysqladmin ext -uroot -i10 -c3


pt-heartbeat

pt-heartbeat -D mydb --monitor --user=admin --password=admin -h10.10.10.174 --master-server-id=174  


pt-slave-delay

pt-slave-find 

pt-slave-find --user=admin --password=admin --host=10.10.10.174


pt-table-checksum h=‘10.10.10.174‘,u=‘admin‘,p=‘admin‘,P=3306 --nocheck-replication-filters --replicate=test.checksums --no-check-binlog-format

 pt-table-checksum h=‘10.10.10.174‘,u=‘admin‘,p=‘admin‘,P=3306 -d mysql --ignore-tables=mysql.user --nocheck-replication-filters --replicate=test.checksums --no-check-binlog-format

 pt-table-checksum --no-check-binlog-format --user=admin --password=admin --host=10.10.10.174

 

 

范例 1:同步 3.135 的 test 库的 aaa 表到 192.168.3.92,在执行之前

可以用--execute 参数换成--print 来查看会变更什么东西,后面那个主

机必须是 master,否则会报错推出。

pt-table-sync --execute --user=root --password=zhang@123 h=192.16

8.3.135,D=test,t=aaa h=192.168.3.92

范例 2:将主的 test 数据库同步到 192.168.3.92,使从上具有一样的

数据。

pt-table-sync --execute --sync-to-master --user=root --password=zhan

g@123 h=192.168.3.92 --database test

范例 3:只同步指定的表

pt-table-sync --execute --sync-to-master --user=root --password=zhan

g@123 h=192.168.3.92 D=test,t=aaa

范例 4:根据 pt-table-checksum 的结果进行数据同步

pt-table-sync --execute --replicate test.checksums --user=root --pass

word=zhang@123 h=192.168.3.135

范例 5:根据 pt-table-checksum 使从的数据和主的数据一致

pt-table-sync --execute --replicate test.checksums --user=root --pass

word=zhang@123 --sync-to-master h=192.168.3.92 D=test,t=aaa



pt-diskstats 


pt-archiver


pt-find 


perldoc /usr/local/bin/pt-table-sync


限制登录PAM模块:

find /usr/share/man/ -iname "pam_*"|grep time


关于系统限制打开文件和进程:

*               hard    nproc           65535

*               soft    nproc           65535

*               hard    nofile          65535

*               soft    nofile          65535


限制SSH登录失败几次就锁住多长时间:

[root@localhost ~]# find /usr/share/man/ -iname "pam_*"|grep tal

/usr/share/man/man8/pam_tally2.8.gz


man pam_tally2


auth     required       pam_tally2.so deny=4 even_deny_root unlock_time=1200


pam_mysql 模块:

yum -y install cyrus-sasl

service saslauthd start

[root@localhost ~]# testsaslauthd -h

testsaslauthd: invalid option -- ‘h‘

testsaslauthd: usage: testsaslauthd -u username -p password

              [-r realm] [-s servicename]

              [-f socket path] [-R repeatnum]

 


内核一般性优化:

net.ipv4.ip_forward = 0

net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.default.accept_source_route = 0

kernel.sysrq = 0

kernel.core_uses_pid = 1

net.ipv4.tcp_syncookies = 1

kernel.msgmnb = 65536

kernel.msgmax = 65536

kernel.shmmax = 68719476736

kernel.shmall = 4294967296

net.ipv4.ip_forward = 0

net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.default.accept_source_route = 0

kernel.sysrq = 0

kernel.core_uses_pid = 1

net.ipv4.tcp_syncookies = 1

kernel.msgmnb = 65536

kernel.msgmax = 65536

kernel.shmmax = 68719476736

kernel.shmall = 4294967296

net.ipv4.tcp_max_tw_buckets = 6000

net.ipv4.tcp_sack = 1

net.ipv4.tcp_window_scaling = 1

net.ipv4.tcp_rmem = 4096        87380   4194304

net.ipv4.tcp_wmem = 4096        16384   4194304

net.core.wmem_default = 8388608

net.core.rmem_default = 8388608

net.core.rmem_max = 16777216

net.core.wmem_max = 16777216

net.core.netdev_max_backlog = 262144

net.core.somaxconn = 262144

net.ipv4.tcp_max_orphans = 3276800

net.ipv4.tcp_max_syn_backlog = 262144

net.ipv4.tcp_timestamps = 0

net.ipv4.tcp_synack_retries = 1

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_mem = 94500000 915000000 927000000

net.ipv4.tcp_fin_timeout = 1

net.ipv4.tcp_keepalive_time = 30

net.ipv4.ip_local_port_range = 1024    65000

net.ipv4.route.gc_timeout = 100

net.nf_conntrack_max = 25000000

net.netfilter.nf_conntrack_max = 25000000

net.netfilter.nf_conntrack_tcp_timeout_established = 180

net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120


在/etc/rc.local 中

modprobe bridge

modprobe ip_conntrack


yum -y install nmap

yum -y install tripwire


CPU调优:

uptime

vmstat

 r    :正在运行

 b    :  阻塞

 in   :系统中断

 cs     :上下文切换

 us     :

 sy     :

 id     :空闲CPU

 wa     :CPU等待外设


程序系统调用过程:

strace


mpstat

--help


内存子系统调优:

free 

vmstat


IO子系统调优:

iostat

查看磁盘调度算法

cat /sys/block/sda/queue/scheduler

永久修改elevator=

临时修改echo 


网络子系统:

iptraf 

netperf


防盗链 referer 实现

nginx前端调度:

nginx

|

lnmp squid(缓存)


http { 


upstream phpservs  {

  server 10.1.1.21 weight=5;

}


upstream squids  {

  server 10.1.1.28 weight=5;

}


server {

  listen 80;

  server_name www.upl.com;

  location / {

    proxy_pass  http://phpservs;

  }


  location ~ .*\.(jpg|jpeg|png|css|js|......)$ {

proxy_pass http://squids;

  }


}


}



KVM虚拟化之旅

yum -y install qemu-kvm

yum install libvirt -y

yum install libvirt-python.x86_64 python-virtinst.noarch virt-manager.x86_64 virt-viewer.x86_64 -y


yum -y install qemu-kvm libvirt libvirt-python.x86_64 python-virtinst.noarch virt-manager.x86_64 virt-viewer.x86_64


软raid

LVM

共享存储(iscsi)

iscsi 多路径

集群开撸:

yum install scsi-target-utils -y


Base  X Window System Desktop


yum -y groupinstall "Desktop" "X Window System" "Base"


MFS 分布式文件系统:


yum list|grep heartbeat


配置下网卡桥接:

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-virbr0 

DEVICE=virbr0

ONBOOT=yes

TYPE=Bridge

BOOTPROTO=static

IPADDR=10.10.10.7

NETMASK=255.255.255.0

STP=on

DELAY=0

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 

DEVICE=eth0

HWADDR=00:0C:29:EB:EA:7D  

TYPE=Ethernet

ONBOOT=yes

BRIDGE=virbr0

[root@localhost ~]# brctl show

bridge name     bridge id               STP enabled     interfaces

virbr0          8000.000c29ebea7d       yes             eth0

注意大小写,ON 和on 结果不一样


主机名三部曲:

1.hostname

2./etc/sysconfig/network

3./etc/hosts


实验图:

VIP

|

|

NODE1 NODE2

[root@node1 ~]# yum list|grep heartbeat

heartbeat.x86_64                           3.0.4-2.el6                  epel    

heartbeat-devel.i686                       3.0.4-2.el6                  epel    

heartbeat-devel.x86_64                     3.0.4-2.el6                  epel    

heartbeat-libs.i686                        3.0.4-2.el6                  epel    

heartbeat-libs.x86_64                      3.0.4-2.el6                  epel    




yum -y install heartbeat.x86_64 heartbeat-libs.x86_64

cp /usr/share/doc/heartbeat-3.0.4/{ha.cf,authkeys,haresources} /etc/ha.d/

[root@node1 ~]# egrep -v "^$|^#" /etc/ha.d/ha.cf 

logfile /var/log/ha-log

keepalive 2

deadtime 12

warntime 6

initdead 120

udpport 694

ucast virbr0 10.10.10.9

auto_failback on

node node1.test.com

node node2.test.com

ping 10.10.10.1

respawn hacluster /usr/lib64/heartbeat/ipfail

apiauth ipfail gid=haclient uid=hacluster

[root@node1 ~]# egrep -v "^$|^#" /etc/ha.d/authkeys 

auth 2

2 sha1 a1!abc

[root@node1 ~]# egrep -v "^$|^#" /etc/ha.d/haresources 

node1.test.com  IPaddr::10.10.10.128/24/virbr0 httpd


chmod 600 /etc/ha.d/authkeys

rsync  -alvR /etc/ha.d/ 10.10.10.9:/

修改另外节点的心跳网络


完成情况服务(httpd)应该heartbeat 来启动

/usr/share/heartbeat/hb_standby 让出资源

/usr/share/heartbeat/hb_takeover   抢占资源


service heartbeat start 启动heartbeat

ip addr 查看是否有VIP 

这个实验只支持心跳故障不支持资源故障(距离现实情况不符)


新实验:

httpd服务挂载共享存储

连接同一个MySQL数据库

1.双心跳

2.双ping

3.启用看门狗watchdog

4.自动挂载共享存储设备

vim /etc/ha.d/haresources 

node1.upl.com IPaddr::192.168.110.128/24/eth0 Filesystem::/dev/iscsi/webdata/part1::/var/www/html  httpd

5.vim /usr/lib/ocf/resource.d/heartbeat/Filesystem

 nfs4|nfs|cifs|smbfs) umount_force="-f" ;;

 修改:nfs|cifs|smbfs|ext3|ext4) umount_force="-f -l" ;;

 

yum 安装LAMP

yum -y install httpd.x86_64 httpd-devel.x86_64

yum -y install mysql.x86_64 mysql-devel.x86_64 mysql-server.x86_64

yum -y install php.x86_64 php-adodb.noarch php-bcmath.x86_64 php-cli.x86_64 php-common.x86_64 php-devel.x86_64 php-gd.x86_64 php-idn.x86_64 \

php-imap.x86_64 php-jpgraph.noarch php-ldap.x86_64 php-mbstring.x86_64 php-mcrypt.x86_64 php-mssql.x86_64 php-odbc.x86_64 php-pclzip.noarch \

php-pdo.x86_64 php-snmp.x86_64 php-soap.x86_64 php-xcache.x86_64 php-xml.x86_64 php-xmlrpc.x86_64 rrdtool-php.x86_64 sphinx-php.x86_64 


yum 安装LNMP

yum -y install nginx.x86_64

php-fpm.x86_64

yum -y install mysql.x86_64 mysql-devel.x86_64 mysql-server.x86_64

yum -y install php.x86_64 php-adodb.noarch php-bcmath.x86_64 php-cli.x86_64 php-common.x86_64 php-devel.x86_64 php-gd.x86_64 php-idn.x86_64 \

php-imap.x86_64 php-jpgraph.noarch php-ldap.x86_64 php-mbstring.x86_64 php-mcrypt.x86_64 php-mssql.x86_64 php-odbc.x86_64 php-pclzip.noarch \

php-pdo.x86_64 php-snmp.x86_64 php-soap.x86_64 php-xcache.x86_64 php-xml.x86_64 php-xmlrpc.x86_64 rrdtool-php.x86_64 sphinx-php.x86_64 php-fpm.x86_64

此环境比较令人蛋疼


Linux 模拟软raid


CREATE MODE

       Usage: mdadm --create md-device --chunk=X --level=Y

                   --raid-devices=Z devices

创建:   

[root@localhost ~]# mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/sdb /dev/sdc

mdadm: Defaulting to version 1.2 metadata

mdadm: array /dev/md0 started.

检查:

[root@localhost ~]# cat /proc/mdstat 

Personalities : [raid0] 

md0 : active raid0 sdc[1] sdb[0]

      41910272 blocks super 1.2 512k chunks

      

unused devices: <none>

格式化:

mkfs.ext4 /dev/md0

挂载:

mount /dev/md0 /mnt


mdadm -E /dev/sdb


停止模拟:

mdadm --stop /dev/md0

mdadm --zero-superblock /dev/sd{b,c}


模拟软raid1

mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdb /dev/sdc

快速查看同步过程:

watch "cat /proc/mdstat"


查看raid结果:

cat /proc/mdstat


mkfs.xfs -f /dev/md1

mount /dev/md1 /mnt


[root@localhost ~]# mdadm /dev/md1 --fail /dev/sdc

mdadm: set /dev/sdc faulty in /dev/md1

[root@localhost ~]# mdadm /dev/md1 --remove /dev/sdc

mdadm: hot removed /dev/sdc from /dev/md1

[root@localhost ~]# mdadm --zero-superblock /dev/sdc

[root@localhost ~]# mdadm -E /dev/sdc

mdadm: No md superblock detected on /dev/sdc.

[root@localhost ~]# mdadm /dev/md1 --add /dev/sdc

mdadm: added /dev/sdc

[root@localhost ~]# watch "cat /proc/mdstat"


[root@localhost ~]# mdadm -As /dev/md1

mdadm: /dev/md1 not identified in config file.


自动组装失败:

[root@localhost ~]# mdadm -As /dev/md1

mdadm: /dev/md1 not identified in config file.


查看其中一块设备:

mdadm -E /dev/sdc

找到:

Array UUID : 257bbde0:545f67fe:9bdf7492:d24bc2c3


重新组装:

[root@localhost ~]# mdadm -A /dev/md1 --uuid="257bbde0:545f67fe:9bdf7492:d24bc2c3"

[root@localhost ~]# cat /proc/mdstat

Personalities : [raid0] [raid1] 

md1 : active raid1 sdc[2] sdb[0]

      20955136 blocks super 1.2 [2/2] [UU]

      

unused devices: <none>

写入配置文件开机自动组装:

[root@localhost ~]# echo "DEVICE /dev/sdb /dev/sdc">/etc/mdadm.conf

[root@localhost ~]# mdadm --detail --scan >>/etc/mdadm.conf

[root@localhost ~]# cat /etc/mdadm.conf



不打算再用这些设备:

[root@localhost ~]# mdadm --stop /dev/md1

mdadm: stopped /dev/md1

[root@localhost ~]# mdadm --zero-superblock /dev/sd{b,c}

[root@localhost ~]# cat /proc/mdstat

Personalities : [raid1] 

unused devices: <none>

[root@localhost ~]# mdadm -E /dev/sdb

mdadm: No md superblock detected on /dev/sdb.

[root@localhost ~]# >/etc/mdadm.conf 


raid5:

[root@localhost ~]# mdadm --create /dev/md5 --level=5 --raid-devices=3 /dev/sd{b,c,d}

mdadm: Defaulting to version 1.2 metadata

mdadm: array /dev/md5 started.

[root@localhost ~]# watch "cat /proc/mdstat"


[root@localhost ~]# mdadm /dev/md5 --fail /dev/sdb

mdadm: set /dev/sdb faulty in /dev/md5

[root@localhost ~]# mdadm /dev/md5 --remove /dev/sdb

mdadm: hot removed /dev/sdb from /dev/md5

[root@localhost ~]# mdadm /dev/md5 --add /dev/sdb

mdadm: added /dev/sdb


再次模拟

[root@localhost ~]# mdadm /dev/md5 --fail /dev/sdd

mdadm: set /dev/sdd faulty in /dev/md5

[root@localhost ~]# mdadm /dev/md5 --remove /dev/sdd

mdadm: hot removed /dev/sdd from /dev/md5

[root@localhost ~]# mdadm --zero-superblock /dev/sdd

[root@localhost ~]# mdadm -E /dev/sdd

mdadm: No md superblock detected on /dev/sdd.

[root@localhost ~]# mdadm /dev/md5 --add /dev/sdd

mdadm: added /dev/sdd

[root@localhost ~]# watch "cat /proc/mdstat"


[root@localhost ~]# mdadm --stop /dev/md5

mdadm: stopped /dev/md5

[root@localhost ~]# mdadm --zero-superblock /dev/sd{b,c,d}

[root@localhost ~]# cat /proc/mdstat



LVM 逻辑卷:

[root@localhost ~]# pvcreate /dev/sd{b,c,d}

  Physical volume "/dev/sdb" successfully created

  Physical volume "/dev/sdc" successfully created

  Physical volume "/dev/sdd" successfully created


[root@localhost ~]# vgcreate vg0 /dev/sd{b,c}

  Volume group "vg0" successfully created

  

[root@localhost ~]# lvcreate  -n lv0 -L 2G vg0

  Logical volume "lv0" created.


[root@localhost ~]# ls -l /dev/vg0/lv0 

lrwxrwxrwx 1 root root 7 Dec 31 15:19 /dev/vg0/lv0 -> ../dm-0


[root@localhost ~]# mkfs.xfs -f /dev/vg0/lv0 

[root@localhost ~]# mount /dev/vg0/lv0 /tmp

关于在线扩容报错:(理论是ext3 ext4 应该不会有错的是XFS文件系统)

[root@localhost ~]# lvextend /dev/vg0/lv0 -L +1G

[root@localhost ~]# resize2fs /dev/vg0/lv0    

resize2fs 1.41.12 (17-May-2010)

resize2fs: Bad magic number in super-block while trying to open /dev/vg0/lv0

Couldn‘t find valid filesystem superblock.


XFS

[root@localhost ~]# lvextend /dev/vg0/lv0 -L +1G

  Size of logical volume vg0/lv0 changed from 3.00 GiB (768 extents) to 4.00 GiB (1024 extents).

  Logical volume lv0 successfully resized

[root@localhost ~]# xfs_growfs /dev/vg0/lv0 

lvcreate -s -l 20%ORIGIN --name snap vg00/lvol1


lvcreate --type raid5 -l 100%FREE -n my_lv vg00

查看分区文件系统类型:

[root@localhost ~]# df -T

Filesystem          Type  1K-blocks    Used Available Use% Mounted on

/dev/sda3           ext4   19276064 2931780  15358428  17% /

tmpfs               tmpfs    502384       0    502384   0% /dev/shm

/dev/sda1           ext4     194241   29439    154562  16% /boot

/dev/mapper/vg0-lv0 xfs     4184064   33056   4151008   1% /tmp

/dev/mapper/vg0-lv2 ext4    7295136   16584   6901312   1% /mnt


[root@localhost ~]# lvextend /dev/vg0/lv2 -l +10%FREE

  Size of logical volume vg0/lv2 changed from 7.20 GiB (1842 extents) to 10.08 GiB (2580 extents).

  Logical volume lv2 successfully resized

[root@localhost ~]# resize2fs /dev/vg0/lv2

resize2fs 1.41.12 (17-May-2010)

Filesystem at /dev/vg0/lv2 is mounted on /mnt; on-line resizing required

old desc_blocks = 1, new_desc_blocks = 1

Performing an on-line resize of /dev/vg0/lv2 to 2641920 (4k) blocks.

The filesystem on /dev/vg0/lv2 is now 2641920 blocks long.



[root@localhost ~]# umount /mnt

[root@localhost ~]# fsck -f /dev/vg0/lv2

fsck from util-linux-ng 2.17.2

e2fsck 1.41.12 (17-May-2010)

Pass 1: Checking inodes, blocks, and sizes

Pass 2: Checking directory structure

Pass 3: Checking directory connectivity

Pass 4: Checking reference counts

Pass 5: Checking group summary information

/dev/mapper/vg0-lv2: 11/659664 files (0.0% non-contiguous), 78323/2641920 blocks

[root@localhost ~]# resize2fs /dev/vg0/lv2 5G

resize2fs 1.41.12 (17-May-2010)

Resizing the filesystem on /dev/vg0/lv2 to 1310720 (4k) blocks.

The filesystem on /dev/vg0/lv2 is now 1310720 blocks long.


[root@localhost ~]# lvreduce /dev/vg0/lv2 -L 5G

  WARNING: Reducing active logical volume to 5.00 GiB

  THIS MAY DESTROY YOUR DATA (filesystem etc.)

Do you really want to reduce lv2? [y/n]: y

  Size of logical volume vg0/lv2 changed from 10.08 GiB (2580 extents) to 5.00 GiB (1280 extents).

  Logical volume lv2 successfully resized

[root@localhost ~]# df -h

Filesystem           Size  Used Avail Use% Mounted on

/dev/sda3             19G  2.8G   15G  17% /

tmpfs                491M     0  491M   0% /dev/shm

/dev/sda1            190M   29M  151M  16% /boot

/dev/mapper/vg0-lv0  4.0G   33M  4.0G   1% /tmp

[root@localhost ~]# mount /dev/vg0/lv2 /mnt

[root@localhost ~]# df -T

Filesystem          Type  1K-blocks    Used Available Use% Mounted on

/dev/sda3           ext4   19276064 2931792  15358416  17% /

tmpfs               tmpfs    502384       0    502384   0% /dev/shm

/dev/sda1           ext4     194241   29439    154562  16% /boot

/dev/mapper/vg0-lv0 xfs     4184064   33056   4151008   1% /tmp

/dev/mapper/vg0-lv2 ext4    5029984   14744   4754540   1% /mnt

[root@localhost ~]# df -T -h

Filesystem          Type   Size  Used Avail Use% Mounted on

/dev/sda3           ext4    19G  2.8G   15G  17% /

tmpfs               tmpfs  491M     0  491M   0% /dev/shm

/dev/sda1           ext4   190M   29M  151M  16% /boot

/dev/mapper/vg0-lv0 xfs    4.0G   33M  4.0G   1% /tmp

/dev/mapper/vg0-lv2 ext4   4.8G   15M  4.6G   1% /mnt

[root@localhost ~]# umount /mnt

[root@localhost ~]# fsck -f /dev/vg0/lv2

fsck from util-linux-ng 2.17.2

e2fsck 1.41.12 (17-May-2010)

Pass 1: Checking inodes, blocks, and sizes

Pass 2: Checking directory structure

Pass 3: Checking directory connectivity

Pass 4: Checking reference counts

Pass 5: Checking group summary information

/dev/mapper/vg0-lv2: 11/325760 files (0.0% non-contiguous), 56910/1310720 blocks

[root@localhost ~]# mount /dev/vg0/lv2 /mnt

[root@localhost ~]# df -T -h

Filesystem          Type   Size  Used Avail Use% Mounted on

/dev/sda3           ext4    19G  2.8G   15G  17% /

tmpfs               tmpfs  491M     0  491M   0% /dev/shm

/dev/sda1           ext4   190M   29M  151M  16% /boot

/dev/mapper/vg0-lv0 xfs    4.0G   33M  4.0G   1% /tmp

/dev/mapper/vg0-lv2 ext4   4.8G   15M  4.6G   1% /mnt

[root@localhost ~]# 


LVM 逻辑卷减少容量

1.umount

2.fsck -f

3.resize2fs

4.lvreduce

5.fsck -f

6.mount


卷组扩容

[root@localhost ~]# vgextend vg0 /dev/sdd

  Volume group "vg0" successfully extended

[root@localhost ~]# vgs

  VG   #PV #LV #SN Attr   VSize  VFree 

  vg0    3   2   0 wz--n- 59.99g 50.99g

  

卷组减少容:

[root@localhost ~]# pvs

  PV         VG   Fmt  Attr PSize  PFree 

  /dev/sdb   vg0  lvm2 a--  20.00g 11.00g

  /dev/sdc   vg0  lvm2 a--  20.00g 20.00g

  /dev/sdd   vg0  lvm2 a--  20.00g 20.00g

[root@localhost ~]# vgreduce vg0 /dev/sdc

  Removed "/dev/sdc" from volume group "vg0"

[root@localhost ~]# pvs

  PV         VG   Fmt  Attr PSize  PFree 

  /dev/sdb   vg0  lvm2 a--  20.00g 11.00g

  /dev/sdc        lvm2 ---  20.00g 20.00g

  /dev/sdd   vg0  lvm2 a--  20.00g 20.00g

[root@localhost ~]# vgs

  VG   #PV #LV #SN Attr   VSize  VFree 

  vg0    2   2   0 wz--n- 39.99g 30.99g

  

删除逻辑卷

[root@localhost ~]# umount /tmp

[root@localhost ~]# umount /mnt

[root@localhost ~]# lvremove /dev/vg0/lv0

Do you really want to remove active logical volume lv0? [y/n]: y

  Logical volume "lv0" successfully removed

[root@localhost ~]# lvremove /dev/vg0/lv2

Do you really want to remove active logical volume lv2? [y/n]: y

  Logical volume "lv2" successfully removed

[root@localhost ~]# lvs

[root@localhost ~]# pvs

  PV         VG   Fmt  Attr PSize  PFree 

  /dev/sdb   vg0  lvm2 a--  20.00g 20.00g

  /dev/sdc        lvm2 ---  20.00g 20.00g

  /dev/sdd   vg0  lvm2 a--  20.00g 20.00g

[root@localhost ~]# vgremove vg0

  Volume group "vg0" successfully removed

[root@localhost ~]# pvs

  PV         VG   Fmt  Attr PSize  PFree 

  /dev/sdb        lvm2 ---  20.00g 20.00g

  /dev/sdc        lvm2 ---  20.00g 20.00g

  /dev/sdd        lvm2 ---  20.00g 20.00g

[root@localhost ~]# vgs

[root@localhost ~]# pvremove /dev/sd{b,c,d}

  Labels on physical volume "/dev/sdb" successfully wiped

  Labels on physical volume "/dev/sdc" successfully wiped

  Labels on physical volume "/dev/sdd" successfully wiped

[root@localhost ~]# pvs

[root@localhost ~]# 


iscsi共享存储


iscsi 提供端:

yum install scsi-target-utils -y

导出:

vim /etc/tgt/targets.conf 

启动服务:

service tgtd start

查看:

tgtadm --lld iscsi --mode target --op show


iscsi 使用端

yum install iscsi-initiator-utils -y

chkconfig iscsid on

chkconfig iscsi on

发现:

iscsiadm -m discovery -t st -p 10.10.10.7

iscsiadm -m node -p 10.10.10.7 -T iqn.2008-09.com.example:target1 -l

登录所有:

iscsiadm -m node -p 10.10.10.7 -l

查看会话:

iscsiadm -m session

取消登录:

iscsiadm -m node -u

忘记所有:

iscsiadm -m node -o delete


这儿有个很重要的东西是UDEV 规则{

根据发现和登录的不同同一个target在不同的机器上面表现出不同的名字

同一个target 在A机器上是/dev/sdb 在B机器上是/dev/sdc 

ls -l /dev/iscsi/target1

UDEV 规则解决了这个问题

}


--lld <driver> --op show --mode target

           Show all the targets.

           Example:


           tgtadm --lld iscsi --mode logicalunit --op update \

                  --tid <TID> --lun <LUN> \

                  --params vendor_id=TGTD,product_id=VirtualHD,product_rev=0103

  


设备多路径:

yum install device-mapper-multipath -y


MFS 分布式文件系统


引入看门狗和启用共享存储(iscsi):

1.先准备iscsi服务器端

yum install scsi-target-utils -y

vim /etc/tgt/targets.conf 

service tgtd start

tgtadm --lld iscsi --mode target --op show

2.准备iscsi客户端

yum install iscsi-initiator-utils -y

chkconfig iscsid on

chkconfig iscsi on

iscsiadm -m discovery -t st -p 10.10.10.7

iscsiadm -m node -p 10.10.10.7 -l

3.分区格式化iscsi

4.另外一台机器重读分区表(已经准备好UDEV规则)

5.配置heartbeat高可用

yum -y install heartbeat.x86_64 heartbeat-libs.x86_64

cp /usr/share/doc/heartbeat-3.0.4/{ha.cf,authkeys,haresources} /etc/ha.d/

[root@node1 ~]# egrep -v "^$|^#" /etc/ha.d/ha.cf

logfile /var/log/ha-log

keepalive 2

deadtime 12

warntime 6

initdead 120

udpport 694

ucast virbr0 10.10.10.9

auto_failback on

watchdog /dev/watchdog

node node1.test.com

node node2.test.com

ping 10.10.10.1

respawn hacluster /usr/lib64/heartbeat/ipfail

apiauth ipfail gid=haclient uid=hacluster

[root@node1 ~]# egrep -v "^$|^#" /etc/ha.d/authkeys 

auth 2

2 sha1 a1!abc

[root@node1 ~]# egrep -v "^$|^#" /etc/ha.d/haresources 

node1.test.com  IPaddr::10.10.10.128/24/virbr0 Filesystem::/dev/iscsi/target2/part1::/var/www/html httpd

{

对比下用heartbeat 实现MySQL高可用 少了个文件系统类型

node1.upl.com IPaddr::192.168.110.128/24/eth0 Filesystem::/dev/iscsi/mysqldata/part::/data::ext4  mysqld

}

[root@node1 ~]# 


6.同步配置到另外的机器:

rsync  -alvR /etc/ha.d/ 10.10.10.9:/

8.vim /usr/lib/ocf/resource.d/heartbeat/Filesystem 

nfs|cifs|smbfs|ext3|ext4) umount_force="-f -l" ;; 添加爱ext3,ext4和-l参数

9.rsync -avlR /usr/lib/ocf/resource.d/heartbeat/Filesystem 10.10.10.8:/


10.验证高可用(很大的问题是没有httpd 服务故障时高可用的转移)


用同样的步骤实现下MySQL的heartbeat 高可用(略)


RHCS集群套件能实现资源故障转移



RHEL5


wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo

epel

repoforge



LVS NAT


[root@localhost ~]# ipvsadm --help

ipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1)

Usage:

  ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine]

  ipvsadm -D -t|u|f service-address

  ipvsadm -C

  ipvsadm -R

  ipvsadm -S [-n]

  ipvsadm -a|e -t|u|f service-address -r server-address [options]

  ipvsadm -d -t|u|f service-address -r server-address

  ipvsadm -L|l [options]

  ipvsadm -Z [-t|u|f service-address]

  ipvsadm --set tcp tcpfin udp

  ipvsadm --start-daemon state [--mcast-interface interface] [--syncid sid]

  ipvsadm --stop-daemon state

  ipvsadm -h


Commands:

Either long or short options are allowed.

  --add-service     -A        add virtual service with options

  --edit-service    -E        edit virtual service with options

  --delete-service  -D        delete virtual service

  --clear           -C        clear the whole table

  --restore         -R        restore rules from stdin

  --save            -S        save rules to stdout

  --add-server      -a        add real server with options

  --edit-server     -e        edit real server with options

  --delete-server   -d        delete real server

  --list            -L|-l     list the table

  --zero            -Z        zero counters in a service or all services

  --set tcp tcpfin udp        set connection timeout values

  --start-daemon              start connection sync daemon

  --stop-daemon               stop connection sync daemon

  --help            -h        display this help message


Options:

  --tcp-service  -t service-address   service-address is host[:port]

  --udp-service  -u service-address   service-address is host[:port]

  --fwmark-service  -f fwmark         fwmark is an integer greater than zero

  --ipv6         -6                   fwmark entry uses IPv6

  --scheduler    -s scheduler         one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,

                                      the default scheduler is wlc.

  --pe            engine              alternate persistence engine may be sip,

                                      not set by default.

  --persistent   -p [timeout]         persistent service

  --netmask      -M netmask           persistent granularity mask

  --real-server  -r server-address    server-address is host (and port)

  --gatewaying   -g                   gatewaying (direct routing) (default)

  --ipip         -i                   ipip encapsulation (tunneling)

  --masquerading -m                   masquerading (NAT)

  --weight       -w weight            capacity of real server

  --u-threshold  -x uthreshold        upper threshold of connections

  --l-threshold  -y lthreshold        lower threshold of connections

  --mcast-interface interface         multicast interface for connection sync

  --syncid sid                        syncid for connection sync (default=255)

  --connection   -c                   output of current IPVS connections

  --timeout                           output of timeout (tcp tcpfin udp)

  --daemon                            output of daemon information

  --stats                             output of statistics information

  --rate                              output of rate information

  --exact                             expand numbers (display exact values)

  --thresholds                        output of thresholds information

  --persistent-conn                   output of persistent connection info

  --nosort                            disable sorting output of service/server entries

  --sort                              does nothing, for backwards compatibility

  --ops          -o                   one-packet scheduling

  --numeric      -n                   numeric output of addresses and ports

[root@localhost ~]# 


rr|wrr|

lc|wlc| 最少连接

lblc|lblcr| 基于局部性最少连接

dh|sh|

sed| 最短期望延迟

nq 不排队


LVS NAT

调度节点:

net.ipv4.ip_forward = 1

yum -y install ipvsadm.x86_64

ipvsadm -A -t 10.10.10.20:80 -s rr

ipvsadm -a -t 10.10.10.20:80 -r 192.168.16.130 -m

ipvsadm -a -t 10.10.10.20:80 -r 192.168.16.131 -m


后端节点:

修改默认网关即可


DR 需要的内核参数:

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2


yum -y install arptables_jf.x86_64

Usage: /etc/rc.d/init.d/arptables_jf {start|stop|restart|condrestart|status|panic|save}

arptables -A IN -d 10.10.10.100 -j DROP


DR 

1.路由器把数据包给DR?(VIP MAC地址){DR 和 后端服务器都绑定有VIP,需要后端服务器不能响应}

a.路由器静态绑定MAC

b.后端修改内核参数net.ipv4.conf.all.arp_ignore = 1

c.arptables_jf 后端服务器拒绝VIP ARP广播 arptables -A IN -d 10.10.10.100(VIP) -j DROP

2.DR把数据包给后端服务器?(MAC地址){VIP 地址广播后端服务器的lo:1 也有VIP后端服务器自己回答自己}

a.静态绑定

b.DR 将VIP 绑定在eth0:1 上

3.后端服务器把数据包给网关(路由器)?(MAC地址){使用自身IP广播而不是VIP广播{收到包物理网卡地址和包中的IP地址不匹配丢弃}}

a.后端绑定网关MAC

b.修改内核参数 net.ipv4.conf.all.arp_announce = 2


所有服务全部持久连接:

ipvsadm -A -t 10.10.10.100:0 -s rr -p 600

ipvsadm -a -t 10.10.10.100:0 -r 10.10.10.21 -g -w 2

ipvsadm -a -t 10.10.10.100:0 -r 10.10.10.21 -g -w 1


服务归并:

iptables -t mangle -A PREROUTING -d 10.10.10.100 -p tcp --dport 80 -j MARK --set-mark 8

iptables -t mangle -A PREROUTING -d 10.10.10.100 -p tcp --dport 22 -j MARK --set-mark 8

ipvsadm -A -f 8 -s rr

ipvsadm -a -f 8 -r 10.10.10.21 -g -w 2

ipvsadm -a -f 8 -r 10.10.10.22 -g -w 2




realserver

ifconfig lo:0 10.10.10.100/32

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2

net.ipv4.conf.lo.arp_ignore = 1

net.ipv4.conf.lo.arp_announce = 2

route add -host 10.10.10.100 dev lo:0


dr

ifconfig eth0:0 10.10.10.100/32

route add -host 10.10.10.100 dev eth0:0


elinks -dump

curl -I


haproxy

tar -xf pcre-8.01.tar.gz 

tar -xf haproxy-1.4.15.tar.gz

cd pcre-8.01

./configure

make && make install

echo "/usr/local/lib">>/etc/ld.so.conf

echo "/usr/local/lib64">>/etc/ld.so.conf

ldconfig 

cd /usr/src/haproxy-1.4.15

make PREFIX=/usr/local/haproxy TARGET=linux26 ARCH=x86_64 USE_STATIC_PCRE=1

make install PREFIX=/usr/local/haproxy

useradd -s /sbin/nologin haproxy

cp /usr/local/haproxy/share/man/man1/haproxy.1 /usr/share/man/man1/

vim /usr/local/haproxy/haproxy.cfg

[root@localhost ~]# egrep -v "^$" /usr/local/haproxy/haproxy.cfg 

global  

        maxconn 10240   #每个进程能够打开的文件描述符的数量,等同ulimit -n 

        chroot /usr/local/haproxy  

        user haproxy  

        group haproxy

        daemon  # 后台守护进程形式运行

        quiet  # 启动的时候不输出调试信息

        pidfile /usr/local/haproxy/haproxy.pid  

defaults  

        log     global  # 全局日志,所有实例都公用

        mode    http    # http 7层调度, tcp 4层调度 ,health 仅应答 OK (连接成功马上关闭)

        option  httplog # 记录所有http相关的日志:请求,会话状态和时间等

        option  dontlognull # 不记录空日志,一般前端lvs等的健康检测,如通过判断端口是否打开来判断haproxy是否健康  

        log 127.0.0.1 local3 #记录到本地的local3日志设备 

        retries 3  # 尝试连接多少次失败之后判定后端节点失效

        option redispatch  # 连接失败后,重新把请求调度到其他后端节点

        maxconn 10000      # 单个调度服务的最高并发连接数

        timeout client  50000  # 如果客户端50秒内无数据交互,认定其超时,释放会话信息

        timeout server  50000  # 如果后端节点50秒内无数据交互,认定其超时,释放会话信息

        timeout connect 60000  # 如果请求放入队列中等待了1分钟,就判断连接超时,请求失败。

listen weblb :80  # 定义代理,可以覆盖 frontend和backend的配置

        mode http  # 该代理为7层调度

        balance roundrobin  # 动态轮询的调度算法

        option httpclose  # 关闭http 1.1的keepalive的支持,单个请求,单个响应后马上关闭连接,不会重用连接

        option forwardfor # 添加 转发头,让后端web服务器能够记录详细的客户端信息的日志 

        option httpchk HEAD /ok.html HTTP/1.0  # 通过HEAD的方法,使用http/1.0版本检测后端节点是否健康,默认只是简单的进行IP和端口判断节点健康状态

        # 定义后端节点 

        server node1 10.10.10.21:80 weight 1 minconn 2 maxconn 6 check inter 2000 rise 2 fall 2

        server node2 10.10.10.22:80 weight 1 minconn 2 maxconn 6 check inter 2000 rise 2 fall 2

                        # check inter 2000 每两秒进行一次健康检测

                        # fall 2 两次无法通过检测则判断节点失效

                        # rise 2 节点重新上线必须两次通过检测

                        # minconn 2 maxconn 6 在低负载的情况下,每个节点可以最低支持2个并发连接

                        # 当并发连接数defaults中定义的maxconn 10000的时候,每个节点最大并发连接数6.

                        # 当超过12个并发后的那些连接都被阻塞进入等待队列,以防止高并发把后端

                        # 节点弄垮。

                        # 假设某代理最高并发3000,单台节点处理6个并发请求需要10ms,那么最大延迟:

                        # 3000 / 2 servers / 6 conns * 10 ms = 2.5 s


listen stats :8888  

       mode http  

       transparent  

       stats uri /haproxy

       stats realm Haproxy \ statistic  

       stats auth admin:admin 

[root@localhost ~]# 


使用自带的haproxy启动脚本

tar -xf pcre-8.01.tar.gz

tar -xf haproxy-1.4.15.tar.gz 

cd pcre-8.01

./configure && make && make install

echo "/usr/local/lib">>/etc/ld.so.conf

echo "/usr/local/lib64">>/etc/ld.so.conf

ldconfig 

cd haproxy-1.4.15

make TARGET=linux26 ARCH=x86_64 USE_STATIC_PCRE=1

make install


useradd -s /sbin/nologin haproxy

mkdir /etc/haproxy

cp /usr/src/haproxy-1.4.15/examples/haproxy.cfg /etc/haproxy/

cp /usr/src/haproxy-1.4.15/examples/haproxy.init /etc/rc.d/init.d/haproxy

chmod a+x /etc/rc.d/init.d/haproxy

ln -s /usr/local/sbin/haproxy /usr/sbin/

mkdir /usr/share/haproxy

vim /etc/haproxy/haproxy.cfg 

chkconfig --add haproxy

service haproxy start


iostat -d -x -k 1 5

du -sh /

du -cks *|sort -nr |head -n 10

vmstat 1 4

lsmod | grep ip_vs

netstat -an | awk ‘/^tcp/ {++S[$NF]} END {for (a in S) print a, S[a]}‘

ps axu | grep -v grep | grep nginx

pgrep nginx

killall


路由

vim /etc/sysconifg/network-scripts/route-eth0

127.16.6.0/24 via 172.16.2.25


最少服务优化:

irqbalance

sshd

network

crond

syslog


ps aux|grep tty|grep -v grep

抗SYN Flood内核参数:

net.ipv4.tcp_syncookies = 1

sysctl -a

同步时间

ntpdate ntp.api.bz

ntpdate pool.ntp.org


最大文件打开数

* soft nofile 65535

* hard nofile 65535


ulimit -SHn 65535

ulimit -n

ulimit -a


配置网卡

PEERDNS=yes →允许从DHCP处获得的DNS覆盖本地的DNS

USERCTL=no~ →不允许普通用户修改网卡


优化fstab

/dev/sda5 /data/pics ext3 noatime,nodiratime 0 0


内核优化参考:

net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_keepalive_time = 1200

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.ip_local_port_range = 1024 65000

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_max_tw_buckets = 5000



NTOP和Iptraf


重挂根

mount -o remount,rw /


查看nginx 能打开的文件数

for pid in `ps aux |grep nginx | grep -v grep| awk ‘{print$2}‘`

do

cat /proc/${pid}/limits |grep ‘Max open files‘

done


后台运行

nohup

screen


vim 配置文件;

set nobackup

set noswapfile

set nohlsearch

set nonumber

set cindent

set autoindent

set shiftwidth=2

set tabstop=2

set softtabstop=2

set expandtab

set ruler

set mouse=v

syntax on


sed -n ‘1,5p‘ /etc/passwd


cat /etc/manpath.config |grep ‘MAN‘|sed ‘s/#.*$//g‘|sed ‘/^$/d‘


删除5天前的文件

find /logs -type f -mtime +5 -exec rm {} \ ;


xargs 命令

高可用软件有Heartbeat、Keepalived,成熟的Linux集群架构有

LVS+Keepalived、Nginx|HAProxy+Keepalived及DRBD+Heartbeat



LVS -p

nginx ip_hash

haproxy balance source


安装haproxy

wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.20.tar.gz

tar zxvf haproxy-1.3.20.tar.gz

cd haproxy-1.3.20

make TARGET=linux26 PREFIX=/usr/local/haproxy

make install PREFIX=/usr/local/haproxy

cd /usr/local/haproxy

mkdir conf

/usr/local/haproxy/conf/haproxy.cfg

global

    log 127.0.0.1 local0

    maxconn 4096

    chroot /usr/local/haproxy

    uid 99

    gid 99

    daemon

    nbproc 1

    pidfile /usr/local/haproxy/logs/haproxy.pid

    debug

defaults

    log  127.0.0.1   local3

    mode  http

    option httplog

    option httpclose

    option dontlognull

    option forwardfor

    option redispatch

    retries 2

    maxconn 2000

    balance source

    stats uri  /haproxy-stats

    contimeout   5000

    clitimeout   50000

    srvtimeout   50000

listen web_proxy 192.168.1.103:80

    #option httpchk HEAD /index.php HTTP/1.0

    server web1 192.168.1.106:80 cookie app1inst1 check inter 2000 rise 2 fall 5

    server web2 192.168.1.107:80 cookie app1inst2 check inter 2000 rise 2 fall 5


/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg


HAProxy的配置中包含5个组件,如下所示(当然这些组件不是必选的,可以根据需要

选择配置)。

·global:参数是进程级的,通常和操作系统(OS)相关。这些参数一般只设置一次,

如果配置无误,就不需要再次配置了。

·defaults:配置默认参数,这些参数可以配置到frontend、backend、listen组件中。

·frontend:接收请求的前端虚拟节点,Frontend可以根据规则直接指定具体使用后端的

backend(可动态选择)。

·backend:后端服务集群的配置,是真实的服务器,一个backend对应一台或多台实体

服务器。

·listen:frontend和backend的组合体。



nginx 配置:

user www www;

worker_processes 8;

error_log /usr/local/webserver/nginx/logs/nginx_error.log crit;

pid    /usr/local/webserver/nginx/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.

worker_rlimit_nofile 65535;

events

{

  use epoll;

  worker_connections 65535;

}

http

{

  include   mime.types;

  default_type application/octet-stream;

  charset utf-8;

  server_names_hash_bucket_size 128;

  client_header_buffer_size 32k;

  large_client_header_buffers 4 32k;

  client_max_body_size 300m;

  sendfile on;

  tcp_nopush  on;

  keepalive_timeout 60;

  tcp_nodelay on;

  server_tokens off;

  client_body_buffer_size 512k;

  proxy_connect_timeout  5;

  proxy_read_timeout   60;

  proxy_send_timeout   5;

  proxy_buffer_size    16k;

  proxy_buffers      4 64k;

  proxy_busy_buffers_size 128k;

  proxy_temp_file_write_size 128k;

  gzip on;

  gzip_min_length 1k;

  gzip_buffers  4 16k;

  gzip_http_version 1.1;

  gzip_comp_level 2;

  gzip_types   text/plain application/x-javascript text/css application/xml;

  gzip_vary on;

  proxy_temp_path /data/proxy_temp_dir;

  proxy_cache_path /data/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;

  upstream backend_server {

  ip_hash;

  server 222.35.135.158:80 max_fails=2 fail_timeout=30s;

  server 222.35.135.159:80 max_fails=2 fail_timeout=30s;

}

upstream www.offer99.com {

server 222.35.135.151;

}

server

{

  listen   80;

  server_name www.offer99.com app.offer99.com;

location /bugfree/

{

  proxy_pass http://www.offer99.com;

}

location /

{

  proxy_next_upstream http_502 http_504 error timeout invalid_header;

  proxy_cache cache_one;

  proxy_cache_valid 200 304 24h;

  proxy_cache_key $host$uri$is_args$args;

  proxy_set_header Host $host;

  proxy_set_header X-Forwarded-For $remote_addr;

  proxy_pass http://backend_server;

  expires   1d;

}

location ~ /purge(/.*)

{

  allow 127.0.0.1;

  deny all;

  proxy_cache_purge  cache_one $host$1$is_args$args;

}

location ~ .*\.(php|jsp|cgi)?$

{

  proxy_set_header Host $host;

  proxy_set_header X-Forwarded-For $remote_addr;

  proxy_pass http://backend_server;

}

location /nginx_status/

{

  stub_status on;

  access_log off;

}

log_format weblogs ‘$remote_addr - $remote_user [$time_local] "$request" ‘

    ‘$status $body_bytes_sent "$http_referer" ‘

    ‘"$http_user_agent" $http_x_forwarded_for‘;

access_log /data/logs/weblogs.log weblogs;

}

}




NFS高可用可以采用DRBD+Heartbeat



nginx + keepalived

先安装Nginx负载均衡器,Nginx负载的设置就用一般的模板来配置了。

1)添加运行Nginx的用户和组www及Nginx存放日志的位置,并安装gcc等基础库,以

免发生libtool报错现象,命令如下:

yum -y install gcc gcc+ gcc-c++ openssl openssl-devel

groupadd www

useradd -g www www

mdkir -p /data/logs/

chown -R www:www /data/logs/

2)下载并安装Nginx 0.8.15(当时最新最稳定的版本,现在我推荐用Nginx 0.8.56)。

另外建议工作中养成好习惯,所下载的软件包均放到/usr/local/src中,如下所示:

cd /usr/local/src

wget http://blog.s135.com/soft/linux/nginx_php/pcre/pcre-7.9.tar.gz

tar zxvf pcre-7.9.tar.gz

cd pcre-7.9/

./configure

make && make install

cd ../

wget http://sysoev.ru/nginx/nginx-0.8.15.tar.gz

tar zxvf nginx-0.8.15.tar.gz

cd nginx-0.8.15/

./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

make && make install

cd ../


user www www;

worker_processes 8;

pid /usr/local/nginx/logs/nginx.pid;

worker_rlimit_nofile 51200;

events

{

  use epoll;

  worker_connections 51200;

}

http{

include   mime.types;

default_type application/octet-stream;

server_names_hash_bucket_size 128;

client_header_buffer_size 32k;

large_client_header_buffers 4 32k;

client_max_body_size 8m;

  sendfile on;

  tcp_nopush  on;

  keepalive_timeout 60;

  tcp_nodelay on;

  fastcgi_connect_timeout 300;

  fastcgi_send_timeout 300;

  fastcgi_read_timeout 300;

  fastcgi_buffer_size 64k;

  fastcgi_buffers 4 64k;

  fastcgi_busy_buffers_size 128k;

  fastcgi_temp_file_write_size 128k;

  gzip on;

  gzip_min_length 1k;

  gzip_buffers  4 16k;

  gzip_http_version 1.0;

  gzip_comp_level 2;

  gzip_types   text/plain application/x-javascript text/css application/xml;

  gzip_vary on;

upstream backend

{

ip_hash;

server 192.168.1.106:80;

server 192.168.1.107:80;

}

server {

listen 80;

server_name www.1paituan.com;

location / {

root /var/www/html ;

index index.php index.htm index.html;

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for;

proxy_pass http://backend;

}

location /nginx {

access_log off;

stub_status on;

#auth_basic_user_file /usr/local/nginx/htpasswd;

}

log_format access ‘remote_addr - remote_user [time_local] "request" ‘

‘$status body_bytes_sent "$http_referer" ‘

‘"$http_user_agent"$http_x_forwarded_for‘;

access_log /data/logs/access.log access;

}

}



安装Keepalived,让其分别作Web及Nginx的HA

1)安装Keepalived,并将其做成服务模式,方便以后调试。Keepalived的安装方法如

下:

wget http://www.keepalived.org/software/keepalived-1.1.15.tar.gz

tar zxvf keepalived-1.1.15.tar.gz

cd keepalived-1.1.15

./configure --prefix=/usr/local/keepalived

make

make install

2)安装成功后做成服务模式,方便启动和关闭,方法如下:

cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/

3)分别设置主Nginx和备用Nginx上的Keepalived配置文件。我们先配置主Nginx上的

keepalived.conf文件,如下所示:

#mkdir /etc/keepalived

#cd /etc/keepalived/

我们可以用vim编辑/etc/keepalived/keepalived.conf,内容如下所示:

! Configuration File for keepalived

global_defs {

 notification_email {

 yuhongchun027@163.com

   }

 notification_email_from keepalived@chtopnet.com

 smtp_server 127.0.0.1

 smtp_connect_timeout 30

 router_id LVS_DEVEL

}

vrrp_instance VI_1 {

  state MASTER

  interface eth0

  virtual_router_id 51

  mcast_src_ip 192.168.1.103

  # 此处是主Nginx的IP地址,此机的priority为100

  priority 100

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass chtopnet

  }

  virtual_ipaddress {

    192.168.1.108        

  }

}


下面设置备用Nginx上的keepalived.conf配置文件,注意与主Nginx上的keepalived.conf

区分,代码如下:

! Configuration File for keepalived

global_defs {

 notification_email {

 yuhongchun027@163.com

   }

 notification_email_from keepalived@chtopnet.com

 smtp_server 127.0.0.1

 smtp_connect_timeout 30

 router_id LVS_DEVEL

}

vrrp_instance VI_1 {

  state BACKUP

  interface eth0

  virtual_router_id 51

  mcast_src_ip 192.168.1.104

  priority 99

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass chtopnet

  }

  virtual_ipaddress {

    192.168.1.108

  }

}



在两台负载均衡器上分别启动Keepalived程序,命令如下:

service keepalived start


tcpdump vrrp



用Nginx_pid.sh来监控Nginx进程,实现真正意义上的负载均衡高可用

针对Nginx+Keepalived方案,我编写了Nginx监控脚本nginx_pid.sh。此脚本的思路其

实也很简单,即将其放置在后台一直监控Nginx进程,如果进程消失,则尝试重启Nginx;如

果失败,则立即停掉本机的Keepalived服务,让另一台负载均衡器接手。此脚本直接从生产

环境下载,内容如下所示:

#!/bin/bash

while :

do

nginxpid=‘ps -C nginx --no-header | wc -l‘

if [ $nginxpid -eq 0 ];then

 /usr/local/nginx/sbin/nginx

 sleep 5

 nginxpid=‘ps -C nginx --no-header | wc -l‘

 echo $nginxpid

  if [ $nginxpid -eq 0 ];then

/etc/init.d/keepalived stop

 fi

fi

sleep 5

done

然后将其置于后台运行sh/root/nginx_pid.sh &,做到这步时大家要注意一下,这种写法

是有问题的,我们退出root账户后,此进程便会消失,正确写法为

nohup/bin/bash/root/nginx_pid.sh &



1)如何让Nginx负载均衡器也支持HTTPS?

要让Nginx支持HTTPS,方法其实很简单,在负载均衡器上开启SSL功能,监听443端口

(防火墙上也要做好映射),将证书放在Nginx负载均衡器上(不是后面的Web服务器),

就可轻松解决此问题。详见以下nginx.conf配置文件,代码如下:

server

{

listen 443;

server_name www.cn7788.com;

ssl on;

ssl_certificate /usr/local/nginx/keys/www.cn7788.com.crt;

ssl_certificate_key /usr/local/nginx/keys/www.cn7788.com.key;

ssl_protocols SSLv3 TLSv1;

ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP;

}


如何让后端的Apache服务器获取客户端的真实IP?

其实我们可以通过修改Nginx proxy的参数,令后端应用获取Nginx发来

的请求报文,并获取外网的IP,在Nginx的配置文件中记得加上如下内容:

proxy_set_header    Host $host;

proxy_set_header    X-Real-IP $remote_addr;

proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;



正确区分Nginx的分发请求。

我在设计某个小项目时,原本是基于Nginx的1+3架构,开发人员突然要增加一台机器

(Windows Server 2003系统),专门存放图片及PDF等,项目要求能在Nginx后的3台Web

机器上显示图片,并且可以下载PDF。当时我有点懵,因为程序用的是Zend Framwork,所

以一直在用正则表达式作为跳转。后来才想明白其中的“玄机”,IE程序先在Nginx负载均衡

器上提申请,所以nginx.conf是在做分发而非正则跳转,此时最前端的Nginx,既是负载匀衡

器又是反向代理。明白这个就好办了。另外要注意location/StockInfo与

location~^/StockInfo的差异性,Nginx默认是正则优先的。顺便也说一下,proxy_pass支持

直接写IP的方式。Nginx的部分代码如下:

upstream mysrv {

    ip_hash;

    server 192.168.110.62;

    server 192.168.110.63;

}

upstream myjpg {

    server 192.168.110.3:88;

}

server

{

    listen 80;

    server_name web.tfzq.com;

    proxy_redirect off;

    location ~ ^/StockInfo{

    proxy_pass http://myjpg;

}


项目案例三:用LVS+Keepalived构建高可用JSP集群

由于服务器均采用的是最小化安装,所以先安装一些基础的编译库,命令如下:

yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype 

下载完成后,修改jdk-6u18-linux-x64.bin为可执行,并运行。

cd /usr/local/src

chmod +x jdk-6u18-linux-x64.bin

./jdk-6u18-.linux-x64.bin

mv jdk1.6.0_18 /usr/local/jdk



接着配置系统的Java运行环境,我是通过修改/etc/profile文件来实现的,修改内容如下

所示:

JAVA_HOME="/usr/local/jdk"

CLASS_PATH="$JAVA_HOME/lib:$JAVA_HOME/jre/lib"

PATH=".:$PATH:$JAVA_HOME/bin"

CATALINA_HOME="/usr/local/tomcat"

export JAVA_HOME CATALINA_HOME

保存并退出后,执行以下命令让环境立即生效:

source /etc/profile



然后下载并安装apache-tomcat 7.0.12,如下所示:

cd /usr/local/src/

wget http://mirror.bjtu.edu.cn/apache/tomcat/tomcat-7/v7.0.12/bin/apache-tomcat-7.0.12.tar.gz

tar zxvf apache-tomcat-7.0.12.tar.gz

mv apache-tomcat-7.0.12 /usr/local/tomcat/

vim /usr/local/tomcat/conf/server.xml

修改Tomcat的根路径位置,我的网站地址为/data/htdocs/www/shop,这个虚拟主机

需要在/usr/local/tomcat/conf/server.xml里指定。改动后的内容如下所示:

<Host name="www.1paituan.com" appBase="/data/htdocs/www/shop"

      unpackWARs="true" autoDeploy="true">

    <Context path="" docBase="·" />

如果我们要继续增加虚拟主机,按照如上格式继续添加内容即可。Host name后面接虚

拟主机名称,docBase后面接虚拟主机对应的路径位置。

安装完成后,启动Tomcat,默认监听了8080端口。启动命令如下:

/usr/local/tomcat/bin/startup.sh


LVS+Keepalived的配置详细过程略过,具体可参考前面的内容。以下为备LVS机器

上的配置文件,备LVS只需更改MASTER为BACKUP,优先级低于100即可。

我们用Vim来编辑/etc/keepalived/keepalived.conf文件,如下所示:

! Configuration File for keepalived

global_defs {

 notification_email {

    yuhongchun027@163.com

 }

 notification_email_from sns-lvs@gmail.com

 smtp_server 127.0.0.1

 router_id LVS_DEVEL

}

vrrp_instance VI_1 {

  state MASTER

  interface eth0

  virtual_router_id 51

  priority 100

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 1111

  }

  virtual_ipaddress {

    203.93.236.148

  }

}

virtual_server 203.93.236.148 80 {

  delay_loop 6

  lb_algo wrr

  lb_kind DR

  persistence_timeout 60

  protocol TCP

  real_server 203.93.236.146 80 {

    weight 3

    TCP_CHECK {

    connect_timeout 10

    nb_get_retry 3

    delay_before_retry 3

    connect_port 80

    }

  }

  real_server 203.93.236.147 80 {

    weight 3

    TCP_CHECK {

    connect_timeout 10

    nb_get_retry 3

    delay_before_retry 3

    connect_port 80

    }

  }

}


项目案例四:Nginx主主负载均衡架构

Nginx和Keepalived的安装比较简单,这里就不重复了,大家可以参考4.4.2节的内容,

这里附上两台Nginx负载均衡器的nginx.conf配置文件,内容如下所示:

  user www www;

  worker_processes 8;

  pid /usr/local/nginx/logs/nginx.pid;

  worker_rlimit_nofile 51200;

  events

  {

  use epoll;

  worker_connections 51200;

  }

  http{

  include  mime.types;

  default_type application/octet-stream;

  server_names_hash_bucket_size 128;

  client_header_buffer_size 32k;

  large_client_header_buffers 4 32k;

  client_max_body_size 8m;

  sendfile on;

  tcp_nopush  on;

  keepalive_timeout 60;

  tcp_nodelay on;

  fastcgi_connect_timeout 300;

  fastcgi_send_timeout 300;

  fastcgi_read_timeout 300;

  fastcgi_buffer_size 64k;

  fastcgi_buffers 4 64k;

  fastcgi_busy_buffers_size 128k;

  fastcgi_temp_file_write_size 128k;

  gzip on;

  gzip_min_length 1k;

  gzip_buffers  4 16k;

  gzip_http_version 1.0;

  gzip_comp_level 2;

  gzip_types  text/plain application/x-javascript text/css application/xml;

  gzip_vary on;

  upstream backend

  {

  server 192.168.1.17:80;

  server 192.168.1.18:80;

  }

  server {

  listen 80;

  server_name www.1paituan.com;

  location / {

  root /var/www/html ;

  index index.php index.htm index.html;

  proxy_redirect off;

  proxy_set_header Host $host;

  proxy_set_header X-Real-IP $remote_addr;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  proxy_pass http://backend;

  }

  location /nginx {

  access_log off;

  auth_basic "NginxStatus";

  #auth_basic_user_file /usr/local/nginx/htpasswd;

  }

  log_format access ‘$remote_addr - $remote_user [$time_local] "$request" ‘

  ‘$status $body_bytes_sent "$http_referer" ‘

  ‘"$http_user_agent" $http_x_forwarded_for‘;

  access_log /data/logs/access.log access;

  }

}


这里简单解释配置Keepalived文件的原理,其实就是通过Keepalived生成两个实例,两

台Nginx互为备份。即第一台是第二台机器的备机,而第二台机器也是第一台的备机,而生

成的两个VIP地址分别对应网站http://www.1paituan.com,这样大家在公网上可以通过DNS

轮询来访问网站。如果任何一台Nginx机器发生硬件损坏,Keepalived会自动将它的VIP地址

切换到另一台机器,不影响客户端的访问,这个跟LVS+Keepalived多实例的原理是一样

的,相信大家也能明白。

主Nginx机器之一的keepalived.conf配置文件如下:

! Configuration File for keepalived

global_defs {

  notification_email {

  yuhongchun027@163.com

    }

  notification_email_from keepalived@chtopnet.com

  smtp_server 127.0.0.1

  smtp_connect_timeout 30

  router_id LVS_DEVEL

}

vrrp_instance VI_1 {

  state MASTER

  interface eth0

  virtual_router_id 51

  priority 100

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 1paituan.com

  }

  virtual_ipaddress {

    192.168.1.8

  }

}

vrrp_instance VI_2 {

  state BACKUP

  interface eth0

  virtual_router_id 52

  priority 99

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 1paituan.com

  }

  virtual_ipaddress {

    192.168.1.9

  }

}

另一台Nginx的keepalived.conf配置文件如下:

! Configuration File for keepalived

global_defs {

  notification_email {

  yuhongchun027@163.com

    }

  notification_email_from keepalived@chtopnet.com

  smtp_server 127.0.0.1

  smtp_connect_timeout 30

  router_id LVS_DEVEL

}

vrrp_instance VI_1 {

  state BACKUP

  interface eth0

  virtual_router_id 51

  priority 99

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 1paituan

  }

  virtual_ipaddress {

    192.168.1.8

  }

}

vrrp_instance VI_2 {

  state MASTER

  interface eth0

  virtual_router_id 52

  priority 100

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 1paituan

  }

  virtual_ipaddress {

    192.168.1.9

  }

}

注意 这两台Nginx应该是互为主备的关系,所以在写keepalived.conf配置文件时,一

定要注意MASTER和BACKUP的关系,并且注意各自的优先级,不是太熟悉的朋友建议直接

用以上的脚本来操作。如果此步遇到了问题,两台Nginx负载均衡机器建议都用TCPdump进

行抓包、分析、排障,正常情况下它们都应该各自向对方发送VRRP包。


大家都知道Keepalived是实现不了程序级别的高可用的,所以我们要通过Shell脚本来实

现Nginx的高可用,脚本/root/nginxpid.sh内容如下:

#!/bin/bash

while :

do

 nginxpid=‘ps -C nginx --no-header | wc -l‘

 if [ $nginxpid -eq 0 ];then

 /usr/local/nginx/sbin/nginx

 sleep 5

  if [ $nginxpid -eq 0 ];then

  /etc/init.d/keepalived stop

  fi

 fi

 sleep 5

done

我们分别在两台主Nginx上执行,命令如下所示:

nohup sh /root/nginxpid.sh &

此脚本是直接从生产服务器上下载的,大家不要怀疑它会引起死循环和有效性的问题。

这是一个无限循环的脚本,放在主Nginx机器上(因为目前主要是由它提供服务),每隔5秒

执行一次,用ps -C命令来收集Nginx的PID值到底是否为0,如果为0(即nginx进程死掉

了),尝试启动nginx进程;如果继续为0,即nginx启动失败,则关闭本机的keepalived进

程,VIP地址会由备机接管。当然,整个网站就会由备机的nginx来提供服务,这样保证

nginx进程的高可用(虽然在实际生产环境中我们基本没发现nginx进程死掉的情况,多此一

步操作做到有备无患)。


项目案例五:生产环境下的高可用NFS文件服务器

某日例行检查服务器时,发现DRBD+Heartbeat+NFS文件服务器已经稳定运行了661天

(两台CentOS 5.3 i386,DELL 2950机器,用于作图片及代码存放文件服务器),相当稳定

和高效。鉴于DRBD已被MySQL官方推荐为实现MySQL高可用的一种非常重要的方式,建议

大家掌握这个知识点。

1.做好整个环境的准备工作

主机名+同步时间

2.DRBD的安装和配置过程

DRBD的官方网站:http://www.drbd.org/。

源码下载地址:http://oss.linbit.com/drbd。

1)安装依赖库,以下是使用CentOS 5.3 i386系统进行安装与测试的,命令如下:

yum install gcc gcc-c++ make glibc flex kernel-devel

2)在primary和secondary上都要使用相同的安装方法,如下所示:

cd /usr/local/src

wget http://oss.linbit.com/drbd/8.0/drbd-8.0.6.tar.gz

tar zxvf drbd-8.0.6.tar.gz

cd drbd-8.0.6

make DKDIR=/usr/src/kernel

make install

这里要说明一下,如果出现“Could not determine uts_release”错误,我们要检查是否

安装了新的内核,还要记得重启机器,否则也不能安装成功,命令如下所示:

make install

3)DRBD程序安装完成后主要生成命令drbdsetup、drbdadmin,配置文

件/etc/drbd.conf、启动文件/etc/init.d/drbd及模块文件drbd.ko(在编译好的安装包目录下

的drbd下可以找到)。我们可以用如下命令查看:

ll /lib/modules/2.6.18-238.9.1.el5/kernel/drivers/block/

4)DRBD采用的是模块控制的方式,所以先要加载drbd.ko模块,命令如下:

modprobe drbd

查看DRBD模块是否已经加载到内核中,有的话表示已成功加载到内核中,命令如下:

lsmod | grep drbd

drbd         226608 0

5)确认两台要镜像的机器是否正常,它们之间的网络是否通畅,需要加载的硬盘是否

处于umount状态。

6)在两台机器上都创建硬件设备DRBD,命令如下:

mknod /dev/drbd0 b 147 0

7)两台机器将/dev/sdb1互为镜像(两台机器的配置相同),这里只列出centos1的操

作步骤,centos2机器的操作步骤类似,具体步骤如下所示:

#yum -y install portmap

#yum -y install nfs

#mkdir /drbd

创建共享目录,用Vim可以编辑/etc/exports文件,内容如下:

/drbd 192.168.1.0/255.255.255.0(rw,no_root_squash,no_all_squash,sync)

只允许192.168.1.0网段的机器共享,这个也是基于安全考虑的。

然后配置NFS涉及的portmap和NFS服务,如下所示:

service portmap start

chkconfig portmap on

chkconfig nfs off

NFS不需要启动,也不需要设置成开机自动运行,这些都将由后面的Heartbeat来完

成。

8)配置DRBD。DRBD运行时,会读取一个配置文件/etc/drbd.conf,这个文件里描述了

DRBD设备与硬盘分区的映射关系,以及DRBD的一些配置参数。编辑/etc/drbd.conf文件,

内容如下:

resource r0 {

protocol C;

startup { wfc-timeout 0; degr-wfc-timeout 120; }

disk { on-io-error detach; }

net {

  timeout 60;

  connect-int 10;

  ping-int 10;

  max-buffers 2048;

  max-epoch-size 2048;

  }

syncer { rate 30M; }

on centos1.cn7788.com {

 device  /dev/drbd0;

 disk   /dev/sdb;

 address 10.0.0.1:7788;

 meta-disk internal;

}

on centos2.cn7788.com {

 device  /dev/drbd0;

 disk   /dev/sdb;

 address 10.0.0.2:7788;

 meta-disk internal;

}

}

此配置文件的重要部分这里也说明一下:

·resource r0表示创建的资源名字。

·syncer C表示采用C协议,如果收到远程主机的写入确认,则认为写入完成。syncer选

项是设备主备节点同步时的网络速率最大值。

·每个主机的说明都以on开头,然后是各自的主机名,再后面的{}里是这个主机的配

置,监听端口为7788。

·meta-disk internal表示在同一个局域网内。

9)启动DRBD,激活前面配置的DRBD资源r0(两个节点都要执行)。在启动DRBD之

前,需要分别在两台机器的hdb1分区上创建供DRBD记录信息的数据块,分别在两台机器上

执行如下命令:

drbdadm create-md r0

创建r0的资源,其中r0是我们在drbd.conf里定义的资源名称,最后一行显示创建r0资源

成功。

现在可以启动DRBD了,分别在两台机器上执行,如下所示:

service drbd start

设置DRBD开机时自启动,命令如下:

chkconfig drbd on

10)初始化centos1(这步只需要在主节点上操作):

drbdsetup /dev/drbd0 primary -o

drbdadm primary r0

第一次设置主节点时用drbdadm命令会失败,所以先用drbdsetup进行操作,以后就可

以用drbdadm了。

再次查看DRBD当前的状态,命令如下所示:

cat /proc/drbd

version: 8.0.6 (api:86/proto:86)

SVN Revision: 2713 build by root@centos1,2008-06-27 14:07:14

1: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r—

ns:18528 nr:0 dw:0 dr:18528 al:0 bm:1 lo:0 pe:0 ua:0 ap:0

[>...................] sync’ed: 0.3%(8170/8189)M

finish: 6:46:43 speed: 336 (324) K/sec

resync: used:0/31 hits:1156 misses:2 starving:0 dirty:0 changed:2

act_log: used:0/257 hits:0 misses:0 starving:0 dirty:0 changed:0

现在主备机状态分别是“主/备”,主机磁盘状态是“实时”,备机状态是“不一致”。

在第3行中可以看到数据正在同步,即主机正在将磁盘上的数据传递到备机上,现在的

进度是0.3%。

设置完之后的第一次同步耗时会比较长,因为需要把整个分区的数据全部同步一遍。

第一次同步完成之后,就可以对DRBD的设备创建文件系统了。

稍等一段时间,在数据同步完成之后再查看一下两台机器的DRBD状态,命令分别如

下:

[root@centos1 ~]# service drbd status

SVN Revision: 3048 build by root@centos1.cn7788.cn,2010-01-20 06:09:12

0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r—

[root@centos2 ~]# service drbd status

SVN Revision: 3048 build by root@centos2.cn7788.cn,2010-01-20 06:09:02

0: cs:Connected st:Secondary/Primary ds:UpToDate/UpToDate C r—

现在磁盘状态都是“实时”,表示数据同步完成了。

在查看DRBD的实时状态时,我喜欢用以下语法(当然cat/proc/drbd也是可以的):

service drbd status

11)DRBD的使用。现在可以把主机上的DRBD设备挂载到一个目录上使用。备机的

DRBD设备无法被挂载,因为它是用来接收主机数据的,由DRBD负责操作。

在centos1主服务器上执行如下命令:

mkfs.ext3 /dev/drbd0

mount /dev/drbd0 /drbd

现在,就可以对/drbd分区进行读写操作了。

注意 secondary节点上不允许对DRBD设备进行任何操作,包括只读。所有的读写操作

只能在primary节点上进行,只有当primary节点挂掉时,secondary节点才能提升成为

primary节点,继续进行读写操作。

截至这步,DRBD的安装就算成功了。那么我们究竟如何保证DRBD机器的高可用呢?

这里就要用Heartbeat来实现了。另外,如果启动了Heartbeat服务,就不需要再手动mount

了,Heartbeat会自动mount。

3.Heartbeat的配置过程

1)在两台机器上分别安装Heartbeat,命令如下:

yum -y install heartbeat

奇怪的是,此命令要执行两次,否则无法安装Heartbeat,这个也算是安装Heartbeat的

Bug吧。

整个故障描述如下(很明显第一次安装Heartbeat包没有成功):

error: %pre(heartbeat-2.1.3-3.el5.centos.x86_64) scriptlet failed,exit status 9

error: install: %pre scriptlet failed (2),skipping heartbeat-2.1.3-3.el5.centos

Installed:

heartbeat.x86_64 0:2.1.3-3.el5.centos Dependency Installed:

heartbeat-pils.x86_64 0:2.1.3-3.el5.centos heartbeat-stonith.x86_64 0:2.1.3-3.el5.centos Complete!

本来要安装4个软件包,结果只安装成功了3个,所以必须再执行一次如下命令:

yum -y install heartbeat

其中Heartbeat配置共涉及如下4个文件:

/etc/ha.d/ha.cf

/etc/ha.d/haresources

/etc/ha.d/authkeys

/etc/ha.d/resource.d/killnfsd

2)两个节点的配置文件都一样,/etc/ha.d/ha.cf文件内容如下:

logfile    /var/log/ha-log

#定义HA的日志名字及存放位置

logfacility  local0

keepalive   2

#设定心跳(监测)时间为2秒

deadtime    5

#死亡时间定义为5秒

ucast     eth1 10.0.0.2

#采用单播方式,IP地址指定为对方IP

auto_failback off

#服务器正常后由主服务器接管资源,另一台服务器放弃该资源

node      centos1.cn7788.com centos2.cn7788.com

#定义节点

3)编辑双机互连验证文件authkeys,我们直接用Vim来编辑,如下所示:

vim /etc/ha.d/authkeys

文件内容如下:

auth 1

1 crc

需要将/etc/ha.d/authkeys设为600的权限,命令如下:

chmod 600 /etc/ha.d/authkeys

4)编辑集群资源文件/etc/ha.d/haresources,内容如下所示:

centos1.cn7788.com IPaddr::192.168.1.108/24/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/drbd::ext3 killnfsd

此文件在两台机器上的配置是一样的,强烈建议不要将另一台机器上配置成

centos2.7788.com,最好的做法是先只在centos1机器上配置,然后将文件scp或rsync配置

到centos2机器上面。

5)编辑脚本文件killnfsd,目的其实就是为了重启NFS服务。这是因为NFS服务切换后,

必须重新mount一下NFS共享出来的目录,否则会出现“stale NFS file handle”的错误。我们

直接用Vim来编辑/etc/ha.d/resource.d killnfsd文件,如下所示:

killall -9 nfsd; /etc/init.d/nfs restart; exit 0

给此文件755权限,如下所示:

chmod 755 /etc/ha.d/resource.d/killnfsd

以上命令的作用是给予killnfsd执行的权限。

6)在两个节点上启动Heartbeat,可以先在主节点上启动,命令如下:

[root@centos1 /]# service heartbeat start

[root@centos2 /]# service heartbeat start

这时就可以在另外的机器上面正常挂载192.168.1.108:/drbd/到自己的/mnt/data下进行

读写了,客户端会认为这仅仅是一台提供NFS的机器。192.168.1.108是Heartbeat产生的VIP

地址,也是对外提供NFS服务的地址。

4.进行测试数据工作和故障模拟

虽然我的线上环境已经很稳定了,但为了让大家熟悉DRBD+Heartbeat,还是按步骤进

行了相关操作。建议完成如下测试后再看Heartbeat能否做到真正的热切换。

1)在另一台FreeBSD 8下挂载192.168.1.108:/drbd,在向里面写数据时,忽然重新启

动主DRBD,看此时写数据是否受到了影响。你会发现primary主机重启或关机对写入数据丝

毫没有影响。

2)正常状态下将primary关机,然后看数据有无问题,观察DRBD的status;然后等主

机启动后,再观察变化,然后再将secondary关机,再启动,观察DRBD变化及Heartbeat起

了作用没有。

3)假设此时把primary的eth0给ifdown了,然后直接在secondary上进行主primary主机

的提升,并且也给mount了,你可能会发现在primary上测试拷入的文件确实同步过来了。

之后把primary的eth0恢复后,看看有没有自动恢复主从关系。经过支持查询,你可能会发

现DRBD检测出现了Split-Brain的状况,两个节点各自都standalone了。故障描述如下:

Split-Brain detected,dropping connection!这即是传说中的“脑裂”。DRBD官方推荐手动

恢复(生产环境下出现这个问题的几率很低,谁会故意去触动生产中的服务器网线呢?谁又

会像这样去折腾线上的生产服务器呢?)。我们在工作中进行IP迁徙时,发现只要不触动心

跳线,产生“脑裂”情况的几率真的很低。

以下为手动解决“脑裂”的方法。

a)在secondary主机上执行如下命令:

drbdadm secondary r0

drbdadm disconnect all

drbdadm -- --discard-my-data connect r0

b)在primary主机上执行如下命令:

drbdadm disconnect all

drbdadm connect r0

4)假设primary主机因为硬件损坏,需要将secondary提升成primary主机,应该如何处

理呢?方法如下:

a)在primary主机上先卸掉DRBD设备,命令如下:

umount /drbd

然后将主机降为备机,命令如下:

[root@centos1 /]# drbdadm secondary r0

[root@centos1 /]# cat /proc/drbd

1: cs:Connected st:Secondary/Secondary ds:UpToDate/UpToDate C r—

现在,两台主机都是备机了,我们可以通过st这项观察到此信息。

b)将centos2备机升级为primary主机,如下所示:

[root@centos2 /]# drbdadm primary r0

[root@centos2 /]# cat /proc/drbd

1: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r—

现在备机就成功转为主机了。由于centos2上面也有完整的数据,所以整个切换过程不

会发生数据丢失的现象,保证了数据的高可用性。

DRBD+Heartbeat+NFS高可用文件服务器的整个构建过程还是比较复杂的,我这里有

个建议:可以在局域网或VMware Server环境下先将整个过程测试几十次,这样大家自然而

然就会清楚其中的逻辑顺序了。大家也可以像我一样将这些操作步骤形成工作文档,这样,

在线上环境中实施时会非常容易,一步一步照做就行了。DRBD是现在很流行的技术,很多

公司极有可能会用它作为高可用文件服务器。不仅如此,DRBD+Heartbeat也适合做生产环

境下的高可用MySQL服务(这个也是MySQL官方推荐),所以我推荐大家熟练掌握

DRBD+Heartbeat+NFS的配置方法。


项目案例六:HAProxy双机高可用方案之

HAProxy+Keepalived

HAProxy+Keepalived配置过程如下。

1.整个环境的准备工作

两台服务器Dell 2950均要做好准备工作,比如设置好hosts文件及进行ntpd对时。

网络拓扑很简单,如下所示:

·ha1.offer99.com eth0:222.35.135.145

·ha2.offer99.com eth0:222.35.135.142

网卡用其自带的千兆网卡即可。

硬盘模式没有要求,RAID0或RAID1即可。

网站对外的VIP地址是:222.35.135.149,这是通过Keepalived来实现的,原理请参考

前面的章节;同时这也是网站的外网DNS对应的IP。

在这里,HAProxy采用七层模式,Frontend(前台)根据任意HTTP请求头内容做规则匹

配,然后把请求定向到相关的Backend(后台)。

2.HAProxy和Keepalived的安装过程

关于此安装过程,请大家参考前面的内容,这里就不重复了,主要注意关键位置的改

动。

1)首先在两台负载均衡机器上启动HAProxy,命令如下所示:

/usr/local/haproxy/sbin/haproxy -c -q -f /usr/local/haproxy/conf/haproxy.cfg

如果启动HAProxy程序后,我们又修改了haproxy.cfg文件,可以用如下命令平滑重启

HAProxy让新配置文件生效,命令如下所示:

 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.conf -st ‘cat /usr/local/haproxy/haproxy.pid‘

2)这里用网站生产环境下的配置文件/usr/local/haproxy/conf/haproxy.cfg举例说明,

其具体内容如下所示(两台HAProxy机器的配置内容一样):

global

    #log 127.0.0.1 local0

    maxconn 65535

    chroot /usr/local/haproxy

    uid 99

    gid 99

    #maxconn 4096

    spread-checks 3

    daemon

    nbproc 1

    pidfile /usr/local/haproxy/haproxy.pid

defaults

    log  127.0.0.1  local3

    mode http

    option httplog

    option httpclose

    option dontlognull

    option forwardfor

    option redispatch

    retries 10

    maxconn 2000

    stats uri /haproxy-stats

    stats auth admin:admin

    contimeout  5000

    clitimeout  50000

    srvtimeout  50000

frontend HAProxy

    bind *:80

    mode http

    option httplog

    acl cache_domain path_end .css .js .gif .png .swf .jpg .jpeg .ico

    acl cache_dir path_reg /apping

    acl cache_jpg path_reg /theme

    acl bugfree_domain path_reg /bugfree

    use_backend varnish.offer99.com if cache_domain

    use_backend varnish.offer99.com if cache_dir

    use_backend varnish.offer99.com if cache_jpg

    use_backend bugfree.offer99.com if bugfree_domain

    default_backend www.offer99.com

backend bugfree.offer99.com

    server bugfree 222.35.135.151:80 weight 5 check inter 2000 rise 2 fall 3

backend varnish.offer99.com

    server varnish 222.35.135.152:81 weight 5 check inter 2000 rise 2 fall 3

backend www.offer99.com

    balance source

    option httpchk HEAD /index.php HTTP/1.0

    server web1 222.35.135.154:80 weight 5 check inter 2000 rise 2 fall 3

    server web2 222.35.135.155:80 weight 5 check inter 2000 rise 2 fall 3

我将HAProxy的配置文件正则情况跟大家稍作说明:

acl cache_domain path_end .css .js .gif .png .swf .jpg .jpeg .ico

以上语句的作用是将.css和.js以及图片类型文件定义成cache_domain。

acl cache_dir path_reg /apping

acl cache_jpg path_reg /theme

以上语句的作用是定义静态页面路径,cache_dir和cache_jpg是自定义的名字。

use_backend varnish.offer99.com if cache_domain

use_backend varnish.offer99.com if cache_dir

use_backend varnish.offer99.com if cache_jpg

如果满足以上文件后缀名或目录名,则HAProxy将客户端请求定向到后端的varnish缓存

服务器varnish.offer99.com上。

acl bugfree_domain path_reg /bugfree

use_backend bugfree.offer99.com if bugfree_domain

以上两行代码的作用是将/bugfree定义成名字为bugfree-domain的静态域,即客户端有

bugfree的请求,则定向到后端的222.35.135.151机器上。

default_backend www.offer99.com

如果客户端的请求都不满足以上条件,则分发到后端的两台Apache服务器上。

配置文件建议写成Frontend(前台)和Backend(后台)的形式,方便我们根据需求来

写HAProxy的正则表达式,实现动静分离,或根据特定的文件名后缀(比如.php或.jsp)来

访问指定的phppool池或javapool池,我们还可以指定静态服务器池,让客户端对静态文件

(比如bmp、jsp或html)访问我们的varnish缓存服务器,这就是大家常说的动静分离功能

(Nginx也能实现此项功能),所以前后台的模型也是非常有用的,不喜欢Frontend(前

台)和Backend(后台)的朋友可以对比下以前没有采用这种模式的配置文件。下面我以老

男孩的生产服务器HAProxy负载均衡器配置文件来说明,大家可以以此范例文件作为参考来

配置自己网站的haproxy.cfg文件,内容如下所示:

global

    log 127.0.0.1 local0 notice

    chroot /srv/haproxy/run

    pidfile /srv/haproxy/run/haproxy.pid

    user oldboy

    group oldboy

    daemon

    maxconn 4096

    spread-checks 3

    nbproc 8

defaults

    log  global

    mode http

    option httpclose

    retries 3

    option redispatch

    contimeout  5000

    clitimeout  50000

    srvtimeout  50000

    stats enable

    stats uri /web? oldboy

    stats auth oldboy:sfklds

frontend oldboyserver

    bind *:80

    acl short_dom hdr(Host)-i etiantian.com

    redirect prefix http://www.etiantian.com code 301 if short_dom

    acl oldboyart_dom   hdr(Host)-i w.etiantian.com

    acl oldboyart_php   path_reg ^/([^/]*)\.html$

    acl oldboyart_home path -i /index.html

    use_backend phppool if oldboyart_dom oldboyart_php !oldboyart_home

    use_backend javapool if oldboyart_dom

    acl oldboydoc_php path_beg /oldboyi/

    acl static path_beg /images/

    acl static path_beg /css/

    acl static path /

    acl static path /index.html

    use_backend phppool if oldboydoc_php

    use_backend staticpool if static

    default_backend javapool-cop

# nginx static content

backend staticpool

    balance static-rr

    option httpchk HEAD /check.txt HTTP/1.0

    server oldboy80 10.0.0.80:8080 maxconn 4096 weight 100 check fall 3

    server oldboy81 10.0.0.81:8080 maxconn 4096 weight 50 check fall 3

# apache+tomcat service

backend javapool

    #reqirep ^([^\ ]*)\ /index.html(.*)\1\ /\2

    #reqirep ^([^\ ]*)\ /index.htm(.*)\1\ /\2

    balance roundrobin

    option httpchk HEAD /oldboycheck.jsp HTTP/1.0

    server tomcat11 10.0.0.17:9070 maxconn 4096 check inter 3s fall 3

    server tomcat14 10.0.0.18:9070 maxconn 4096 check inter 3s fall 3

    server tomcat71 10.0.0.19:9070 maxconn 4096 check inter 3s fall 3

    server tomcat72 10.0.0.20:9070 maxconn 4096 check inter 3s fall 3

backend javapool-cop

    balance roundrobin

    #option httpchk HEAD /oldboycheck.jsp HTTP/1.0

    server tomcat11 10.0.0.21:80 maxconn 4096 check fall 3

    server tomcat14 10.0.0.22:80 maxconn 4096 check fall 3

    server tomcat71 10.0.0.23:80 maxconn 4096 check fall 3

    server tomcat72 10.0.0.24:80 maxconn 4096 check fall 3

backend phppool

    balance static-rr

    option httpchk HEAD /check.txt HTTP/1.0

    server php80 10.0.0.83:8066 maxconn 4096 weight 100 check fall 3

    server php81 10.0.0.84:8066 maxconn 4096 weight 50 check fall 3

Keepalived的配置过程比较简单,这里略过,大家可以参考前面的配置,配置成功后可

以分别在两台机器上启动HAProxy及Keepalived服务,主机上Keepalived.conf配置文件内容

如下:

! Configuration File for keepalived

global_defs {

  notification_email {

    yuhongchun027@163.com

  }

  notification_email_from sns-lvs@gmail.com

  smtp_server 127.0.0.1

  router_id LVS_DEVEL

}

vrrp_instance VI_1 {

  state MASTER

  interface eth0

  virtual_router_id 51

  priority 100

  advert_int 1

  authentication {

    auth_type PASS

    auth_pass 1111

  }

  virtual_ipaddress {

  203.93.236.149

  }

}

3.替HAProxy添加日志支持

编辑/etc/syslog.conf文件,添加内容如下:

local3.*   /var/log/haproxy.log

local0.*   /var/log/haproxy.log

编辑/etc/sysconfig/syslog文件,修改内容如下:

SYSLOGD_OPTIONS="-r -m 0"

然后重启syslog服务,命令如下:

service syslog restart

在这里有一点要说明,在实际的生产环境下,开启HAProxy日志功能是需要硬件成本

的,它会消耗大量的CPU资源从而导致系统速度变慢(这点在硬件配置较弱的机器上表现尤

为突出),如果不需要开启HAProxy日志功能这里可以将其关闭,大家可以根据实际需求来

选择是否开启HAProxy日志。

4.验证此架构及注意事项

我们可以关闭主HAProxy机器或重新启动,看VIP地址在此过程中有没有正确地转移到

从HAProxy机器上,是否影响我们访问网站。以上步骤我测试过多次,加之线上环境的稳定

运行,证明HAProxy+Keepalived双机方案确实是有效的。

关于HAProxy+Keepalived这种负载均衡高可用架构,有些情况我也跟大家说明一下。

·在此HAProxy+Keepalived负载均衡高可用架构中,如何解决Session问题呢?这里采用

的是它自身的balance source机制,它跟Nginx的ip_hash机制原理类似,是让客户机访问时

始终访问后端的某一台真实的Web服务器,这样Session就固定下来了。

·option httpchk HEAD/index.jsp HTTP/1.0是网页监控,如果HAProxy检测不到Web根

目录下的index.jsp,就会产生503报错。

5.HAProxy的监控页面

可以在地址栏输入http://www.offer99.com/haproxy-stats/,输入用户名和密码后,显

示界面如图4-9所示(HAProxy内置的监控页面,这是我非常喜欢的功能之一)。

Session rate的Cur选项可以反映网站的即时并发数,这个是大家最关心的选项之一,还

可以利用此监控页面关注Web服务器的存活信息等,相当实用。



1)目前网站架构一般分为负载均衡层、Web层和数据库层,其实一般我还会多加一

层,即文件服务器层,因为随着网站的流量越来越多,文件服务器的压力也越来越大,如果

觉得DRBD+Heartbeat+NFS架构在后期压力太大,这时候可以考虑图片单独分离,或者在

前端采用Squid服务器缓存集群的方法来解缓海量图片的压力。网站最前端的负载均衡层称

为Director,它起分摊请求的作用,最常见的就是轮询,这个基本功能是每一台负载均衡器

都自带的。

2)F5是通过硬件的方式来实现负载均衡的,在CDN系统上用得较多,用于Squid反向加

速集群的负载均衡,是专业的硬件负载均衡设备,尤其适合每秒新建连接数和并发连接数要

求高的场景。LVS和HAProxy是通过软件的方式来实现的,但其稳定性也相当强悍,在处理

高并发的情况时有着相当不俗的表现。至于Nginx,我现在较倾向于将其放在整个系统或网

站的中间,让其作为中间层的负载均衡器,这样效果更好。

3)Nginx对网络的依赖较小,理论上只要ping得通,网页访问正常,Nginx就能连得

通。Nginx还能区分内外网,如果是同时拥有内外网的节点,就相当于单机拥有了备份线

路。LVS则比较依赖于网络环境,它所涉及项目的所有服务器都必须在同一机房的同一交换

机上,我们有时不得不考虑单交换带来的单点故障问题。

4)目前较成熟的负载均衡高可用技术有LVS+Keepalived、Nginx+Keepalived,以前

Nginx没有成熟的双机备份方案,但通过Shell脚本监控是可以实现的。另外,如果考虑Nginx

的双主负载均衡高可用,也可以通过DNS轮询的方式来实现,但由于我们目前的商务网站要

考虑Google收录及域名备案还有其他的因素,所以暂时只能用单域名,目前只能采用

Nginx+Keepalived方案了。Nginx+Keepalived在我们的机房中已经稳定运行两年了,所以

我向大家推荐这个方案,有相关工作需求的朋友可以放心实施。

5)集群是指负载均衡后面的Web集群或Tomcat集群等,但有时候大家所谈论的Linux

集群却泛指了整个系统架构,既包括了负载均衡器,也包括了后端的应用服务器集群等。其

实我们可以这样来加以区分,如果专指小范围的集群概念,可以指Web集群、Squid集群

等,如果指广泛意义上的集群,我们可以接受Linux集群这种叫法,这样大家就不至于混淆

了。

6)负载均衡高可用中的高可用指的是实现负载均衡器的HA,即一台负载均衡器坏掉后

另一台可以在小于1秒的时间内切换,最常用的软件就是Keepalived和Heartbeat,在成熟的

生产环境下负载均衡器方案有LVS+Keepalived、Nginx+Keepalived。如果能保证Heartbeat

的心跳线稳定的话,Heartbeat+DRBD也可应用在很成熟的生产环境下,适合NFS文件服务

器或MySQL的高可用环境。

7)LVS的优势非常多,比如:抗负载能力强,工作稳定性高(因为有成熟的HA方

案),无流量的转发,效率高,基本上能支持所有的TCP应用(当然包括Web)等。基于以

上的优点,LVS拥有不少的粉丝,但它也有缺点,LVS对网络的依赖性太大了,在网络环境

相对复杂的应用场景中,我不得不放弃它而选用Nginx。

8)Nginx对网络的依赖性小,而且它的正则表达式强大且灵活(个人觉得比HAProxy的

确实简单些),其稳定的特点吸引了不少人,而且配置起来也相当方便和简约,在中小型项

目的实施过程中我基本上都会考虑用它。当然,如果资金充足,F5是不二的选择。

9)在大型网站架构中其实可以结合使用F5/LVS或Nginx,根据情况选择其中的两种或全

部选择。如果因为预算的原因不选择F5,那么网站最前端的指向应该是LVS,也就是DNS的

指向应为LVS均衡器,LVS的优点令它非常适合这个任务。那些重要的IP地址,最好交由LVS

托管,比如数据库的IP、提供Web服务的IP等,这些IP地址随着时间的推移,使用面会越来

越大。如果更换IP则故障会接踵而至,所以将这些重要IP交给LVS托管是最为稳妥的。

10)VIP地址是Keepalived或Heartbeat虚拟的一个IP,它是一个对外的公开IP,也是

DNS指向的IP,所以在设计网站架构时,你必须向你的IDC多申请一个对外IP。如果是做

LVS+Keepalived的纯公网架构,那就最好购买一个IP网段吧。

11)在实际项目实施过程中,我发现LVS和Nginx对HTTPS的支持都非常好,尤其是

LVS,相对而言处理起来更为简便。

12)如果是基于LVS+Keepalived及Nginx+Keepalived架构的Web网站发生故障时,我

们处理起来是很方便的。如果发生了系统故障或服务器相关故障,可以将DNS指向后端的某

台真实Web机器上,达到短期处理故障的目的。对于广告网站和电子商务网站来说,流量就

是金钱,这也是要将负载均衡高可用设计于此的原因。如果是大型的广告网站,我建议最好

直接上CDN系统。

13)现在Linux集群被大家神化了,其实它并不是很复杂,关键看你的应用场景,哪种

适合就选用哪种。Nginx、HAProxy、LVS和F5都不是神话,都有自己本身的缺陷,我们应该

扬长避短,最大限度地发挥它们的优势。

14)另外关于Session共享的问题(这也是一个老生常谈的问题了),Nginx可以用

ip_hash机制解决,HAProxy有balance source,而F5/LVS则可以用会话保持机制来解决。此

外,还可以将Session写进数据库,这也是一个解决Session共享的好办法,当然,这也会加

重数据库的负担,这就要看系统架构师的取舍了。

15)现在很多朋友都用Nginx(尤其是作为Web服务器),其实在服务器性能优异且内

存足够的情况下,Apache的抗并发能力并不弱(16GB的内存下Apache过2000并发问题也不

大,当然配置文件也要优化),整个网站的瓶颈应该还是在数据库方面。我建议大家全面了

解Apache和Nginx,前端用Nginx作负载均衡器,后端用Apache作Web应用服务器,这样升

级以前的单Apache网站时就可以实现平稳过渡,给网站带来的影响也是最小的。

16)Heartbeat的“脑裂”问题没有想象中的那么严重,在线上环境下可以考虑使用它。

DRDB+Heartbeat算是成熟的应用了,我建议掌握这个知识热点。我在相当多的场合中用此

组合来替代EMC共享存储,毕竟30多万元的价格并不是每个客户都能接受的。

17)无论设计的方案多么成熟,还是建议配置Nagios监控机来实时监控服务器的情况。

邮件和短信报警都可以开启,毕竟手机可以随身携带。有条件的话还可以购买专门的商业扫

描网站服务,例如Alertbot,它会以1秒为频率扫描你的网站,如果发现没有alive,它会向

你的邮箱中发警告邮件。

18)关于网站的安全性问题,我建议用硬件防火墙,比较推荐的是华赛或Juniper系列

的防火墙,DDoS的安全防护一定要到位(国内的DDoS攻击还是挺多的)。Linux服务器本

身的iptables和SELinux均可关闭。另外,端口数量开放得越少越好。

19)测试网站的响应时间时我们可以用http://tools.pingdom.com,我发现用了

LVS+Keepalived、Nginx+Keepalived后并不影响网站的访问速度,各位不用多虑。Nginx现

在做反向加速也日趋成熟了,大家可尝试一下在自己的网站上用它来作反向加速服务器。


线上环境中MySQL应该采用的编译安装方法

由于服务器都是最小化安装,所以要安装gcc、gcc-c++等基础库文件,命令如下:

yum -y install gcc gcc-c++ zlib-devel libtool ncurses-devel

libxml2-devel

groupadd mysql

useradd -g mysql mysql

cd /usr/local/src/

tar zxvf mysql-5.1.47.tar.gz

cd mysql-5.1.47

./configure --prefix=/usr/local/mysql --with-charset=utf8 --with-extra-charsets=all --enable-thread-safe-client --enable-assembler --with-readline --with-big-tables --with-plugins=all --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static

make && make install && cd ../

2)对mysql进行权限配置,将mysql的数据安装路径设为/data/mysql,并配置成mysql

为服务启动状态,步骤如下:

cd /usr/local/mysql

cp /usr/local/mysql/share/mysql/my-huge.cnf /etc/my.cnf

cp /usr/local/mysql/share/mysql/mysql.server /etc/init.d/mysqld

chmod +x /etc/init.d/mysqld

chown -R mysql:mysql /usr/local/mysql

mkdir -p /data/mysql

这里暂时只用系统自带的my-huge.cnf作为MySQL数据库的配置文件,后期根据MySQL

的status运行状态进行调优整理。


下面,我们根据以上推荐的硬件配置并结合一份已经优化好的my.cnf进行说明。

以下只列出my.cnf文件中[mysqld]段落里的内容,其他段落的内容对MySQL的运行性

能影响甚微,比如MySQL的语言和日志配置选项,这里姑且忽略。

[mysqld]

[mysqld]组中包括了mysqld服务启动时的参数,它涉及的方面很多,其中有mysql的

目录和文件、通信、网络、信息安全、内存管理、优化、查询缓存区,以及MySQL日志设置

等。

port=3306

mysqld服务运行时的端口号。

socket=/tmp/mysql.sock

socket文件是在Linux/Unix环境下特有的,用户在Linux/Unix环境下客户端连接可以不

通过TCP/IP网络而直接使用unix socket连接MySQL(基于安全因素考虑)。

skip-external-locking

避免MySQL的外部锁定,减少出错几率,增强稳定性。

skip-name-resolve

禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时

间。但需要注意的是,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式了,

否则MySQL将无法正常处理连接请求。

back_log = 384

back_log参数的值指出在MySQL暂时停止响应新请求之前,短时间内的多少个请求可以

被存在堆栈中。如果系统在短时间内有很多连接,则需要增大该参数的值,该参数值指定到

来的TCP/IP连接的侦听队列的大小。不同的操作系统在这个队列的大小上有它自己的限制。

如果试图将back_log设定得高于操作系统的限制将是无效的。其默认值为50。对于Linux系

统而言,推荐设置为小于512的整数。

key_buffer_size = 384M

key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。对于

内存在4GB左右的服务器来说,该参数可设置为256MB或384MB。不建议将该参数值设置得

过大,这样反而会降低服务器的整体效率。

max_allowed_packet = 4M

max_allowed_packet指在网络传输中一次消息传输量的最大值。系统默认值为1MB,

最大值是1GB,必须设定为1024的倍数,单位为字节。

thread_stack = 256K

thread_stack是指设置MySQL每个线程的堆栈大小,默认值足够大,可满足普通操作。

可设置范围128KB至4GB,默认192KB。

table_cache = 614K

table_cache是指表高速缓存的大小。当MySQL访问一个表时,如果在MySQL表缓冲区

中还有空间,那么这个表就被打开并放入表缓冲区,这样做的好处是可以更快速地访问表中

的内容。一般来说,可以通过查看数据库运行峰值时间的状态值Open_tables和

Opened_tables,用以判断是否需要增加table_cache的值,即如果open_tables接近

table_cache的时候,并且Opened_tables这个值在逐步增加,那就要考虑增加这个值的大小

了。

sort_buffer_size = 6M

sort_buffer_size指的是查询排序时所能使用的缓冲区大小,系统默认大小为2MB,从

5.1.23版本开始,在除了Windows之外的64位平台上可以超出4GB的限制。

注意 该参数对应的分配内存是每连接独占的,如果有100个连接,那么实际分配的总

排序缓冲区大小为100×6MB=600MB。所以,对于内存在4GB左右的服务器来说,推荐将其

设置为6~8MB。

read_buffer_size = 4M

read_buffer_size指的是读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,

该参数对应的分配内存也是每连接独享。

join_buffer_size = 8M

join_buffer_size指的是联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,

该参数对应的分配内存也是每连接独享。

myisam_sort_buffer_size = 64M

myisam_sort_buffer_size用于设置在REPAIR TABLE或用CREATE INDEX创建索引或

ALTER TABLE的过程中排序索引所分配的缓冲区大小,可设置范围为4MB至4GB,默认为

8MB。

thread_cache_size = 64

thread_cache_size用于设置Thread Cache池中可以缓存的连接线程最大数量,可设置

为0~16384,默认为0。这个值表示可以重新利用保存在缓存中线程的数量,当断开连接

时,如果缓存中还有空间,那么客户端的线程将被放到缓存中;如果线程重新被请求,那么

请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如

果有很多新的线程,增加这个值可以改善系统性能。通过比较Connections和

Threads_created状态的变量,可以看到这个变量的作用。我们可以根据物理内存设置规则

如下:1GB内存可以配置为8,2GB内存可以配置为16,3GB内存可以配置为32,4GB及以上

可以给此值为64或更大的数值。

query_cache_size = 64M

query_cache_size指定MySQL查询缓冲区的大小。可以通过在MySQL控制台观察,如果

Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;如果Qcache_hits

的值非常大,则表明查询缓冲使用得非常频繁;另外,如果该值较小反而会影响效率,那么

可以考虑不用查询缓冲;对于Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片

很多。

tmp_table_size = 256M

tmp_table_size用于设置内存临时表的最大值。如果超过该值,则会将临时表写入磁

盘,其范围为1KB到4GB。

max_connections = 768

max_connections用于指定MySQL允许的最大连接进程数。如果在访问论坛时经常出

现“Too Many Connections”的错误提示,则需要增大该参数值。

max_connect_errors = 1000

max_connect_errors用于设置每台主机的连接请求异常中断的最大次数,当超过该次

数,MySQL服务器将禁止host的连接请求,直到MySQL服务器重启或通过flush hosts命令清

空此host的相关信息,此值可设置为1~18446744073709547520,默认为10。

wait_timeout = 10

wait_timeout用于指定一个请求的最大连接时间,对于4GB左右内存的服务器来说,可

以将其设置为5~10。

thread_concurrency = 8

thread_concurrency的取值为服务器逻辑CPU数量的两倍,在本例中,服务器有2个物理

CPU,而每个物理CPU又支持H.T超线程,所以实际取值为4×2=8;这也是目前双四核主流

服务器的配置。

skip-networking

skip_networking指开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果Web服务

器是以远程连接的方式访问MySQL数据库服务器的则不要开启该选项,否则将无法正常连

接!

table_cache=1024

物理内存越大,设置就越大。默认为2402,调到512~1024最佳。

innodb_additional_mem_pool_size=4M

默认为2MB。

innodb_flush_log_at_trx_commit=1

设置为0就是等到innodb_log_buffer_size列队满后再统一储存,默认为1。

innodb_log_buffer_size=2M

默认为1MB。

innodb_thread_concurrency=8

服务器CPU有几个就设置为几,建议用默认设置,一般为8。

tmp_table_size=64M

用于设置内存临时表最大值。如果超过该值,则会将临时表写入磁盘。设置范围为1KB

至4GB。

read_rnd_buffer_size=16M

read_rnd_buffer_size设置进行随机读的时候所使用的缓冲区。此参数和

read_buffer_size所设置的Buffer相反,一个是顺序读的时候使用,一个是随机读的时候使

用。但是两者都是针对线程的设置,每个线程都可以产生两种Buffer中的任何一种。

read_rnd_buffer_size的默认值为256KB,最大值为4GB。

值得注意的是,如果key_reads太大,则应该把my.cnf中的key_buffer_size变大,保持

key_reads/key_read_requests至少在1/100以上,越小越好;如果qcache_lowmem_prunes

很大,就要增加query_cache_size的值。

不过,很多时候需要具体情况具体分析,其他参数的变更我们可以等MySQL上线稳定一

段时间后根据status值进行调整。

1.慢查询

有时我们为了定位系统中效率比较低下的Query语名,需要打开慢查询日志,也就是

slow query log。查询慢查询日志的相关命令如下:

mysql> show variables like ‘%slow%‘;

+------------------+-------+

| Variable_name| Value |

+------------------+-------+

| log_slow_queries | ON |

| slow_launch_time | 2  |

+------------------+-------+

mysql> show global status like ‘%slow%‘;

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| Slow_launch_threads | 0  |

| Slow_queries    | 4148 |

+------------------+-------+

打开慢查询日志可能会对系统性能有一点儿影响,如果你的MySQL是主-从结构,可以

考虑打开其中一台从服务器的慢查询日志,这样既可以监控慢查询,对系统性能影响也会很

小,另外,可用MySQL自带的命令mysqldumpslow进行查询,比如,下面的命令可以查出访

问次数最多的20个SQL语句:

mysqldumpslow -s c -t 20 host-slow.log

2.连接数

如果经常遇见“MySQL:ERROR 1040:Too manyconnections”的情况,一种情况是访问量

确实很高,MySQL服务器抗不住,这个时候就要考虑增加从服务器分散读压力了,另外一种

情况是MySQL配置文件中max_connections的值过小。来看一个例子,如下所示:

mysql> show variables like ‘max_connections‘;

+-----------------+-------+

| Variable_name | Value |

+-----------------+-------+

| max_connections | 256 |

+-----------------+-------+

这台MySQL服务器的最大连接数是256,然后查询一下该服务器响应的最大连接数:

mysql> show global status like ‘Max_used_connections‘;

+----------------------+-------+

| Variable_name    | Value |

+----------------------+-------+

| Max_used_connections | 245 |

+----------------------+-------+

MySQL服务器过去的最大连接数是245,没有达到服务器连接数的上限256,应该不会

出现1040错误,比较理想的设置是:

Max_used_connections/max_connections *100% ≈ 85%

最大连接数占上限连接数的85%左右,如果发现比例在10%以下,则说明MySQL服务

器连接数的上限设置得过高了。

3.key_buffer_size

key_buffer_size是设置MyISAM表索引引擎缓存空间的大小,此参数对MyISAM表性能影

响最大,下面是一台以MyISAM为主要存储引擎服务器的配置:

mysql> show variables like ‘key_buffer_size‘;

+-----------------+------------+

| Variable_name  |  Value  |

+-----------------+------------+

| key_buffer_size | 536870912 |

+-----------------+------------+

从上面的配置可以看出,分配了512MB内存给key_buffer_size,我们再看一下

key_buffer_size的使用情况:

mysql> show global status like ‘key_read%‘;

+------------------------+-------------+

| Variable_name      | Value  |

+------------------------+-------------+

| Key_read_requests   | 27813678764 |

| Key_reads        | 6798830  |

+------------------------+-------------+

一共有27813678764个索引读取请求,有6798830个请求在内存中没有找到,直接从硬

盘读取索引,计算索引未命中缓存的概率:

key_cache_miss_rate = Key_reads / Key_read_requests * 100%

比如上面的数据,key_cache_miss_rate为0.0244%,4000个索引读取请求才有一个直

接读硬盘,已经很不错了,key_cache_miss_rate在0.1%以下都很好(每1000个请求有一个

直接读硬盘),如果key_cache_miss_rate在0.01%以下,则说明key_buffer_size分配得过

多,可以适当减少。

MySQL服务器还提供了key_blocks_*参数,如下所示:

mysql> show global status like ‘key_blocks_u%‘;

+------------------------+-------------+

| Variable_name      |  Value  |

+------------------------+-------------+

| Key_blocks_unused   |  0       |

| Key_blocks_used     |  413543   |

+------------------------+-------------+

Key_blocks_unused表示未使用的缓存簇(blocks)数;Key_blocks_used表示曾经用到

的最大的blocks数。比如这台服务器,所有的缓存都用到了,要么增加key_buffer_size,要

么就是过渡索引,把缓存占满了。比较理想的设置是:

Key_blocks_used/(Key_blocks_unused+Key_blocks_used)*100%≈80%

4.临时表

当执行语句时,关于已经被创造了的隐含临时表的数量,我们可以用如下命令查知其具

体情况:

mysql>show global status like ‘created_tmp%‘;

+-------------------------+---------+

| Variable_name      | Value  |

+-------------------------+---------+

| Created_tmp_disk_tables| 21197  |

| Created_tmp_files    |  58  |

| Created_tmp_tables   | 1771587|

+-------------------------+---------+

每次创建临时表时,created_tmp_tables都会增加,如果是在磁盘上创建临时

表,created_tmp_disk_tables也会增加,created_tmp_files表示MySQL服务创建的临时文

件数,比较理想的配置是:

created_tmp_disk_tables/created_tmp_tables*100%<=25%

比如上面的服务器,Created_tmp_disk_tables/Created_tmp_tables*100%=1.20%,

应该说是相当好了。我们再看一下MySQL服务器对临时表的配置:

mysql>show variables where Variable_name in(‘tmp_table_size‘,‘max_heap_table_size‘);

+---------------------+-----------+

| Variable_name    | Value   |

+---------------------+-----------+

| max_heap_table_size| 268435456|

| tmp_table_size   | 536870912|

+---------------------+-----------+

只有256MB以下的临时表才能全部放在内存中,超过的就会用到硬盘临时表。

5.open table的情况

open_tables表示打开表的数量,opened_tables表示打开过的表数量,我们可以用如下

命令查看其具体情况:

mysql>show global status like ‘open%tables%‘;

+---------------+-------+

|Variable_name| Value|

+---------------+-------+

|Open_tables | 919  |

|Opened_tables| 1951 |

+---------------+-------+

如果opened_tables数量过大,说明配置中table_cache(MySQL 5.1.3之后这个值叫做

table_open_cache)的值可能太小,我们查询一下服务器table_cache值:

mysql>show variables like ‘table_cache‘;

+---------------+-------+

|Variable_name| Value|

+---------------+-------+

|table_cache  | 2048 |

+---------------+-------+

比较合适的值为:

Open_tables/Opened_tables *100%>=85%

Open_tables/table_cache*100%<=95%

6.进程使用情况

如果我们在MySQL服务器的配置文件中设置了thread_cache_size,当客户端断开之

时,服务器处理此客户请求的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存

数未达上限)。threads_created表示创建过的线程数,我们可以用如下命令查看:

mysql>show global status like ‘Thread%‘;

+-------------------+-------+

| Variable_name  | Value|

+-------------------+-------+

| Threads_cached  | 46 |

| Threads_connected | 2  |

| Threads_created | 570 |

| Threads_running | 1  |

+-------------------+-------+

如果发现threads_created的值过大,表明MySQL服务器一直在创建线程,这也是比较

耗资源的,可以适当增大配置文件中thread_cache_size的值,查询服务器

thread_cache_size配置,如下所示:

mysql>show variables like ‘thread_cache_size‘;

+-------------------+-------+

| Variable_name  | Value|

+-------------------+-------+

| thread_cache_size | 64 |

+-------------------+-------+

示例中的MySQL服务器还是挺健康的。




生产环境下的DRBD+Heartbeat+MySQL双机高可用

1.DRBD的部署安装

两台机器分别用如下命令来安装DRBD软件,命令如下所示:

yum -y install drbd83 kmod-drbd83

载入drbd模块并检测模块是否正常载入,命令如下所示:

modprobe drbd

lsmod|grep drbd

两台机器的drbd.conf配置文件内容如下所示(两台机器的配置是一样的):我们用cat

命令查看/etc/drbd.conf配置文件,此文件内容如下:

global {

# minor-count dialog-refresh disable-ip-verification

usage-count no;       # 统计drbd的使用

}

common {

syncer { rate 30M; }  # 同步速率,视带宽而定

}

resource r0 {     # 创建一个资源,名字叫”r0”

protocol C;      # 选择的是drbd的C协议(数据同步协议,C为收到数据并写入后返回,确认成功)

handlers {       # 默认drbd的库文件

pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";

pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";

local-io-error "/usr/lib/drbd/notify-io-error.sh;

/usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f";

# fence-peer "/usr/lib/drbd/crm-fence-peer.sh";

# split-brain "/usr/lib/drbd/notify-split-brain.sh root";

# out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";

# before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k";

# after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;

}

startup {

# wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb

wfc-timeout 120;

degr-wfc-timeout 120; 

}

disk {

# on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes

# no-disk-drain no-md-flushes max-bio-bvecs

on-io-error detach;

}

net {

# sndbuf-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers

# max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret

# after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork

max-buffers 2048;

cram-hmac-alg "sha1";

shared-secret "123456";

# DRBD同步时使用的验证方式和密码信息

# allow-two-primaries;

}

syncer {

rate 30M;

# rate after al-extents use-rle cpu-mask verify-alg csums-alg

}

on centos1.mypharma.com { # 设定一个节点,分别以各自的主机名命名

device /dev/drbd0;  # 设定资源设备/dev/drbd0指向实际的物理分区/dev/sda6

disk  /dev/sda6;

address 192.168.1.1:7788; # 设定监听地址以及端口

meta-disk   internal;

}

on centos2.mypharma.com { # 设定一个节点,分别以各自的主机名命名

device /dev/drbd0; # 设定资源设备/dev/drbd0 指向实际的物理分区 /dev/sdb1

disk  /dev/sda6;

address 192.168.1.2:7788;   # 设定监听地址以及端口

meta-disk   internal;    # internal表示是在同一局域网内

}

}

1)需要执行drbdadm create-md r0命令来创建DRBD元数据信息,执行命令如下所示

(两台机器都需要执行此步),可能出现下列报错:

Device ‘0‘ is configured!

Command ‘drbdmeta 0 v08 /dev/sda6 internal create-md‘ terminated with exit code 20

drbdadm create-md r0: exited with code 20

为了避免此错误,建议用dd破坏文件分区,命令如下所示:

dd if=/dev/zero of=/dev/sda6 bs=1M count=100

在centos1的机器上操作,命令如下:

[root@centos1 ~]# drbdadm create-md r0

命令显示结果如下所示:

Writing meta data...

initializing activity log

NOT initialized bitmap

New drbd meta data block successfully created.

在centos2的机器上操作,命令如下:

[root@centos2 ~]# drbdadm create-md r0

命令显示结果如下所示:

Writing meta data...

initializing activity log

NOT initialized bitmap

New drbd meta data block successfully created.

两台机器分别有上面的显示结果则表明一切都正常。

2)启动DRBD设备,两台机器上分别执行如下命令:

service drbd start

2.Heartbeat的安装和部署

1)两台机器上分别用yum来安装heartbeat,如下命令操作两次:

yum -y install heartbeat

如果只操作一次,你会惊奇地发现,heartbeat第一次时并没有安装成功。

2)两个节点的heartbeat配置文件分别如下所示。

centos1.mypharma.com的配置文件:

logfile /var/log/ha-log

# 定义Heartbeat的日志名字及位置

logfacility local0

keepalive 2

# 设定心跳(监测)时间为2秒

deadtime 15

# 设定死亡时间为15秒

ucast eth0 112.112.68.172

ucast eth2 10.0.0.2

ucast eth3 192.168.1.2

# 采用单播的方式,IP地址指定为对方IP,这里为了防止“脑裂”,特意使用了两条心跳线外加公网地址IP作为心跳

# 监测线路,事实上,在项目上线测试阶段,除非人为手动破坏,否则没有发生“脑裂”的可能。

auto_failback off

# 当Primary机器发生故障切换到Secondary机器后不再进行切回操作。

node centos1.mypharma.com centos2.mypharma.com

centos2.mypharma.com的配置文件:

logfile /var/log/ha-log

logfacility local0

keepalive 2

deadtime 15

ucast eth0 112.112.68.170

ucast eth2 10.0.0.1

ucast eth3 192.168.1.1

auto_failback off

node centos1.mypharma.com centos2.mypharma.com

#参数情况跟centos1类似,这里不再重复解释。

3)编辑双机互连验证文件cat/etc/ha.d/authkeys,如下所示:

auth 1

1 crc

需要将此文件设定为600权限,否则启动heartbeat服务时会报错,命令如下所示:

chmod 600 /etc/ha.d/authkeys

4)编辑集群资源文件/etc/ha.d/haresources,命令如下:

centos1.mypharma.com IPaddr::112.112.68.174/29/eth0 drbddisk::r0

Filesystem::/dev/drbd0::/drbd::ext3 mysqld

这个文件在两台机器上都是一样的,这个轻易不要改动。

mysqld为MySQL服务器启动、重启及关闭脚本,这里选择安装MySQL自带的,后面在安

装MySQL时会提到此步。


2.MySQL Proxy 0.8.2的安装步骤

先从官方网址http://dev.mysql.com/downloads/mysql-proxy/下载源码包

到/usr/local/src/目录下,建议大家采用最新的MySQL Proxy 0.8.2版本。安装MySQL Proxy

0.8.2之前先决条件如下。

·libevent 1.x或更高

·glib 2 2.6.0或更高

·lua 5.1.x或更高

·pkg-config

·libtool 1.5或更高

·MySQL 5.0.x或更高的开发库

·服务器操作系统:CentOS 5.8 x86_64

1)为了加快安装进度,可以先yum安装必需的库,同时解决pkg-config、libtool和

MySQL开发库,由于mysql-proxy实际上并不需要在本机上运行MySQL实例,所以这里用

yum安装,命令如下所示:

yum -y install gcc gcc-c++ autoconf mysql-devel libtool pkgconfig ncurses ncurses-dev

2)安装libevent-2.0.13版本

3)安装glib-2.18.4版本,命令如下所示:

4)安装lua-5.1.4版本,安装之前需要先安装readline-6.1,否则会报缺少头文件的错

误。

运行如下命令进行安装:

cd /usr/local/src

wget ftp://ftp.cwru.edu/pub/bash/readline-6.1.tar.gz

tar xvf readline-6.1.tar.gz

cd readline-6.1

./configure

make && make install

为了让动态链接库为系统所共享,这里用ldconfig,命令如下:

ldconfig -v

用此选项时,ldconfig将显示正在扫描的目录及搜索到的动态链接库,以及它所创建的

连接的名字。

安装lua-5.1.4版本,其下载地址为http://www.lua.org/ftp/lua-5.1.4.tar.gz。运行如下

命令安装:

cd /usr/local/src

tar xvf lua-5.1.4.tar.gz

cd lua-5.1.4

注意 64位系统,须在CFLAGS里加上-fPIC,我们用Vim编辑src/Makefile文件,修改代

码命令如下所示:

CFLAGS= -O2 -Wall -fPIC $(MYCFLAGS)

我们继续用如下命令进行安装,如下:

make linux

make install

5)配置pkg-config环境变量,命令如下所示:

cp etc/lua.pc /usr/local/lib/pkgconfig/

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

6)经过以上操作就完成了基础文件的安装,接下来是MySQL Proxy 0.8.2的安装,下载

完后运行如下命令:

tar xvf mysql-proxy-0.8.2.tar.gz

cd mysql-proxy-0.8.2

./configure -prefix=/usr/local/mysql-proxy

make && make install

cp lib/rw-splitting.lua /usr/local/lib/

cp lib/admin.lua /usr/local/lib/

mysql-proxy --help-all

管理功能选项:

·--admin-address=host:port指定一个mysql-proxy的管理端口,默认是4041。

·--admin-username=指定登录的用户名。

·--admin-password=指定登录的密码。

·--admin-lua-script=指定由admin插件执行的脚本。

代理功能选项:

·-P,--proxy-address=是mysql-proxy服务器端的监听端口,默认是4040,建议改为

3306,方便开发人员编写代码。

·-r,--proxy-read-only-backend-addresses=是只读Slave的地址和端口,默认为不设

置。

·-b,--proxy-backend-addresses=是远程Master的地址和端口,可设置多个做failover

和load balance,默认是127.0.0.1:3306。

·--proxy-skip-profiling表示关闭查询分析功能,默认是打开的。

·-s,--proxy-lua-script=指定一个Lua脚本来控制mysql-proxy的运行和设置,这个脚本

在每次新建连接和脚本发生修改的时候将重新调用。

其他选项:

·--defaults-file=配置文件,可以把mysql-proxy的参数信息置入一个配置文件里,建议

大家用这种配置MySQL Proxy,比较方便。

·--daemon mysql-proxy以守护进程方式运行。

·--pid-file=file设置mysql-proxy的存储PID文件的路径。

·--keepalive try to restart the proxy if it crashed,保持连接启动进程会有两个,一号

进程用来监视二号进程,如果二号进程死掉自动重启Proxy,这是新版MySQL Proxy0.8.2增

加的Keepalived功能,它修正了以前MySQL Proxy容易死掉的Bug,建议大家开启此功能。

完整的mysql-proxy配置文件/etc/mysql-proxy.cnf如下:

[mysql-proxy]

admin-username=root

admin-password=123456

admin-lua-script=/usr/local/lib/admin.lua

proxy-read-only-backend-addresses=192.168.2.115

proxy-backend-addresses=192.168.2.117

proxy-lua-script=/usr/local/lib/rw-splitting.lua

log-file=/var/log/mysql-proxy.log

log-level=debug

daemon=true

keepalive=true

(2)给用户授权

在Master/Slave建立一个测试用户,因为以后客户端发送的SQL都是通过mysql-proxy服

务器来转发,所以要确保可以从mysql-proxy服务器上登录MySQL主从库,分别在主机

MySQL和从机MySQL上执行如下命令。

主机MySQL上执行命令如下:

grant all privileges on *.* to ‘test‘@‘192.168.2.117‘ identified by ‘test‘ with grant option;

从机MySQL上执行命令如下:

grant all privileges on *.* to ‘test‘@‘192.168.2.115‘ identified by ‘test‘ with grant option;

(3)测试

做完此步就可以在MySQL Proxy机器上进行测试,命令如下所示:

/usr/local/mysql-proxy/bin/mysql-proxy -P 192.168.2.112:3306

--defaults-file=/etc/mysql-proxy.cnf

我们监测MySQL Proxy的日志,出现如下字样时表示MySQL Proxy已成功启动(注意之

前要成功启动117和115上的MySQL程序),命令显示结果如下所示:

3)配置文件的权限问题。

建议以配置文件的形式启动,注意配置文件必须是660权限,否则无法启动。如果有多

个Slave,proxy-read-only-backend-addresses参数可以配置多个以逗号分隔的IP:Port从库

列表。



利用DenyHosts工具和脚本来防止SSH暴力破解

1)判断系统安装的sshd是否支持tcp_wrappers(默认都支持),命令如下:

ldd /usr/sbin/sshd | grep libwrap.so.0

2)判断默认安装的Python版本,命令如下:

1)安装DenyHosts。

# cd /usr/local/src

# wget http://jaist.dl.sourceforge.net/sourceforge/denyhosts/DenyHosts-2.6.tar.gz

# tar zxf DenyHosts-2.6.tar.gz

# cd DenyHosts-2.6

# python setup.py install


程序脚本自动安装到/usr/share/denyhosts。

库文件自动安装到/usr/lib/python2.3/site-packages/DenyHosts。

denyhosts.py自动安装到/usr/bin。

2)设置启动脚本,命令如下所示:

# cd /usr/share/denyhosts/

# cp daemon-control-dist daemon-control

# chown root daemon-control

# chmod 700 daemon-control

# grep -v "^#" denyhosts.cfg-dist > denyhosts.cfg

# vim denyhosts.cfg

我们可以根据自己的需要对文件denyhosts.cfg进行相应的修改,如下所示:

SECURE_LOG = /var/log/secure

上述代码表示RedHat/CentOS系统中安全日志的文件位置。

其他版本的Linux请根据denyhosts.cfg-dist内的提示进行选择。

PURGE_DENY = 30m

上述代码表示过多久后清除。

DENY_THRESHOLD_INVALID = 1

上述代码表示允许无效用户(/etc/passwd未列出)登录失败的次数。

DENY_THRESHOLD_VALID = 5

上述代码表示允许有效(普通)用户登录失败的次数。

DENY_THRESHOLD_ROOT = 3

上述代码表示允许root登录失败的次数。

HOSTNAME_LOOKUP=NO

上述代码表示是否做域名反解。

3)启动DenyHosts工具,命令如下:

/usr/share/denyhosts/daemon-control start

如果要使DenyHosts每次重启后自动启动还需进行如下设置:

# cd /etc/init.d

ln -s /usr/share/denyhosts/daemon-control denyhosts

chkconfig --add denyhosts

chkconfig --level 345 denyhosts on

然后就可以启动了,启动命令如下:

service denyhosts start

DenyHosts配置文件的语法如下:

SECURE_LOG = /var/log/secure

这里,SSH日志文件是根据这个文件来判断非法IP的。

HOSTS_DENY = /etc/hosts.deny

这是控制用户登录的文件。

PURGE_DENY = 5m

上述代码表示要过多久后清除已经禁止的IP,这个可根据具体时间而定。

BLOCK_SERVICE = sshd

上述代码表示禁止的服务名。

DENY_THRESHOLD_INVALID = 1

上述代码表示允许无效用户失败的次数。

DENY_THRESHOLD_VALID = 10

上述代码表示允许普通用户登录失败的次数。

DENY_THRESHOLD_ROOT = 5

上述代码表示允许root登录失败的次数。

HOSTNAME_LOOKUP=NO

上述代码表示是否做域名反解。

DAEMON_LOG = /var/log/denyhosts

这是自己的日志文件。

ADMIN_EMAIL = yuhongchun027@163.com

这是管理员邮件地址,它会给管理员发邮件,CentOS 5.5默认开启sendmail邮件服务




本文出自 “醉寒江” 博客,请务必保留此出处http://cjlozbg.blog.51cto.com/3513565/1733239

Linux 学习

标签:学习linux

原文地址:http://cjlozbg.blog.51cto.com/3513565/1733239

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!