工作纪实51-手撸AB实验分流策略

前几天写了一篇关于哈希算法的文章,起源就是在构思AB实验平台的时候,用到了哈希,所以对其做了深入的了解
AB实验平台是一般互联网做策略、样式实验会用到的一个系统,一般开启某个实验之后,需要对线上流量进行分流:客户端->实验平台->策略平台->应用服务,大概是这个链路

场景

线上流量策略分流,需要对不同人群做策略实验,最终效果好的一组需要推全到100%,在未推全之前,100%的流量会被分到原有流量+几个实验组;
比如我有一个实验:样式迭代,产品希望60%的流量走线上逻辑,剩下的40%,均分到4个实验组,这样可以细致的比对样式的效果,当然,如果一个用户命中了实验组A,那么他后续的行为,在实验组不调整的情况下,需要一直保持(有的人说希望调整了也保持,但是真的了解AB分流逻辑之后,真挺难的);
其实我们有自己的AB平台,但是我在想如果让我去实现,我会怎么做,便有了这一篇文章;

考虑的问题

1.如何保证一个用户对实验命中唯一性

在实验组不调整的情况下,PM希望用户分流的结果始终保持一致;
【策略】:hash算法,通过对imei进行哈希运算得到int的哈希值即可,可以加一个时间戳(实验修改时间),来控制用户的imei命中变化

2.如何按比例分流

【策略】取模运算,构建一个长度为100的bucket,然后通过对imei的哈希值运算结果对100取模,即可得到0-100的数,从而去命中数据区间,挑选实验组即可;由于哈希算法的特性,只要imei不变,时间戳(因子)不变,计算得到的哈希值是永远不会变的,所以取模结果,命中实验的结果也是不变的;

比如我的case是线上流量60%,其他实验组10%,10%,10%,10%,则可以构建一个数据区间:【0,60,70,80,90,100】
在这里插入图片描述

实战

代码

@Data
public class TrafficDistributor {
    private String id;// 实验id
    private String name;
    private double isolation;// 线上流量
    private List<Experiment> experiments;// 实验组
    private Table<String, String, Set<String>> whiteTable = HashBasedTable.create();
    private static Date updateTime = new Date(1719844946L);//2024/7/1 22:42:26

    public TrafficDistributor(String id, String name, double isolation, List<Experiment> experiments, Table<String, String, Set<String>> whiteTable) {
        this.id = id;
        this.name = name;
        this.isolation = isolation;
        this.experiments = experiments;
        this.whiteTable = whiteTable;
    }

    public static void main(String[] args) {
        // 实验id
        String id = "new_style";
        // 1.初始化白名单==》正式环境从db中拿出来初始化
        Table<String, String, Set<String>> white = HashBasedTable.create();
        white.put(id, "00", Sets.newHashSetWithExpectedSize(0));
        white.put(id, "01", Set.of("whitelist_imei_1", "whitelist_imei_2"));
        white.put(id, "02", Set.of("whitelist_imei_3", "whitelist_imei_4"));
        white.put(id, "11", Set.of("whitelist_imei_5", "whitelist_imei_6"));
        white.put(id, "12", Set.of("whitelist_imei_7", "whitelist_imei_8"));
        // 2.初始化实验组
        Experiment experiment1 = new Experiment("01", "对照组01", 10);
        Experiment experiment2 = new Experiment("02", "对照组02", 10);
        Experiment experiment3 = new Experiment("11", "实验组01", 10);
        Experiment experiment4 = new Experiment("12", "实验组02", 10);
        List<Experiment> experiments = List.of(experiment1, experiment2, experiment3, experiment4);
        // 3.初始化分流器
        TrafficDistributor distributor = new TrafficDistributor(id, "新样式实验", 60, experiments, white);
        // 4.模拟分流
        for (int times = 0; times < 100; times++) {
            int index = 1, size = 100;
            Map<String, Integer> result = Maps.newHashMap();
            List<Long> cost = Lists.newArrayListWithCapacity(size);
            while (index <= size) {
                String imei = RandomStringUtils.randomAlphanumeric(64);
                long start = System.currentTimeMillis();
                // 核心分流
                Experiment experiment = distributor.allocate(id, imei);
                if (experiment != null) {
                    // 实验组
                    result.compute(experiment.getId(), (eid, count) -> (count == null) ? 1 : count + 1);
                } else {
                    // 线上
                    int value = result.getOrDefault("00", 0);
                    result.put("00", value + 1);
                }
                cost.add(System.currentTimeMillis() - start);
                index++;
            }
            System.out.println("耗时:" + cost.stream().mapToLong(Long::longValue).sum() + ";结果:" + JSON.toJSONString(result));
        }
    }

    /**
     * 流量分配: 白名单 - 实验组 - 线上流量
     */
    public Experiment allocate(String id, String imei) {
        Experiment whiteListShot = whiteListShot(id, imei);
        if (whiteListShot != null) {
            return whiteListShot;
        }
        List<Double> weights = experiments.stream().map(Experiment::getWeight).collect(Collectors.toList());
        int groupId = distributeTraffic(weights, imei);
        if (groupId < 0) {
            // 线上流量
            return null;
        }
        // 实验组流量
        return experiments.get(groupId);
    }

    /**
     * 根据每个实验组的权重配比,判断最终流量应该分配到哪个实验组。
     *
     * @param weights 每个实验组的权重值数组。
     * @param imei    imei
     * @return 分配流量的实验组索引
     */
    public int distributeTraffic(List<Double> weights, String imei) {
        if (CollectionUtils.isEmpty(weights)) {
            return -1;
        }
        double totalWeight = 100;// 总权重100%
        double testWeight = weights.stream().mapToDouble(Double::doubleValue).sum();// 实验组总权重
        if (totalWeight != (isolation + testWeight)) {
            throw new IllegalArgumentException("实验组和对照组流量分配存在问题");
        }
        // imei+时间戳(因子)生成hash
        int hash = HashUtils.hashcode(imei + updateTime.getTime());
        return bucketShot(weights, hash % totalWeight);
    }

    /**
     * 哈希值进行取模定位后,命中的实验
     */
    public int bucketShot(List<Double> weights, double bucketIndex) {
        List<Double> range = Lists.newArrayListWithCapacity(weights.size() + 1);
        range.add(isolation);
        double pre = range.get(0);
        for (double weight : weights) {
            range.add(pre + weight);
            pre = pre + weight;
        }
        for (int i = 0; i < range.size(); i++) {
            if (bucketIndex <= range.get(i)) {
                return i - 1;
            }
        }
        throw new IllegalArgumentException("实验组和对照组流量分配存在问题");
    }

    /**
     * 白名单命中
     *
     * @param id   实验id
     * @param imei imei
     * @return 实验组
     */
    public Experiment whiteListShot(String id, String imei) {
        assert whiteTable != null && !whiteTable.isEmpty();
        if (!whiteTable.containsRow(id)) {
            throw new IllegalArgumentException("实验id=" + id + "不存在");
        }
        Map<String, Set<String>> experimentData = whiteTable.row(id);
        for (Map.Entry<String, Set<String>> entry : experimentData.entrySet()) {
            Set<String> values = entry.getValue();
            if (!CollectionUtils.isEmpty(values) && values.contains(imei)) {
                String key = entry.getKey();
                return experiments.stream().filter(test -> test.getId().equals(key)).findFirst().orElse(null);
            }
        }
        return null;
    }

    // 其他方法保持不变
    @Data
    @AllArgsConstructor
    static class Experiment {
        private String id;
        private String name;
        private double weight;
    }
public class HashUtils {
    /**
     * hashCode方法
     */
    public static int hashcode(Object obj) {
        final int p = 16777619;
        int hash = (int) 2166136261L;
        String str = obj.toString();
        for (int i = 0; i < str.length(); i++)
            hash = (hash ^ str.charAt(i)) * p;
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;

        if (hash < 0)
            hash = Math.abs(hash);
        return hash;
    }
}

分析

耗时:34;结果:{"11":11,"00":61,"01":7,"12":9,"02":12}
耗时:4;结果:{"11":8,"00":61,"12":4,"01":9,"02":18}
耗时:2;结果:{"11":9,"00":60,"01":10,"12":7,"02":14}
耗时:2;结果:{"11":11,"00":54,"01":10,"12":14,"02":11}
耗时:1;结果:{"11":9,"00":65,"12":12,"01":8,"02":6}
耗时:3;结果:{"11":9,"00":61,"01":6,"12":12,"02":12}
耗时:2;结果:{"11":9,"00":56,"12":8,"01":17,"02":10}
耗时:2;结果:{"11":7,"00":61,"12":7,"01":10,"02":15}
耗时:1;结果:{"11":8,"00":58,"01":13,"12":4,"02":17}
耗时:0;结果:{"11":5,"00":72,"01":9,"12":5,"02":9}
耗时:0;结果:{"11":2,"00":70,"12":14,"01":8,"02":6}
耗时:2;结果:{"11":7,"00":63,"12":10,"01":10,"02":10}
耗时:0;结果:{"11":8,"00":60,"12":11,"01":10,"02":11}
耗时:1;结果:{"11":9,"00":60,"12":11,"01":13,"02":7}
耗时:0;结果:{"11":12,"00":71,"12":5,"01":9,"02":3}
耗时:1;结果:{"11":12,"00":57,"01":11,"12":11,"02":9}
耗时:0;结果:{"11":8,"00":62,"01":14,"12":7,"02":9}
耗时:1;结果:{"11":10,"00":64,"12":6,"01":9,"02":11}
耗时:2;结果:{"11":5,"00":73,"12":7,"01":9,"02":6}
耗时:0;结果:{"11":9,"00":68,"01":6,"12":9,"02":8}
耗时:1;结果:{"11":12,"00":63,"01":10,"12":4,"02":11}
耗时:1;结果:{"11":15,"00":59,"01":8,"12":9,"02":9}
耗时:0;结果:{"11":10,"00":66,"01":8,"12":6,"02":10}
耗时:1;结果:{"11":8,"00":64,"01":10,"12":6,"02":12}
耗时:2;结果:{"11":11,"00":63,"01":8,"12":8,"02":10}
耗时:1;结果:{"11":5,"00":66,"12":9,"01":12,"02":8}
耗时:3;结果:{"11":8,"00":67,"12":10,"01":9,"02":6}
耗时:1;结果:{"11":9,"00":54,"12":16,"01":7,"02":14}
耗时:0;结果:{"11":11,"00":63,"12":5,"01":11,"02":10}
耗时:1;结果:{"11":10,"00":59,"01":12,"12":8,"02":11}
耗时:1;结果:{"11":12,"00":62,"12":11,"01":8,"02":7}
耗时:0;结果:{"11":8,"00":59,"12":8,"01":13,"02":12}
耗时:1;结果:{"11":12,"00":51,"12":11,"01":15,"02":11}
耗时:1;结果:{"11":1,"00":72,"01":10,"12":8,"02":9}
耗时:1;结果:{"11":8,"00":55,"01":18,"12":9,"02":10}
耗时:0;结果:{"11":6,"00":54,"01":22,"12":5,"02":13}
耗时:1;结果:{"11":9,"00":58,"12":11,"01":11,"02":11}
耗时:1;结果:{"11":15,"00":57,"12":12,"01":3,"02":13}
耗时:1;结果:{"11":6,"00":66,"12":10,"01":11,"02":7}
耗时:0;结果:{"11":13,"00":61,"12":12,"01":8,"02":6}
耗时:0;结果:{"11":8,"00":61,"12":11,"01":10,"02":10}
耗时:0;结果:{"11":10,"00":57,"01":10,"12":12,"02":11}
耗时:1;结果:{"11":6,"00":62,"12":12,"01":11,"02":9}
耗时:5;结果:{"11":9,"00":64,"12":8,"01":10,"02":9}
耗时:0;结果:{"11":15,"00":54,"12":8,"01":9,"02":14}
耗时:0;结果:{"11":12,"00":62,"01":8,"12":10,"02":8}
耗时:0;结果:{"11":9,"00":63,"12":6,"01":12,"02":10}
耗时:0;结果:{"11":9,"00":59,"01":10,"12":9,"02":13}
耗时:1;结果:{"11":10,"00":58,"01":7,"12":14,"02":11}
耗时:1;结果:{"11":9,"00":73,"01":8,"12":2,"02":8}
耗时:0;结果:{"11":14,"00":62,"12":7,"01":10,"02":7}
耗时:1;结果:{"11":12,"00":55,"12":10,"01":12,"02":11}
耗时:0;结果:{"11":5,"00":59,"01":7,"12":17,"02":12}
耗时:0;结果:{"11":10,"00":59,"12":7,"01":10,"02":14}
耗时:1;结果:{"11":11,"00":54,"01":17,"12":8,"02":10}
耗时:0;结果:{"11":8,"00":65,"12":8,"01":9,"02":10}
耗时:1;结果:{"11":13,"00":61,"12":8,"01":9,"02":9}
耗时:1;结果:{"11":6,"00":67,"01":10,"12":11,"02":6}
耗时:1;结果:{"11":7,"00":61,"12":8,"01":10,"02":14}
耗时:0;结果:{"11":6,"00":63,"12":8,"01":10,"02":13}
耗时:0;结果:{"11":9,"00":62,"12":9,"01":9,"02":11}
耗时:1;结果:{"11":5,"00":65,"01":8,"12":11,"02":11}
耗时:0;结果:{"11":11,"00":52,"12":9,"01":15,"02":13}
耗时:0;结果:{"11":14,"00":66,"01":4,"12":7,"02":9}
耗时:0;结果:{"11":12,"00":54,"12":8,"01":8,"02":18}
耗时:1;结果:{"11":9,"00":64,"12":8,"01":10,"02":9}
耗时:1;结果:{"11":9,"00":65,"01":3,"12":11,"02":12}
耗时:0;结果:{"11":5,"00":67,"01":7,"12":12,"02":9}
耗时:0;结果:{"11":13,"00":50,"01":12,"12":11,"02":14}
耗时:1;结果:{"11":18,"00":55,"12":7,"01":10,"02":10}
耗时:0;结果:{"11":5,"00":64,"01":12,"12":5,"02":14}
耗时:0;结果:{"11":10,"00":68,"12":6,"01":7,"02":9}
耗时:1;结果:{"11":9,"00":71,"12":4,"01":6,"02":10}
耗时:0;结果:{"11":8,"00":62,"12":9,"01":9,"02":12}
耗时:0;结果:{"11":10,"00":64,"12":8,"01":9,"02":9}
耗时:0;结果:{"11":9,"00":57,"12":10,"01":9,"02":15}
耗时:0;结果:{"11":10,"00":60,"12":13,"01":9,"02":8}
耗时:0;结果:{"11":12,"00":66,"01":5,"12":9,"02":8}
耗时:0;结果:{"11":6,"00":58,"01":11,"12":13,"02":12}
耗时:1;结果:{"11":10,"00":62,"01":12,"12":9,"02":7}
耗时:1;结果:{"11":7,"00":66,"12":11,"01":7,"02":9}
耗时:0;结果:{"11":10,"00":63,"12":9,"01":11,"02":7}
耗时:1;结果:{"11":8,"00":61,"12":10,"01":12,"02":9}
耗时:0;结果:{"11":8,"00":62,"12":6,"01":10,"02":14}
耗时:0;结果:{"11":7,"00":68,"12":8,"01":11,"02":6}
耗时:0;结果:{"11":11,"00":54,"01":11,"12":16,"02":8}
耗时:0;结果:{"11":7,"00":68,"01":10,"12":6,"02":9}
耗时:0;结果:{"11":7,"00":65,"12":7,"01":8,"02":13}
耗时:0;结果:{"11":8,"00":69,"01":8,"12":5,"02":10}
耗时:0;结果:{"11":15,"00":60,"01":6,"12":11,"02":8}
耗时:0;结果:{"11":9,"00":70,"01":6,"12":7,"02":8}
耗时:0;结果:{"11":14,"00":62,"12":7,"01":10,"02":7}
耗时:0;结果:{"11":11,"00":64,"12":7,"01":7,"02":11}
耗时:1;结果:{"11":6,"00":56,"12":14,"01":10,"02":14}
耗时:0;结果:{"11":7,"00":64,"12":8,"01":11,"02":10}
耗时:1;结果:{"11":14,"00":65,"12":4,"01":10,"02":7}
耗时:0;结果:{"11":13,"00":59,"12":7,"01":13,"02":8}
耗时:1;结果:{"11":5,"00":65,"12":8,"01":14,"02":8}
耗时:1;结果:{"11":12,"00":54,"01":11,"12":10,"02":13}
耗时:1;结果:{"11":10,"00":56,"12":11,"01":11,"02":12}
Process finished with exit code 0
  • 我手写的hashCode方法,包括随机字符串生成的imei仍然存在实验组分类偏向的情况,中间尝试过使用一致性哈希解决偏移,但是又解决不了加权按比例分配的问题,不知道各位同仁有没有什么好的建议
  • 取模算法是个宝藏,既可以精准定位,也可以利用随机性,来做区间命中
  • updateTime它是个变化因子,如果实验有新增实验组或者流量调整,可以利用它来控制imei实验组变化

参考资料

  • https://zhuanlan.zhihu.com/p/404232432
  • https://blog.csdn.net/SmartCodeTech/article/details/113698568?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ECtr-2-113698568-blog-131205090.235%5Ev43%5Epc_blog_bottom_relevance_base8&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ECtr-2-113698568-blog-131205090.235%5Ev43%5Epc_blog_bottom_relevance_base8&utm_relevant_index=5

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

太速科技-FMC144 -八路 250MSPS 14bit AD FMC子卡

FMC144 -八路 250MSPS 14bit AD FMC子卡 一、板卡概述   FMC144是一款具有8通道模数转换器&#xff08;ADC&#xff09;的FMC卡&#xff0c;具有14bit分辨率&#xff0c;最大采样速率达250Msps。时钟配置芯片为AD9516-1&#xff0c;可由板载10MHz时钟提供参考&#xff0c;也可…

[游戏开发][UE5]引擎学习记录

C Log和蓝图Log C Log 方法 UE_Log(参数1&#xff0c;参数2&#xff0c;参数3) //举例: UE_LOG(LogTemp, Error, TEXT("Log Info: %s"),"Test Log"); 三个参数的作用 参数1&#xff1a;输出窗口归类使用&#xff0c;你写什么它就显示什么 参数2&#x…

node.js安装

下载地址 https://nodejs.org/en/download 安装教程

Stable Diffusion初体验——提示词指南

前言 Stable Diffusion是一种深度学习模型&#xff0c;它能够根据提示词生成高质量的图像。在Stable Diffusion模型中&#xff0c;提示词起着至关重要的作用&#xff0c;因为它们为模型提供了关于所需输出的指导。本文将探讨Stable Diffusion关于提示词的原理&#xff0c;包括…

k8s集群node节点加入失败

出现这种情况&#xff1a; [preflight] FYI: You can look at this config file with kubectl -n kube-system get cm kubeadm-config -o yaml [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kub…

计算机网络——数据链路层(数据链路层概述及基本问题)

链路、数据链路和帧的概念 数据链路层在物理层提供服务的基础上向网络层提供服务&#xff0c;其主要作用是加强物理层传输原始比特流的功能&#xff0c;将物理层提供的可能出错的物理连接改造为逻辑上无差错的数据链路&#xff0c;使之对网络层表现为一条无差错的链路。 链路(…

sheng的学习笔记-AI-K均值算法

ai目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 需要学习前置知识&#xff1a;聚类&#xff0c;可参考 sheng的学习笔记-聚类(Clustering)-CSDN博客 目录 什么是k均值算法 流程 伪代码 数据集 伪代码 代码解释 划分示意图 优化目标 随机初始化 选择聚类数…

酣客的“FFC模式”|白酒商业模式|分润制度顶层架构设计

酣客公社摒弃传统商业模式&#xff0c;提出“心联网”及“FFC模式”的商业模式。 坐标&#xff1a;厦门&#xff0c;我是肖琳 深耕社交新零售行业10年&#xff0c;主要提供新零售系统工具及顶层商业模式设计、全案策划运营陪跑等。 今天和大家分享“酣客”的营销模式&#xff…

Parallels Toolbox for mac(pd工具箱) 6.0.2激活版

Parallels Toolbox 是由 Parallels 公司开发的一款实用工具集合软件&#xff0c;它主要面向使用 Parallels Desktop 的用户&#xff0c;提供了许多方便用户在 macOS 和 Windows 之间进行切换和管理的工具。Parallels Desktop 是一款流行的虚拟化软件&#xff0c;允许用户在 mac…

【24医学顶刊】GANDALF:主动学习 + 图注意力变换器 + 变分自编码器,改善多标签图像分类

GANDALF&#xff1a;主动学习 图注意力变换器 变分自编码器&#xff0c;改善多标签图像分类 提出背景子解法1&#xff1a;多标签信息样本的选择子解法2&#xff1a;生成信息丰富且非冗余的合成样本 例子&#xff1a;胸部X射线图像分析传统方法的操作和局限GaNDLF方法的优势 工…

理解ABP的领域驱动设计

大家好&#xff0c;我是张飞洪&#xff0c;感谢您的阅读&#xff0c;我会不定期和你分享学习心得&#xff0c;希望我的文章能成为你成长路上的垫脚石&#xff0c;让我们一起精进。 关于玩转ABP框架相关的文章&#xff0c;之前在博客园陆续写了《ABP vNext系列文章和视频》&…

电路仿真王者之争:SmartEDA如何领跑业界,打破传统仿真软件格局?

在电子设计领域&#xff0c;电路仿真软件一直扮演着至关重要的角色。它们为工程师们提供了一个虚拟的实验室&#xff0c;可以在不耗费大量实际资源的情况下&#xff0c;进行电路设计、优化和测试。在众多电路仿真软件中&#xff0c;SmartEDA以其独特的优势&#xff0c;逐渐崭露…

嵌入式开发十九:SysTick—系统定时器

在前面实验中我们使用到的延时都是通过SysTick进行延时的。 我们知道&#xff0c;延时有两种方式&#xff1a;软件延时&#xff0c;即CPU 循环等待产生的&#xff0c;这个延时是不精确的。第二种就是滴答定时器延时&#xff0c;本篇博客就来介绍 STM32F4 内部 SysTick 系统定时…

浅谈API生态建设:API安全策略的6项原则

API作为连接系统与应用的桥梁&#xff0c;在助力实现高效业务流程的同时&#xff0c;也不可避免出现资产管理困难、敏感数据泄漏风险骤增等安全问题。前段时间&#xff0c;安全公司Fastly公布了一项重磅调查报告&#xff0c;报告中显示95%的企业在过去1年中遭遇过API安全问题。…

AXI接口简介

AXI接口&#xff0c;全称为Advanced eXtensible Interface&#xff0c;是ARM公司推出的一种高性能、低成本、可扩展的高速总线接口。AXI接口是ARM公司提出的AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;高级微控制器总线架构的一部分。2003年发布了…

简易电阻、电容和电感测量仪-FPGA

通过VHDL语言编写程序用于设计电阻、电容和电感测量仪&#xff0c;通过使用试验箱进行验证是否设计正确&#xff0c;资料获取到咸&#x1f41f;&#xff1a;xy591215295250 \\\或者联系wechat 号&#xff1a;comprehensivable 设计并制作--台数字显示的电阻、电容和电感参数测试…

07-border布局的另一个用处

07-border布局的另一个用处 实现如下的布局: 分析: 1.USERNAME和PASSWORD使用form 2.PASSWORD的文本框使用NewMultiLineEntry 布局1 USERNAME和PASSWORD作为一个form整体&#xff0c;使用border布局&#xff0c;form设置为top&#xff0c;文本框设置为center参数。 packa…

Postman 接口测试 安装使用教程

1 下载官网:https://www.postman.com/downloads/ 2 方便下载,特提供百度云网盘: 链接&#xff1a;Postman 3 windows10 安装&#xff0c;点击安装包 #自动安装&#xff0c;并打开 4 举例&#xff0c;比如豆瓣&#xff0c;get 查询时间&#xff0c;图片登 5 举例&#xff0…

HSRP热备份路由协议(VRRP虚拟路由冗余协议)配置以及实现负载均衡

1、相关原理 在网络中&#xff0c;如果一台作为默认网关的三层交换机或者路由器损坏&#xff0c;所有使用该网关为下一跳的主机通信必然中断&#xff0c;即使配置多个默认网关&#xff0c;在不重启终端的情况下&#xff0c;也不能彻底换到新网关。Cisco提出了HSRP热备份路由协…

传神论文中心|第14期人工智能领域论文推荐

在人工智能领域的快速发展中&#xff0c;我们不断看到令人振奋的技术进步和创新。近期&#xff0c;开放传神&#xff08;OpenCSG&#xff09;社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自的论…