如何使用单例模式确保服务 “负载均衡” 的唯一性?

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: 如何通过 SingletonConstructor(单例对象构造器)快速地创建单例对象,在单进程应用中确保对象的唯一性至关重要!

说起单例模式,想必大家都不陌生,在创建型模式中应该是最常用的设计模式之一了。此处就不再过多叙述,可以查看《单例模式》的文章。

image.png

应用需求

某软件公司承接了一个服务器负载均衡(LB,Load Balance)软件的开发工作,该软件运行在一台负载均衡服务器上,可以将并发访问和数据流量分发到服务器集群中的多台设备上进行并发处理,提高了系统的整体处理能力,缩短了响应时间。由于集群中的服务器需要动态删减,且客户端请求需要统一分发,因此需要确保负载均衡器的唯一性,只能有一个负载均衡器来负责服务器的管理和请求的分发,否则将会带来服务器状态的不一致以及请求分配冲突等问题。

分析:对于上面的需求场景,问题的关键是如何确保 LB唯一性

单例模式设计服务器负载均衡器

接下来我们尝试使用【单例模式】设计服务器负载均衡器。

1、创建控制台应用程序

使用 vs 创建【控制台应用程序】,命名为:ConsoleApp1,或者使用 cli 命令:

dotnet new console -n ConsoleApp1

2、模拟 LB 创建类对象

using System.Collections;

namespace ConsoleApp1;

/// <summary>
/// 模拟负载均衡器
/// </summary>
internal class LoadBalancer
{
    //服务器集合
    private static readonly ArrayList? serverList = null;

    //静态构造函数
    static LoadBalancer()
    {
        serverList = new ArrayList();
    }

    //增加服务器
    public void AddServer(string server)
    {
        serverList?.Add(server);
    }

    //删除服务器
    public void RemoveServer(string server)
    {
        serverList?.Remove(server);
    }

    //使用Random类随机获取服务器
    public string GetServer()
    {
        int i = Random.Shared.Next(serverList.Count); //随机选一台服务器
        return serverList[i].ToString();
    }
}

3、构建单例对象构造器

namespace ConsoleApp1;

/// <summary>
/// 单例对象构造器
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonConstructor<T> where T : class, new()
{
    private static T? _Instance;
    private readonly static object _lockObj = new();

    /// <summary>
    /// 获取单例对象的实例
    /// </summary>
    /// <returns></returns>
    public static T GetInstance()
    {
        if (_Instance != null) return _Instance;
        lock (_lockObj)
        {
            if (_Instance == null)
            {
                var item = Activator.CreateInstance<T>();
                System.Threading.Interlocked.Exchange(ref _Instance, item);
            }
        }
        return _Instance;
    }
}

4、通过单例对象构造器创建 LB 实例对象

Main 方法中,添加如下代码:

static void Main(string[] args)
{
    // 1. 使用单例对象构造器(SingletonConstructor)创建 LB 实例对象
    var balancer1 = SingletonConstructor<LoadBalancer>.GetInstance();
    var balancer2 = SingletonConstructor<LoadBalancer>.GetInstance();
    var balancer3 = SingletonConstructor<LoadBalancer>.GetInstance();

    if (balancer1.Equals(balancer2) && balancer2.Equals(balancer3))
    {
        Console.WriteLine("服务器负载均衡器(LB)实例对象具有唯一性!");
    }

    for (int i = 0; i < 5; i++)
    {
        balancer1.AddServer($"Server {i + 1}");
    }

    for (int i = 0; i < 20; i++)
    {
        string server = balancer1.GetServer();
        Console.WriteLine($"底[{i + 0}]次分发请求至服务器:{server}");
    }

    Console.ReadKey();
}

5、启动 ConsoleApp1 项目运行

image.png

输入信息:

服务器负载均衡器(LB)实例对象具有唯一性!
第[1]次分发请求至服务器:Server 2
第[2]次分发请求至服务器:Server 1
第[3]次分发请求至服务器:Server 3
第[4]次分发请求至服务器:Server 2
第[5]次分发请求至服务器:Server 2
第[6]次分发请求至服务器:Server 1
第[7]次分发请求至服务器:Server 2
第[8]次分发请求至服务器:Server 3
第[9]次分发请求至服务器:Server 2
第[10]次分发请求至服务器:Server 3

6、单例对象构造器另一种使用

除了上面的单例对象构造器的使用方式,还可以这样使用,改造如下:

  1. 修改 LoadBalancer 继承 SingletonConstructor 单例对象构造器。
/// <summary>
/// 模拟负载均衡器
/// </summary>
internal class LoadBalancer : SingletonConstructor<LoadBalancer>
{
   // 其他代码不变
}
  1. 修改客户端调用方式。
var balancer1 = LoadBalancer.GetInstance();
var balancer2 = LoadBalancer.GetInstance();
var balancer3 = LoadBalancer.GetInstance();

这样就改造好了,启动运行效果相同。

image.png

以上就是 SingletonConstructor(单例对象构造器) 的完整使用,更佳优雅的构建单例对象。使用的时候,注意具体的类对象,必须是无参构造函数,遵循单例模式的规则即可。

总结

通过模拟 LB 操作,体验使用【单例模式】设计并确保 LB唯一性 至关重要,在实际的项目应用中,类似的场景很多,而对于单例模式的创建,我们可以封装 SingletonConstructor(单例对象构造器)来快速创建具体类的单例对象,SingletonConstructor 使用的两种方式,依据实际情况自行选择吧。

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
19天前
|
弹性计算 监控 负载均衡
|
开发框架 负载均衡 Java
Spring Cloud 介绍及负载均衡Ribbon、服务容错Hystrix 组件使用详解
Spring Cloud 介绍及负载均衡Ribbon、服务容错Hystrix 组件使用详解
215 0
|
19天前
|
运维 负载均衡 算法
|
1月前
|
负载均衡 Kubernetes 区块链
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
随机密码生成器+阿里k8s负载均衡型服务加证书方法+移动终端设计+ico生成器等
53 1
|
3月前
|
存储 设计模式 缓存
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
该文章主要介绍了如何在OpenFeign中集成Ribbon以实现负载均衡,并详细分析了Ribbon中服务选择和服务过滤的核心实现过程。文章还涉及了Ribbon中负载均衡器(ILoadBalancer)和负载均衡策略(IRule)的初始化方式。
OpenFeign集成Ribbon负载均衡-过滤和选择服务核心实现
|
3月前
|
负载均衡 Kubernetes 开发工具
k8s相关服务与负载均衡
k8s相关服务与负载均衡
44 0
|
4月前
|
负载均衡 监控 Kubernetes
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
|
3月前
|
负载均衡 Dubbo 算法
Dubbo服务负载均衡原理
该文章主要介绍了Dubbo服务负载均衡的原理,包括Dubbo中负载均衡的实现位置、为什么需要负载均衡机制、Dubbo支持的负载均衡算法以及随机负载均衡策略的源码分析。
|
6月前
|
负载均衡 算法 应用服务中间件
这些负载均衡都解决哪些问题?服务、网关、NGINX?
这些负载均衡都解决哪些问题?服务、网关、NGINX?
256 1
|
6月前
|
负载均衡 网络协议 应用服务中间件
【亮剑】在Linux中构建高可用性和高性能网络服务的负载均衡工具HAProxy、Nginx和Keepalived。
【4月更文挑战第30天】本文介绍了在Linux中构建高可用性和高性能网络服务的负载均衡工具HAProxy、Nginx和Keepalived。HAProxy是一个高性能的开源TCP和HTTP负载均衡器,适合处理大量并发连接;Nginx是一个多功能Web服务器和反向代理,支持HTTP、HTTPS和TCP负载均衡,同时提供缓存和SSL功能;Keepalived用于监控和故障切换,通过VRRP实现IP热备份,保证服务连续性。文中详细阐述了如何配置这三个工具实现负载均衡,包括安装、配置文件修改和启动服务,为构建可靠的负载均衡系统提供了指导。
158 0