最近做了一些LVS配置和方案的验证实验,将过程中用到的一些配置、工具和具体的解决方案记录一下。使用DR模式。验证一种不中断业务的RealServer升级或者重启方案。

网络规划:

节点 IP地址
ceph1(RealServer1) 172.16.0.114
ceph2(RealServer2) 172.16.0.115
ceph4(DirectServer) 172.16.0.113
客户端:Win 8.1 172.16.0.100
一、配置
 

DirectServer:

vip=172.16.0.113
r1ip=172.16.0.114
r2ip=172.16.0.115
port=$1
if [ -z "$port" ]
then
        port=2100
fi

ipvsadm -C
ipvsadm -A -t ${vip}:${port} -s wrr
ipvsadm -a -t ${vip}:${port} -r ${r1ip}:${port} -g
ipvsadm -a -t ${vip}:${port} -r ${r2ip}:${port} -g

RealServer:

#!/bin/sh
VIP=172.16.0.113
BROADCAST=172.16.0.255 #vip's broadcast

Usage ()
{
        echo "Usage:`basename $0` (start|stop)"
exit 1
}

if [ $# -ne 1 ];then
        Usage
fi

case $1 in
start)
        echo "reparing for Real Server"
        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
        /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $BROADCAST up
        /sbin/route add -host $VIP dev lo:0
;;
stop)
        /sbin/ifconfig lo:0 down
        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 "stop Real Server"
;;
*)
        Usage
esac
上述配置是标准的DR模式的配置。

二、工具

RealServer上面提供可以监听固定端口,并接受客户端从TCP连接发送过来的数据的TCP Server服务,将接收到的数据打印到屏幕,并回复当前节点信息给客户端,让客户端能够区分具体的服务是由哪个RealServer提供的。

服务的代码如下:
 
package com;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;

publicclass Server
{

publicstaticvoid main(String[] args) throws IOException
    {

if (args.length < 1)
        {
            System.out.println("arguments error!\nusage: java -jar tcpser.jar server port");
            System.exit(0);
        }

int serverport = Integer.parseInt(args[0]);

        System.out.println("==============TCP SERVER==============");

        ServerSocket server = null;
try
        {
            server = new ServerSocket(serverport);
            System.out.println("Listening Port is " + server.getLocalPort() + "...");
while (true)
            {
                Socket connectedCli = server.accept();
                System.out.println("a new client: " + connectedCli.getInetAddress() + ":" + connectedCli.getPort());
new DataProcesser(connectedCli).start();
            }
        }
catch (Exception e)
        {
            e.printStackTrace();
        }
finally
        {
if (server != null)
            {
                server.close();
            }
        }
    }
}
package com;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;

publicclass DataProcesser extends Thread
{
private Socket cli;

public DataProcesser(Socket clientsocket)
    {
        cli = clientsocket;
    }

    @Override
publicvoid run()
    {
        BufferedReader reader = null;
        BufferedWriter writer = null;
try
        {
            reader = new BufferedReader(new InputStreamReader(cli.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(cli.getOutputStream()));
while (true)
            {
                String receivedString = reader.readLine();
if (receivedString != null)
                {
                    System.out.println(cli.getInetAddress() + ":" + cli.getPort() + " " + receivedString);
                    String hostname = InetAddress.getLocalHost().getHostName();
                    writer.write("it's from the host: " + hostname);
                    writer.write("\n");
                    writer.flush();
                }
if ("shutdown".equals(receivedString))
                {
break;
                }
            }

        }
catch (Exception e)
        {
            e.printStackTrace();
        }
finally
        {
if (reader != null)
            {
try
                {
                    reader.close();
                }
catch (Exception e2)
                {
                    e2.printStackTrace();
                }
            }

if (cli != null)
            {
try
                {
                    cli.close();
                }
catch (Exception e2)
                {
                    e2.printStackTrace();
                }
            }

        }
    }
}
 
将上面的服务端代码导出为jar包:server.jar,部署到两台RealServer上面:
 
启动信息如下:
 
root@ceph1:~# java -jar server.jar 2100
==============TCP SERVER==============
Listening Port is 2100...
a new client: /172.16.0.100:49314
a new client: /172.16.0.100:49316
 
 
 

客户端工具:

客户端工具直接使用开源的sockettest工具:http://sourceforge.net/projects/sockettest/

三、验证RealServer的一种安全退出机制

当IPVS正在接受业务时,IPVS将请求按照指定的规则分发给两个节点。当需要重启某一个业务节点时,会存在两个问题:1、正在执行的业务会被中断,如:TCP上面正在做数据交互会中断;2、如何确保不再有新的业务下发到需要重启的节点上面,如果采用LVS服务器将业务节点踢出,那么也会中断已经接入的请求。

其中问题1,一般来说需要服务本身去做判断,判断业务全部完成后,再做下电重启等处理。

对于问题2,需要寻求一种安全的移除业务节点的方案。既不能影响已经接入点业务请求,又不能让新的业务再下发到该节点上面。考虑使用带权重的轮询方式,将某个业务节点的权重设置为0,这样该节点就不会再有业务。但是节点并没有从lvs的配置中删除掉。因此已有的业务不会受影响。

结合客户端工具,和服务端的长连接支持方式,最终很轻松即可验证上述方案,验证步骤:

1、配置好DirectServer,两条分发记录到ceph1和ceph2节点;
2、配置RealServer,启动TCP Server服务;
3、在Windows上面使用sockettest工具分别与LVS的VIP建立长连接;

4、在LVS上面修改配置:
 
ipvsadm -e -t 172.16.0.113:2100 -r 172.16.0.114:2100 -w 0
 

5、观察之前已经跟114节点建立的连接是否断开,是否还能继续发送和接受数据。验证结果为:连接不会断开,该连接还能继续处理数据。
6、DirectServer接受到的新的请求,是否还是会转给114节点。验证结果为:0权重生效,所有的业务都只发送到另外一个业务节点上面。
7、到此整个验证结束。

对于RealServer维护期间,需要精细化的维护业务不受损,可以使用如上方案来实现。

一些LVS实验配置、工具和方案的更多相关文章

  1. LVS/DR 配置

    LVS/DR 配置 实验环境 三台主机:Linux Centos 6.4 32位 调度器Director:192.168.1.160(公网IP).192.168.1.100(VIP) HTTP真实服务 ...

  2. LVS/NAT 配置

    LVS/NAT 配置 实验环境 三台主机:Linux Centos 6.4 32位 调度器Director:192.168.1.160(内网IP).192.168.2.20(公网IP) HTTP真实服 ...

  3. 物联网框架ServerSuperIO(SSIO)更新、以及增加宿主程序和配置工具,详细介绍

    一.更新内容 1.修改*Server类,以及承继关系.2.增加IRunDevice的IServerProvider接口继承.3.修复增加COM设备驱动可能造成的异常.4.修复网络发送数据可能引发的异常 ...

  4. 安装LVS安装LVS和配置LVS的工作比较繁杂

    安装LVS安装LVS和配置LVS的工作比较繁杂,读者在配置的过程中需要非常细心和耐心.在本节我们将对其进行详细地介绍.主要包括如下几个核心步骤:1.获取支持LVS的内核源代码如果读者需要使用LVS,需 ...

  5. centos LB负载均衡集群 三种模式区别 LVS/NAT 配置 LVS/DR 配置 LVS/DR + keepalived配置 nginx ip_hash 实现长连接 LVS是四层LB 注意down掉网卡的方法 nginx效率没有LVS高 ipvsadm命令集 测试LVS方法 第三十三节课

    centos   LB负载均衡集群 三种模式区别 LVS/NAT 配置  LVS/DR 配置  LVS/DR + keepalived配置  nginx ip_hash 实现长连接  LVS是四层LB ...

  6. CentOS 7网络配置工具

    CentOS 7网络配置工具 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.网卡命名机制 CentOS 6之前,网络接口使用连续号码命名:eth0.eth1等,当增加或删除网卡 ...

  7. lvs+keepalived做高可用方案1

    本文我们主要讲解的是LVS通过keepalived来实现负载均衡和高可用,而不是我们第三篇文章介绍的通过手动的方式来进行配置.通过脚本的方式来显示RS节点的健康检查和LVS的故障切换.此文会通过一个实 ...

  8. CYQ.Data.Orm.DBFast 新增类介绍(含类的源码及新版本配置工具源码)

    前言: 以下功能在国庆期就完成并提前发布了,但到今天才有时间写文介绍,主要是国庆后还是选择就职了,悲催的是上班的地方全公司都能上网,唯独开发部竟不让上网,是个局域网. 也不是全不能上,房间里有三台能上 ...

  9. SharePoint 2013 表单认证使用ASP.Net配置工具添加用户

    前 言 上面一篇博客,我们了解到如何为SharePoint 2013配置表单身份认证,但是添加用户是一个麻烦事儿:其实,我们还可以用Asp.Net的配置工具,为SharePoint 2013添加表单用 ...

随机推荐

  1. [技术]浅谈OI中矩阵快速幂的用法

    前言 矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中,矩阵的运算是数值分析领域的重要问题. 基本介绍 (该部分为入门向,非入门选手可以跳过) 由 m行n列元素排列成的矩形阵列.矩阵里的 ...

  2. java中Comparable和Comparator两种比较器的区别

    Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较 ...

  3. python enumerate 枚举函数用法

    enumerate()说明 enumerate()是python的内置函数 enumerate在字典上是枚举.列举的意思 对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enum ...

  4. 重新认识alias:通过alias让rm更安全

    rm的悲剧总是发生在不经意之间,所以无论是在shell脚本中还是交互式bash环境下,执行rm命令时总应该三思三思再三思.也因此,很多人想尽办法防止文件误删除,方法也各种各样. 1.1.1 alias ...

  5. 使用Openfire配置安卓客户端聊天服务器

    Openfire是一种即时通信服务器,采用开放的XMPP协议,您可以使用各种支持XMPP协议的IM客户端软件登陆服务. Openfire 采用Java开发,开源的实时协作(RTC)服务器基于XMPP( ...

  6. HTML——CSS的基础语法2

    一.盒模型 1-1.什么是盒模型? HTML5盒模型包括:内容(content).填充(padding.也叫做内边距).边框(border).边界(margin,也叫做外边距). 这些属性我们可以用日 ...

  7. windows重装后,不重装oracle,直接恢复数据库

    windows重装后,不重装oracle,让原来的库可用的问题环境: windows 7/Oracle 11.2.0.1.0  64位 原来的Oracle安装在D盘.重装只格式化了C盘 1.修改注册表 ...

  8. 深入解析Javascript异步编程

    这里深入探讨下Javascript的异步编程技术.(P.S. 本文较长,请准备好瓜子可乐 :D) 一. Javascript异步编程简介 至少在语言级别上,Javascript是单线程的,因此异步编程 ...

  9. 谈谈Golang中goroutine的调度问题

    goroutine的调度问题,同样也是我之前面试的问题,不过这个问题我当时并不是很清楚,回来以后立马查阅资料,现整理出来备忘. 有一些预备知识需要说明,就是操作系统中的线程.操作系统中的线程分为两种: ...

  10. k-临近算法学习

    本章主要内容: k-临近算法是通过对象本身的特征将对象划分到某一类型中去,比如电影中的题材类型的分类是,可能就会考虑到电影中出现的镜头出现的次数的多少将电影划分为动作电影,爱情电影等等,本次的随笔参考 ...