最近做了一些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. 从零开始编写动态库文件Makefile,C++版

    这篇文章前,假设你已经看过<跟我一起写Makefile(一)>,陈皓写的那个. 对现有的一个C++动态库文件和调用程序,分别编写Makefile文件,从零开始,花了四天时间才搞清楚一半,生 ...

  2. ARP与RARP协议及arp脚本

    1.什么是ARP与RARP协议 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议. 在⽹络通讯时,源主机的应⽤程序知道 ...

  3. 常用类:String,StringBuffer,StringBuilder

    String String类被final修饰符修饰,所以不能将其进行继承,所有对它的改变都要重新创建一个新的地址 1.String的构造器 String() String(byte []bytes)/ ...

  4. IDEA教程(转载)

    https://github.com/judasn/IntelliJ-IDEA-Tutorial

  5. Three.js使用局部纹理更新

    THREE.js开发的应用运行在iphone5下发现有些时候会崩溃,跟了几天发现是因为Sprite太多频繁更新纹理占用显存导致的.通常解决纹理频繁更新问题就要用到one draw all方法,放到纹理 ...

  6. registry key 'Java Runtime Environment' has value'1.8',but '1.7' is requaired(转)

    当更新jdk后,运行java命令可能会提示类似这样registry key 'Java Runtime Environment' has value'1.8',but '1.7' is requair ...

  7. 【JBoss】Linux下JBoss服务器"Too many open files"的解决方法

    linux中,每个socket连接都使用文件描述符进行标识,文件描述符属于系统资源,存在使用上的限制:缺省情况下JBoss能使用的最大描述符数是系统默认的最大文件描述符数(通过命令ulimit -H ...

  8. APUE 3 -- 信号(signal)<I> :概念

    信号可以理解成一种软件中断.他提供了一种异步处理事件的方式.每个信号都有一个与之对应的信号名,这些信号名都带有SIG前缀,如:SIGABRT,SIGALARM.头文件signal.h 中定义了所有的信 ...

  9. Java入门——学会使用API

    API是什么? API(Application Programming Interface)就是别人写的代码使用说明书. 下面是中文版API的使用具体截图. 1.左上角有个显示(图中"隐藏& ...

  10. vue.js拓展篇(8):测试开发与调试

    内容 第15章:测试开发与调试 任何实际项目的开发,除了功能性代码的完成,规范的开发流程和严谨的测试都是不可或缺的.合理使用工具将事半功倍. 1.ESLint ESLint是Lint语法检查工具,避免 ...