`
收藏列表
标题 标签 来源
keepalived安装配置 http http://www.tuicool.com/articles/2qAjUf
cd /usr/local

1、下载安装包并解压

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

tar zxvf keepalived-1.2.13.tar.gz 

2、编译安装

cd keepalived-1.2.13

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

[如果出现configure: error:

     !!! OpenSSL is not properly installed on your system. !!!

则需要先安装openssl和openssl-devel, yum install openssl openssl-devel]

make 

sudo make install

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

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

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

mkdir /etc/keepalived

cd /etc/keepalived

sudo cp /usr/local/keepalived/etc/keepalived/keepalived.conf ./

3、将keepalived添加到开机启动服务中,并进行测试

chkconfig keepalived on

chkconfig --list | grep keepalived

sudo service keepalived restart

修改keepalived.conf文件(smtp_server 改成localhost, router_id变成NodeMaster, virtual_ipaddress 改成你自己网段内且没有被使用的如10.1.xx.xx/24格式的.

运行ip addr查看vip

运行ping命令访问vip。

4、在从服务器上进行步骤1-3

注意:router_id变成NodeBackup,priority变成99, state变成BACKUP,主从服务器要在同一个网段内。








1.安装LVS前系统需要安装popt-static,kernel-devel,make,gcc,openssl-devel,lftp,libnl*,popt*

 #yum –y install popt-static,kernel-devel,make,gcc,openssl-devel,lftp,libnl*,popt*
 #ln -s /usr/src/kernels/2.6.32-431.17.1.el6.x86_64/ /usr/src/linux
 #tar -zxvf ipvsadm-1.26.tar.gz
 #cd ipvsadm-1.26
 #make && make install
2.安装keepalived

 #wget http://www.keepalived.org/software/keepalived-1.2.13.tar.gz
 #tar –zxvf keepalived-1.2.13.tar.gz
 #cd keepalived-1.2.13
 #./configure
 #make && make install
 ######### 将keepalived做成启动服务,方便管理##########
 # cp /usr/local/etc/rc.d/init.d/keepalived /etc/init.d/
 # cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
 # mkdir /etc/keepalived/
 # cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
 # cp /usr/local/sbin/keepalived /usr/sbin/
 # service keepalived start | stop
3.开启路由转发

1 #vi /etc/sysctl.conf
2 #sysctl –p
4.配置keepalived

1 #vi /etc/keepalived/keepalived.conf
keepalive.conf具体如下:

 ! Configuration File for keepalived
 
 global_defs {
    notification_email {
       382566697@qq.com
    }
    smtp_connect_timeout 30
    router_id LVS_MASTER #备份服务器上将MASTER改为BACKUP 
 }
 vrrp_sync_group KEEPALIVED_LVS {  
    group {  
        KEEPALIVED_LVS_MASTER
    }  
}  
   
 vrrp_instance  KEEPALIVED_LVS_MASTER  {
     state MASTER #备份服务器上将MASTER改为BACKUP 
     interface eth0  #该网卡名字需要查看具体服务器的网口
     lvs_sync_daemon_interface eth2
     virtual_router_id 51
     priority 100 # 备份服务上将100改为90
     advert_int 1
     authentication {
         auth_type PASS
         auth_pass 1111
     }
     virtual_ipaddress {
         192.168.0.209
          #(如果有多个VIP,继续换行填写.)
     }
 }
 
 virtual_server 192.168.0.209 80 {
     delay_loop 6   #(每隔6秒查询realserver状态)
     lb_algo rr   #(rr 算法)
     lb_kind DR      #(Direct Route)
     nat_mask 255.255.255.0
     persistence_timeout 0   #会话保存时长(秒),0表示不使用stickyness会话    
     protocol TCP    #(用TCP协议检查realserver状态)
 
     real_server 192.168.0.212 80 {
         weight 1   #(权重)
         TCP_CHECK {
             connect_timeout 10    #(10秒无响应超时)
             nb_get_retry 3
             delay_before_retry 3
             connect_port 80
         }
      }
      real_server 192.168.0.227 80 {
         weight 1
         TCP_CHECK {
             connect_timeout 10 #连接超时时间  
             nb_get_retry 3    #重试次数  
             delay_before_retry 3 #每次重试前等待延迟时间 
             connect_port 80
         }
      }
     
 }
需要注意的是{前面需要有空格,我在配置时TCP_CHECK没有空格导致无法找到real_server   eth2为机器网卡名称

RS真实服务器的脚本
#!/bin/bash
SNS_VIP=172.16.62.100

/etc/rc.d/init.d/functions

case "$1" in

start)
ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP #netmask 255.255.255.255注意
/sbin/route add -host $SNS_VIP dev lo:0
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p > /dev/null 2>&1
echo "RealServer started!"

;;

stop)
ifconfig lo:0 down
/sbin/route del $LVS_VIP > /dev/null 2>&1
echo "0" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer stopped!"

;;
*)
echo "Usage: $0 {start | stop}"
exit 1

esac
exit 0





3,发送邮件的perl脚本sendmail.pl内容如下:
vrrp_sync_group KEEPALIVED_LVS {  
    group {  
        KEEPALIVED_LVS_JIM2
    }  
	notify_master /etc/keepalived/sendmail.pl
}
注意主备发送邮件的标题是不一致的,只要你能识别漂移IP在哪台服务器上即可。
#!/usr/bin/perl -w
use Net::SMTP_auth;
use strict;
my $mailhost = 'smtp.163.com';
my $mailfrom = 'test@163.com';
my @mailto   = ('123456@139.com');
my $subject  = 'keepalived up on backup';
my $text = "正文\n第二行位于此。";  
my $user   = 'test@163.com';
my $passwd = 'xxxxxxx';
&SendMail();
##############################
# Send notice mail
##############################
sub SendMail() {
    my $smtp = Net::SMTP_auth->new( $mailhost, Timeout => 120, Debug => 1 )
      or die "Error.\n";
    $smtp->auth( 'LOGIN', $user, $passwd );
    foreach my $mailto (@mailto) {
        $smtp->mail($mailfrom);
        $smtp->to($mailto);
        $smtp->data();
        $smtp->datasend("To: $mailto\n");
        $smtp->datasend("From:$mailfrom\n");
        $smtp->datasend("Subject: $subject\n");
        $smtp->datasend("\n");
        $smtp->datasend("$text\n\n"); 
        $smtp->dataend();
    }
    $smtp->quit;
}
说明:
a、由于keeplived自带的发送邮件机制是个鸡肋,如果本地不启动25端口就无法实现邮件发送,就琢磨着能不能通过自定义脚本来实现,真的是很幸运,就采用了认证的方式。
b、其他的配置说明就不详细讲了,网上很多资料。
4,测试keepalived
主备调度器都开启80端口,两台服务器上的测试内容不一致,这样更方便测试。

##########################

#所需安装模块

#use Net::SMTP

#Authen::SASL

##########################

#$stmp->auth('user','pass');

#大部分SMTP服务器为了防止 spam /垃圾邮件,就需要用户验证身份。

#此方法需要另外安装模块:Authen::SASL, 此模块可能系统不自带

##########################

#Debug => 1

#此段代码用于测试之用,所以开启了Debug,一般测试一次完毕,正式使用的话会关闭它。

注:可在命令行界面直接执行:/etc/keepalived/sendmail.pl,看看能否发送邮件成功,如果失败的话则需要安装Net::SMTP_auth模块

安装方法:

yum -y install perl-CPAN
cpan Net::SMTP_auth
http协议之 文件上传数据包 http http://www.cnblogs.com/linjiqin/archive/2011/11/09/2242579.html
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.util.Map;

/**
 * 上传文件到服务器
 * 
 * @author Administrator
 *
 */
public class SocketHttpRequester {
    /**
     * 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:
     *   <FORM METHOD=POST ACTION="http://192.168.1.101:8083/upload/servlet/UploadServlet" enctype="multipart/form-data">
            <INPUT TYPE="text" NAME="name">
            <INPUT TYPE="text" NAME="id">
            <input type="file" name="imagefile"/>
            <input type="file" name="zip"/>
         </FORM>
     * @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.iteye.cn或http://192.168.1.101:8083这样的路径测试)
     * @param params 请求参数 key为参数名,value为参数值
     * @param file 上传文件
     */
    public static boolean post(String path, Map<String, String> params, FormFile[] files) throws Exception{     
        final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
        final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志
        
        int fileDataLength = 0;
        for(FormFile uploadFile : files){//得到文件类型数据的总长度
            StringBuilder fileExplain = new StringBuilder();
             fileExplain.append("--");
             fileExplain.append(BOUNDARY);
             fileExplain.append("\r\n");
             fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
             fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
             fileExplain.append("\r\n");
             fileDataLength += fileExplain.length();
            if(uploadFile.getInStream()!=null){
                fileDataLength += uploadFile.getFile().length();
             }else{
                 fileDataLength += uploadFile.getData().length;
             }
        }
        StringBuilder textEntity = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据
            textEntity.append("--");
            textEntity.append(BOUNDARY);
            textEntity.append("\r\n");
            textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
            textEntity.append(entry.getValue());
            textEntity.append("\r\n");
        }
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString().getBytes().length + fileDataLength +  endline.getBytes().length;
        
        URL url = new URL(path);
        int port = url.getPort()==-1 ? 80 : url.getPort();
        Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);           
        OutputStream outStream = socket.getOutputStream();
        //下面完成HTTP请求头的发送
        String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
        outStream.write(requestmethod.getBytes());
        String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";
        outStream.write(accept.getBytes());
        String language = "Accept-Language: zh-CN\r\n";
        outStream.write(language.getBytes());
        String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "\r\n";
        outStream.write(contenttype.getBytes());
        String contentlength = "Content-Length: "+ dataLength + "\r\n";
        outStream.write(contentlength.getBytes());
        String alive = "Connection: Keep-Alive\r\n";
        outStream.write(alive.getBytes());
        String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
        outStream.write(host.getBytes());
        //写完HTTP请求头后根据HTTP协议再写一个回车换行
        outStream.write("\r\n".getBytes());
        //把所有文本类型的实体数据发送出来
        outStream.write(textEntity.toString().getBytes());           
        //把所有文件类型的实体数据发送出来
        for(FormFile uploadFile : files){
            StringBuilder fileEntity = new StringBuilder();
             fileEntity.append("--");
             fileEntity.append(BOUNDARY);
             fileEntity.append("\r\n");
             fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
             fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
             outStream.write(fileEntity.toString().getBytes());
             if(uploadFile.getInStream()!=null){
                 byte[] buffer = new byte[1024];
                 int len = 0;
                 while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){
                     outStream.write(buffer, 0, len);
                 }
                 uploadFile.getInStream().close();
             }else{
                 outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
             }
             outStream.write("\r\n".getBytes());
        }
        //下面发送数据结束标志,表示数据已经结束
        outStream.write(endline.getBytes());
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        if(reader.readLine().indexOf("200")==-1){//读取web服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败
            return false;
        }
        outStream.flush();
        outStream.close();
        reader.close();
        socket.close();
        return true;
    }
    
    /**
     * 提交数据到服务器
     * @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080这样的路径测试)
     * @param params 请求参数 key为参数名,value为参数值
     * @param file 上传文件
     */
    public static boolean post(String path, Map<String, String> params, FormFile file) throws Exception{
       return post(path, params, new FormFile[]{file});
    }
}
Global site tag (gtag.js) - Google Analytics