如何实现一个分布式单例对象?什么场景需要分布式单例?

news2025/3/20 6:08:30

单例模式确保一个类在同一个进程中只有一个实例,并提供一个全局访问点。这意味着无论在哪里调用该类的实例化方法,返回的都是同一个对象实例。

在分布式系统中,无论是单台机器多个实例,还是多台机器多个实例,每个实例通常运行在独立的进程中,分布式单例是在这些多进程环境中,确保某个类的实例对象在整个分布式系统中是唯一的,即所有进程访问的都是同一个对象实例。

按照这个思路,需要确保在任意时刻,只有一个进程能够访问和修改单例对象。,而分布式场景下的分布式锁就很容易实现这个功能。

多个进程竞争分布式锁,谁抢到锁,谁此时就可以使用这个单例对象,用完之后释放这个对象,并且释放锁这样不就保证多进程中实例对象唯一了吗?

分布式锁可以用 redis 实现,三方外部存储也可以用 redis 实现。

  1. 选择合适的分布式锁机制:使用Redis的SETNX命令或者Redlock算法来实现分布式锁。SETNX命令可以尝试设置一个键,如果键不存在,则成功设置并返回1;如果键已经存在,则不执行任何操作并返回0。这可以用来模拟锁的行为。

  2. 获取锁:在尝试访问单例对象前,每个进程都需要先尝试获取分布式锁。只有成功获取锁的进程才能继续下一步操作。

  3. 从Redis加载数据:成功获取锁的进程需要从Redis中加载单例对象的数据。如果这是第一次加载,Redis中可能没有相关数据,此时可以初始化一个新的对象。

  4. 反序列化:将从Redis获取的数据反序列化为对象实例。如果Redis中没有数据,则创建一个新的对象实例。

  5. 使用对象:使用反序列化后的对象实例执行所需的操作。

  6. 序列化并存储:完成对象的使用后,将对象的数据序列化,并将其存储回Redis中,覆盖之前的版本。

  7. 释放锁:最后,释放分布式锁,允许其他进程竞争锁以使用单例对象。

  8. 异常处理:在整个过程中,还需要考虑异常处理,确保即使发生错误也能正确释放锁,避免死锁的发生。

public class DistributedSingleton {
    private static final String LOCK_KEY = "singleton_lock";
    private static final String INSTANCE_KEY = "singleton_instance";
    
    public Object getInstance() {
        // 尝试获取分布式锁
        boolean lockAcquired = acquireDistributedLock(LOCK_KEY);
        
        if (lockAcquired) {
            try {
                // 从Redis加载数据
                String serializedData = getFromRedis(INSTANCE_KEY);
                // 反序列化
                Object instance;
                if (serializedData == null) {
                    instance = new SingletonObject(); // 如果是第一次加载,创建新的实例
                } else {
                    instance = deserialize(serializedData); // 否则,反序列化已有的数据
                }  
                // 使用对象
                useInstance(instance);   
                // 序列化并存储
                String newData = serialize(instance);
                saveToRedis(INSTANCE_KEY, newData);
                return instance;
            } finally {
                // 释放锁
                releaseDistributedLock(LOCK_KEY);
            }
        } else {
            throw new RuntimeException("Failed to acquire lock");
        }
    }
    private void useInstance(Object instance) {
        // 执行对象的具体操作
    }
    private boolean acquireDistributedLock(String key) {
        // 实现获取分布式锁的逻辑
        return true; // 假设获取成功
    }
    private void releaseDistributedLock(String key) {
        // 实现释放分布式锁的逻辑
    }
    private String getFromRedis(String key) {
        // 从Redis获取数据
        return null; // 返回数据或null
    }
    private void saveToRedis(String key, String value) {
        // 将数据保存到Redis
    }
    private String serialize(Object obj) {
        // 序列化对象
        return ""; // 返回序列化后的字符串
    }
    private Object deserialize(String str) {
        // 反序列化对象
        return null; // 返回反序列化后的对象
    }
}
应用场景
  1. 全局配置管理:在分布式系统中,可能需要一个全局的配置中心来统一管理应用的配置信息。这些配置信息需要被所有节点共享,并且在更新时保持一致性。

  2. 会话管理:在Web应用中,用户会话信息通常需要跨多个服务器共享。使用分布式单例可以确保所有服务器访问相同的会话数据,提供一致的用户体验。

  3. 缓存管理:为了提高性能,应用可能会使用缓存来存储频繁访问的数据。在分布式环境中,确保所有节点都能访问相同的缓存数据是非常重要的。

  4. 计数器或统计信息:当需要在多个节点之间同步计数器或统计信息时,使用分布式单例可以帮助保持数据的一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2318194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VBA常见的知识都有哪些,让AI编写的VBA经常 报错,所以VBA的基础还是要学习的

掌握这些能够大大的提高VBA的编写效率,欢迎来到涛涛聊AI。 1. 异常处理 Cleanup:是VBScript的错误处理标签,用于标记程序执行失败或退出时需要执行的清理操作(如关闭文件、释放对象)。这段代码会在遇到错误或用户取消操作时跳转…

DeepSeek(8):结合Kimi-PPT助手一键生成演示报告

1 生成内容 在Deepseek中生成内容: 帮我创建年度计划,描述《智能枕头》产品的如何在全国销售,计划切分到每个月。从而让我们的老板和团队对报告充满信息。输出的内容我需要放到ppt中进行展示。 使用Deepseek R1模型,如下&#x…

【MySQL】MySQL如何存储元数据?

目录 1.数据字典的作用 2. MySQL 8.0 之前的数据字典 3. MySQL 8.0 及之后的数据字典 4.MySQL 8 中的事务数据字典的特征 5.数据字典的序列化 6. .sdi文件的作用: 7..sdi的存储方式 在 MySQL 中,元数据(Metadata) 是描述数…

用ASCII字符转化图片

代码 from PIL import Image# 定义 ASCII 字符集,从最暗到最亮 ASCII_CHARS "%#*-:. "def resize_image(image, new_width100):width, height image.sizeratio height / widthnew_height int(new_width * ratio)resized_image image.resize((new_wi…

蓝桥与力扣刷题(蓝桥 组队)

题目:作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员,组成球队的首发阵容。 每位球员担任 1号位至 5号位时的评分如下表所示。请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少? 本题为填空题&…

AI Agent系列(六) -基于ReAct架构搭建LLM Agent(Deepseek)

AI Agent系列【六】 一、 ReAct1.1 ReAct 的处理过程:1.1 代码结构 二、 Python代码实现2.1 通过Zero-shot 实现python代码实例Python代码示例1:python代码实现示例2 一、 ReAct ReAct 是 Reseaning 和 Action 两个词的前缀合成,代表着先推…

AnyTouch:跨多个视觉触觉传感器学习统一的静态动态表征

25年3月来自人大、武汉科技大学和北邮的论文“AnyTouch: Learning Unified Static-dynamic Representation Across Multiple Visuo-tactile Sensors”。 视觉触觉传感器旨在模拟人类的触觉感知,使机器人能够精确地理解和操纵物体。随着时间的推移,许多精…

YOLOv11 目标检测

本文章不再赘述anaconda的下载以及虚拟环境的配置,博主使用的python版本为3.8 1.获取YOLOv11的源工程文件 链接:GitHub - ultralytics/ultralytics: Ultralytics YOLO11 🚀 直接下载解压 2.需要自己准备的文件 文件结构如下:红…

VSCode C/C++ 环境搭建指南

一、前言 Visual Studio Code(简称 VSCode)是一款轻量级且功能强大的跨平台代码编辑器,凭借丰富的插件生态和高度的可定制性,深受开发者喜爱。对于 C/C 开发者而言,在 VSCode 中搭建开发环境,能够获得灵活…

Python 中下划线 “_” 的多面性:从变量到约定

# Python中下划线“_”的多面性:从变量到约定 在Python的语法体系里,下划线“_”看似毫不起眼,实则扮演着极为重要且多样化的角色。它不仅能作为普通变量参与编程,更在多个特殊场景下有着独特的用途与约定。深入理解下划线的各种…

Vue3项目开发:状态管理实践指南

# Vue3项目开发:状态管理实践指南 一、引言 背景介绍 在Vue项目中,状态管理是一个非常重要的话题。合理的状态管理能够帮助我们更好地组织和管理数据,提升项目的可维护性和可扩展性。本文将深入探讨Vue3项目中状态管理的最佳实践,…

数据结构-------栈

顺序栈: 一、数据结构定义 数据元素 DATATYPE typedef struct person {char name[32];char sex;int age;int score; } DATATYPE;顺序栈结构 SeqStack typedef struct list {DATATYPE *head; // 栈空间首地址int tlen; // 栈总容量(total leng…

机器学习概要

文章目录 一、什么是机器学习 二、机器学习的种类 1. 有监督学习 2. 无监督学习 3.强化学习 三、机器学习的应用 四、机器学习的步骤 1. 数据的重要性 2. 数据和学习的种类 3. 可视化 一、什么是机器学习 机器学习指的是计算机根据给定的问题、课题或环境进行学习&a…

【LangChain入门 2 Model组件】开始!LLM Models简单对话

文章目录 一、使用langchain_ollama二、采用DeepSeek的API三、Model 介绍3.1 OllamaLLM 预训练模型3.2 ChatOllama 聊天预训练模型3.3 OllamaEmbeddings 实现一个helloworld,跑通一个简单的对话。 后面章节会正式介绍LangChain的各个功能。 后台llm的端口可以任意选…

C++20 中线程管理与取消机制的深度剖析

文章目录 std::jthread:更智能的线程管理背景与优势构造函数与 std::stop_token 的集成 std::stop_token、std::stop_source 和 std::stop_callback:灵活的取消机制std::stop_token:取消请求的指示器std::stop_source:取消请求的发…

Vue3 核心特性解析:Suspense 与 Teleport 原理深度剖析

Vue3 核心特性解析:Suspense 与 Teleport 原理深度剖析 一、Teleport:突破组件层级的时空传送 1.1 实现原理图解 #mermaid-svg-75dTmiektg1XNS13 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-s…

FPGA——实现LED流水灯

文章目录 一、Quartusll_18.1和VS Code软件的关联二、DE2-115的时钟电路三、流水灯的分层次设计四、总结 一、Quartusll_18.1和VS Code软件的关联 1.先打开Quartus II 软件,然后选择菜单栏“Tools”下的“Options…”。 2.点击“Options…”,在弹出的对…

Excel 小黑第12套

对应大猫13 涉及金额修改 -数字组 -修改会计专用 VLOOKUP函数使用(查找目标,查找范围(F4 绝对引用),返回值的所在列数,精确查找或模糊查找)双击填充柄就会显示所有值 这个逗号要中文的不能英…

滚动元素的新api

点击的时候需要双重视图滚动 itemClick(id) {// 滚动到对应位置this.$nextTick(() > {// 找到对应 id 在 initList2 中的索引const index this.initList2.findIndex((item) > item.id Number(id));if (index ! -1) {// 获取所有菜单项const menuItems document.queryS…

多机调度问题(C语言)

代码如下&#xff1a; #include<stdio.h> #include<stdlib.h>int compare(void* a, void* b)//比较函数&#xff0c;用于qsort按处理时间从大到小排序 {return *(int*)a - *(int*)b; }int LPT(int jobs[], int n, int m)//多机调度问题的LPT算法 {qsort(jobs, n, …