LVS(Linux Virtual Server)是什么?国人章文嵩博士开源的四层反向代理服务器

HAProxy简介

单节点直接访问

HAProxy是用C语言开发的,是一款开源的自由软件。它具备高可用性、负载均衡功能,并能代理TCP和HTTP应用程序。在负载均衡速度和并发处理能力方面,HAProxy比Nginx更胜一筹。众多大型网站架构中,HAProxy常被选用,确保网站高效运作。

多节点访问

负载均衡访问

单点问题应对

网关+负载均衡

负载均衡器有单一故障点,一旦发生故障,整个系统可能受到影响。为了防止这种情况,我们可以使用Nginx搭配Keepalived或HAproxy搭配Keepalived的方案。这样的组合能在负载均衡器出现问题时快速切换,确保系统持续运行,降低因故障点造成的损失。

动静分离

Nginx集群

网关鉴权设置

Nginx TCP连接传输

Nginx与LVS对比

直接将所有流量导入server存在安全风险。为了解决这个问题,我们可以在流量进入server之前,先进行一次身份验证,这个环节就是网关。为了防止出现故障点,网关应以集群模式运行。网关的验证功能可以过滤掉非法流量,增强系统的安全保障。

负载均衡转发

LVS主从

设备接收到客户端的SYN请求,便运用负载均衡算法选择最合适的服务器。随后,它将报文中的目标IP地址更改为后端服务器的IP,并直接进行转发。在某些特定情况下,为了确保服务器能够准确回包,设备还会对报文原有的源地址进行相应调整。通过这种方式,可以实现流量在各服务器之间的合理分配。

LVS集群

Nginx集群

静态资源部署

流量大时,将静态资源部署在CDN上是个不错的选择。CDN会自动挑选离用户最近的节点来提供资源。若不利用CDN,服务器在高流量下可能承受不住,进而影响用户的使用体验。采用CDN进行资源分发,能有效提高网站的响应速度。

引入CDN

架构部署选择

流量较少时,使用多台Nginx是可行的。然而,LVS作为Linux内核模块,运行于内核层,而Nginx则运行在用户层,相对较重。因此,在性能和稳定性方面,Nginx不及LVS。所以,通常采用LVS与Nginx结合的部署模式,以实现更佳的性能表现。

public interface LoadBalance {
    /**
     * 路由
     *
     * @param serverMap 服务列表
     * @return 选择到的一个服务
     */
    String route(Map<String, Integer> serverMap);
}

请求分配算法

public class IpMap {
    /**
     * 待路由的Ip列表,Key代表Ip,Value代表该Ip的权重
     */
    public static Map<String, Integer> serverWeightMap = new HashMap<>();
    static {
        serverWeightMap.put("192.168.1.100", 1);
        serverWeightMap.put("192.168.1.101", 1);
        serverWeightMap.put("192.168.1.102", 2);
        serverWeightMap.put("192.168.1.103", 2);
        serverWeightMap.put("192.168.1.104", 3);
    }
}

通过访问URL的哈希值来分配请求,可以让每个URL都指向同一个后端服务器。这种方法在后端服务器进行缓存时特别有用。它能确保缓存得到充分利用,降低重复计算的需求。例如,大型电商网站的商品页面缓存就是利用这种方法来提升响应速度的。

public class LoadBalanceUtil {
    private static String requestIp;
    /**
     * 统计路由结果
     *
     * @param routingMap 记录路由结果的Map
     */
    public static void countRoutingMap(Map<String, Integer> routingMap) {
        // 路由总体结果
        for (Map.Entry<String, Integer> entry : routingMap.entrySet()) {
            System.out.println("IP:" + entry.getKey() + ",次数:" + entry.getValue());
        }
    }
    /**
     * 模拟路由调用
     *
     * @param loadBalance  负载均衡策略
     * @param requestCount 请求次数
     * @return 负载均衡的记录
     */
    public static Map<String, Integer> imitateRouting(LoadBalance loadBalance, int requestCount) {
        Map<String, Integer> serverMap = new ConcurrentHashMap<>(IpMap.serverWeightMap.size());
        for (int i = 0; i < requestCount; i++) {
            String server = loadBalance.route(IpMap.serverWeightMap);
            Integer count = serverMap.getOrDefault(server, 0);
            serverMap.put(server, ++ count);
        }
        return serverMap;
    }
    /**
     * 获取Ip地址
     *
     * @return IP地址
     */
    public static String getIp() {
        try {
            InetAddress ip4 = Inet4Address.getLocalHost();
            return ip4.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取请求的 Ip地址 (模拟)
     *
     * @return IP地址
     */
    public static String getRequestIp() {
        return requestIp;
    }
    /**
     * 设置请求的IP 模拟
     *
     * @param requestIp 请求IP
     */
    public static void setRequestIp(String requestIp) {
        LoadBalanceUtil.requestIp = requestIp;
    }
}

缓存处理问题

public class RandomLoadBalance implements LoadBalance {
    /**
     * 路由
     *
     * @param serverMap 服务列表
     * @return 选择到的一个服务
     */
    @Override
    public String route(Map<String, Integer> serverMap) {
        // 复制遍历用的集合,防止操作中集合有变更
        List<String> serverList = new ArrayList<>(serverMap.size());
        serverList.addAll(serverMap.keySet());
        // 随机数随机访问
        int randomInt = new Random().nextInt(serverList.size());
        return serverList.get(randomInt);
    }
}

服务器一旦出现故障,与之关联的对象缓存便会失效。这时,需将故障服务器的缓存清除,导致缓存服务器总数减少至N减1台。同时,映射计算方式也将调整为hash(object)对(N - 1)取余。这一变动将扰乱既有的缓存策略,进而对系统性能造成影响。

/**
 * 测试 随机
 */
@Test
public void testRandom() {
    Map<String, Integer> routingMap = LoadBalanceUtil.imitateRouting(new RandomLoadBalance(), 20000);
    // 统计路由结果
    LoadBalanceUtil.countRoutingMap(routingMap);
}

一致性哈希算法

IP:192.168.1.100,次数:3959
IP:192.168.1.101,次数:4015
IP:192.168.1.102,次数:4017
IP:192.168.1.103,次数:4009
IP:192.168.1.104,次数:4000

为了克服数据分布不均的问题,一致性哈希算法采用了虚拟节点的方法。这种方法会为每个服务节点生成多个哈希值,然后在相应的位置放置一个代表该节点的虚拟节点。这样做可以使数据分布更加均衡,从而提升系统的整体性能。

public class RoundRobinLoadBalance implements LoadBalance {
    private static volatile Integer index = 0;
    /**
     * 路由
     *
     * @param serverMap 服务列表
     * @return 选择到的一个服务
     */
    @Override
    public String route(Map<String, Integer> serverMap) {
        // 复制遍历用的集合,防止操作中集合有变更
        List<String> serverList = new ArrayList<>(serverMap.size());
        serverList.addAll(serverMap.keySet());
        synchronized (RoundRobinLoadBalance.class) {
            index++;
            if (index == serverList.size()) {
                index = 0;
            }
            return serverList.get(index);
        }
    }
}

虚拟节点示例

/**
 * 测试 轮询
 */
@Test
public void testRoundRobin() {
    Map<String, Integer> routingMap = LoadBalanceUtil.imitateRouting(new RoundRobinLoadBalance(), 20000);
    // 统计路由结果
    LoadBalanceUtil.countRoutingMap(routingMap);
}

为每台服务器设定三个虚拟节点,具体为“Node A#1”“Node A#2”“Node A#3”和“Node B#1”“Node B#2”“Node B#3”,并计算它们的哈希值。这样得到六个虚拟节点。这些节点能更精确地分配数据,有助于降低数据不平衡现象。

IP:192.168.1.100,次数:4000
IP:192.168.1.101,次数:4000
IP:192.168.1.102,次数:4000
IP:192.168.1.103,次数:4000
IP:192.168.1.104,次数:4000

在实际的架构部署过程中,众人对哪种负载均衡技术更偏爱?不妨在评论区留下您的看法,同时别忘了点赞和转发这篇文章!

public class WeightRandomLoadBalance implements LoadBalance {
    /**
     * 路由
     *
     * @param serverMap 服务列表
     * @return 选择到的一个服务
     */
    @Override
    public String route(Map<String, Integer> serverMap) {
        Map<String, Integer> tempMap = new HashMap<>(serverMap.size());
        tempMap.putAll(serverMap);
        List<String> serverList = new ArrayList<>();
        for (String server : tempMap.keySet()) {
            // 按照权重比例添加服务节点(权重高,节点数量多)
            for (int i = 0; i < serverMap.get(server); i++) {
                serverList.add(server);
            }
        }
        int randomInt = new Random().nextInt(serverList.size());
        return serverList.get(randomInt);
    }
}

/**
 * 测试 加权随机
 */
@Test
public void testWeightRandom() {
    Map<String, Integer> routingMap = LoadBalanceUtil.imitateRouting(new WeightRandomLoadBalance(), 20000);
    // 统计路由结果
    LoadBalanceUtil.countRoutingMap(routingMap);
}

tp官方
TokenPocket是全球知名的数字货币多链钱包,支持比特币、以太坊、BNB、波场等多种公链和资产。在这里,你可以下载手机或桌面端的钱包,提交DApp和Token,参与Staking、挖矿、DeFi等多种增益方式
作者头像
tp官方正版下载创始人

tp官网

  • TokenPocket (TP Wallet)是一款全球领先的去中心化多链钱包,支持比特币/以太坊/波场/币安智能链等多种区块链资产管理,提供安全,私钥自持的数字货币存储和交易服务.下载TokenPocket官方钱包,轻松管理您的数字资产!
  • 版权声明:本站文章如无特别标注,均为本站原创文章,于2025-04-20,由tp官方正版下载发表,共 6344个字。
  • 转载请注明出处:tp官方正版下载,如有疑问,请联系我们
  • 本文地址:https://ylsfc.cn/tpzb/21.html
上一篇:负载均衡原理与应用:DNS与代理服务器如何实现高效网络流量分配
下一篇:如何联系tpWallet客服?官网支持、在线聊天和电子邮件详细指南

相关推荐