C++负载均衡远程调用学习之获取主机信息功能

目录

01Lars-lbAgentV0.2-赋值均衡数据结构关系分析

02 Lars-lbAgent0.2-host_info-load_balance-route_lb数据结构的定义

03Lars-lbAgentV0.2-proto协议的定义

04 Lars-lbAgentV0.2-route_lb与UDP server的关联

05 -Lars-lbAgentV0.2-route_lb与UDP server的关联

06Lars-lbAgentV0.2-route_lb更新host主机路由信

07Lars-lbAgentV0.2-route_lb获取host信息不存在

08 昨日回顾及agent获取host信息流程

09 Lars-LbAgentV0.2-Api获取主机信息-更新流程梳理

10 Lars-LbAgentV0.2-Api-load_balance模块更新主

11 Lars-LbAgentV0.2-Api目录结构创建

12 Lars-LbAgentV0.2-Api创建udp连接实现-lars-lbagent启动失败修正

13 Lars-LbAgentV0.2-Api-getHost请求实现

14 Lars-LbAgentV0.2-loadBalance-选择主机业务实现

15 Lars-LbAgentV0.3-api-get_hostAPI接口测试

16Lars-LbAgentV0.3-api-get_hostAPI流程总结

17 Lars-LbAgentV0.4-api-上报业务实现


01Lars-lbAgentV0.2-赋值均衡数据结构关系分析

# 七、Lars启动工具脚本

我们提供一个启动lars系统子系统和测试工具的一个脚本工具,`run_lars`

> Lars/run_lars

```shell
#!/bin/bash

LARS_REPORTER_PATH="./lars_reporter"
LARS_DNS_PATH="./lars_dns"
LARS_LBAGENT_PATH="./lars_loadbalance_agent"
LARS_WEB_PATH="./larsWeb"
LARS_API_EXAMPLE_PATH="./api/cpp/example"

usage()
{
    echo ""
    echo "=======启动子系统=========="
    echo "Usage ./run_lars [reporter|dns|lbagent|web|test]"
    echo

    echo "=======测试工具============"
    echo "Usage ./run_lars test gethost ModID CmdID"
    echo "Usage ./run_lars test getroute ModID CmdID"
    echo "Usage ./run_lars test report ModID CmdID IP Port 0|1  --- 0:SUCC, 1:OVERLOAD"
    echo "Usage ./run_lars test simulator ModID CmdID [errRate(0-10)] [queryCnt(0-999999)]"
    echo "Usage ./run_lars test qps ThreadNum"
    echo "Usage ./run_lars test example ModID CmdID"
    echo
}

if [ "$1" = "test" ]; then
    if [ "$2" = "gethost" ]; then
        $PWD/$LARS_API_EXAMPLE_PATH/get_host $3 $4 
    elif [ "$2" = "getroute" ]; then
        $PWD/$LARS_API_EXAMPLE_PATH/get_route $3 $4 
    elif [ "$2" = "report" ]; then
        $PWD/$LARS_API_EXAMPLE_PATH/report $3 $4 $5 $6 $7
    elif [ "$2" = "example" ]; then
        $PWD/$LARS_API_EXAMPLE_PATH/example $3 $4
    elif [ "$2" = "simulator" ]; then
        if [ $# -eq 4 ]; then
            $PWD/$LARS_API_EXAMPLE_PATH/simulator $3 $4 
        elif [ $# -eq 5 ]; then
            $PWD/$LARS_API_EXAMPLE_PATH/simulator $3 $4 $5
        elif [ $# -eq 6 ]; then
            $PWD/$LARS_API_EXAMPLE_PATH/simulator $3 $4 $5 $6
        else
            usage
        fi
    elif [ "$2" = "qps" ]; then
        $PWD/$LARS_API_EXAMPLE_PATH/qps $3
    fi
elif [ "$1" = "reporter" ]; then
    cd $LARS_REPORTER_PATH
    ./bin/lars_reporter
elif [ "$1" = "dns" ]; then
    cd $LARS_DNS_PATH
    ./bin/lars_dns
elif [ "$1" = "lbagent" ]; then
    cd $LARS_LBAGENT_PATH
    ./bin/lars_lb_agent
elif [ "$1" = "web" ]; then
    cd $LARS_WEB_PATH
    ./lars-web
elif [ "$1" = "help" ]; then
    usage
else
    usage
fi
```
 

02 Lars-lbAgent0.2-host_info-load_balance-route_lb数据结构的定义

**其他测试工具启动方式**

```bash
$ ./run_lars help

=======启动子系统==========
Usage ./run_lars [reporter|dns|lbagent|web|test]

=======测试工具============
Usage ./run_lars test gethost ModID CmdID
Usage ./run_lars test getroute ModID CmdID
Usage ./run_lars test report ModID CmdID IP Port 0|1  --- 0:SUCC, 1:OVERLOAD
Usage ./run_lars test simulator ModID CmdID [errRate(0-10)] [queryCnt(0-999999)]
Usage ./run_lars test qps ThreadNum
Usage ./run_lars test example ModID CmdID

```

03Lars-lbAgentV0.2-proto协议的定义

# 八、Lars优化建议

## 1) 量小的情况下过载发现太慢

对于一个小量服务, 假设一个窗口内(15s)匀速只有20次过程调用,如果远端过载, 则在已有策略上需要1succ 19err 几乎全失败才会感知

更严重的是,匀速<20次过程调用,即使全部失败也不可能达到过载条件

**优化:**

连续2个窗口内都没过载,但是这2个窗口内真实失败率都高于70%: 说明是小业务量,认为此节点过载

## 2) 某场景下节点过载发现太慢

04 Lars-lbAgentV0.2-route_lb与UDP server的关联

**场景回顾:**

远程服务mod的一台节点h已经挂了,但Lars系统一直没有将h节点判定为过载

**问题分析**

业务调用方的超时时间设置的是1秒,每次调用h节点都超时,即都消耗1秒,于是1秒才向Lb Agent上报一次状态

与此行为冲突的是,agent每隔15秒会重置所有正常节点的调用统计,15s内,agent仅收到15次对h节点调用错误的上报,即15个err,根本达不到h节点过载的条件,于是h节点在每个15s内都一直被Lars认为是正常的,永远无法被判定为过载

**结论**

05 -Lars-lbAgentV0.2-route_lb与UDP server的关联

**结论**

Lars的过载判定算法没有对节点调用耗时进行考虑

假设业务设置的调用超时时间为3秒,则业务方调用h节点失败消耗了3秒,并仅向Lars agent上报一个调用错误,`err + 1`

**优化:**

当调用节点失败,向上报状态要携带本次调用时间`timecost`(ms),Lb agent在收到调用失败的汇报时,会对失败个数根据`timecost`进行放大

具体是:

> ```
> errcnt = timecost / 100; errcnt = 1 if timecost = 0
> ```

于是乎,业务调用方调用h节点失败并消耗了1s,上报给Lb agent后,agent会认为h节点失败了1000ms/100 = 10次,会使挂掉的h更快达到过载条件

06Lars-lbAgentV0.2-route_lb更新host主机路由信

**本优化可以更快感知调用超时情况的过载**

## 3) 多线程分配如Dns、Report等 简单轮询改成一致性Hash算法

>  MurmurHash一致性hash

### 3.1 什么是一致性HASH

> 注: 本小结内容转载自:<https://www.wmathor.com/index.php/archives/1138/>

工程设计中常用服务器集群来设计和实现数据缓存,以下是常见的策略:

1. 无论是添加、查询还是删除数据,都先将数据的 id 通过哈希函数转换成一个哈希值,记为 key
2. 如果目前机器有 N 台,则计算 key%N 值,这个值就是该数据所属的的机器编号,无论是添加、删除还是查询操作,都只在这台机器上进行

请分析这种缓存策略可能带来的问题,并提出改进的方案。
 

07Lars-lbAgentV0.2-route_lb获取host信息不存在

#### A. 普通 Hash 算法

缓存策略的潜在问题是如果增加或删除机器时(N 变化)代价会很高,所有的数据都不得不根据 id 重新计算一遍哈希值,并将哈希值对新的机器数进行取模操作,然后进行大规模的数据迁移。  



#### B. 一致性Hash算法

​        为了解决这些问题,引入一致性哈希算法。假设数据的 id 通过哈希函数转换成的哈希值范围是 2的32次幂,也就是( 0,  2^32−1) 的数字空间中。我们将这些数字头尾相连,想象成一个闭合的环形,那么一个数字 id 在计算出哈希值之后认为对应到环中的一个位置上

![12-murmurHash_1](/Users/apple/Nustore%20Files/%E6%88%91%E7%9A%84%E5%9D%9A%E6%9E%9C%E4%BA%91/%E8%AF%BE%E7%A8%8B%E7%A0%94%E5%8F%91/Lars/%E8%AE%B2%E4%B9%89/pictures/12-murmurHash_1.png)

08 昨日回顾及agent获取host信息流程

​        接下来,想象有三台机器也处于这样一个环中,这三台机器在环中的位置根据机器 id 计算出的哈希值来决定。那么一条数据如何确定归属哪台机器呢?首先把该数据的 id 用哈希值算出哈希值,并映射到环中的相应位置,然后顺时针找寻离这个位置最近的机器,那台机器就是该数据的归属。例如,下图有一个数据 m,计算其 hash 值后映射到环上,那么他的归属就是 2 号机器.

![13-murmurHash_2](/Users/apple/Nustore%20Files/%E6%88%91%E7%9A%84%E5%9D%9A%E6%9E%9C%E4%BA%91/%E8%AF%BE%E7%A8%8B%E7%A0%94%E5%8F%91/Lars/%E8%AE%B2%E4%B9%89/pictures/13-murmurHash_2.png)


​        普通 hash 求余算法最为不妥的地方就是在有机器的添加或者删除之后会照成大量的对象存储位置失效,这样就大大的不满足单调性了。下面来分析一下一致性哈希算法是如何处理的.

09 Lars-LbAgentV0.2-Api获取主机信息-更新流程梳理

##### a. 结点(机器)删除

​        以上面的分布为例,如果 Node2(机器 2)出现故障被删除了,那么按照顺时针迁移的方法,Hash 值属于图中红色片段的所有数据将会被迁移到 Node3(机器)中,这样仅仅是红色的一段映射位置发生了变化,其它的对象没有任何的改动。如下图:

![14-murmurHash_3](/Users/apple/Nustore%20Files/%E6%88%91%E7%9A%84%E5%9D%9A%E6%9E%9C%E4%BA%91/%E8%AF%BE%E7%A8%8B%E7%A0%94%E5%8F%91/Lars/%E8%AE%B2%E4%B9%89/pictures/14-murmurHash_3.png)

##### b. 结点(机器)添加        



​        如果往集群中添加一个新的节点 NODE4,通过对应的哈希算法得到 KEY4,并映射到环中,如下图:

![15-murmurHash_4](/Users/apple/Nustore%20Files/%E6%88%91%E7%9A%84%E5%9D%9A%E6%9E%9C%E4%BA%91/%E8%AF%BE%E7%A8%8B%E7%A0%94%E5%8F%91/Lars/%E8%AE%B2%E4%B9%89/pictures/15-murmurHash_4.png)

10 Lars-LbAgentV0.2-Api-load_balance模块更新主

按照顺时针迁移的规则,数据 Hash 值处于红色段的数据被迁移到了 Node4 中,其它对象还保持这原有的存储位置。通过对节点的添加和删除的分析,一致性哈希算法在保持了单调性的同时,数据的迁移时间达到了最小,这样的算法对分布式集群来说是非常合适的,避免了大量数据迁移,减小了服务器的的压力.

​        

##### c. 一致性哈希算法优化

​        其实上面的一致性哈希函数还存在一个很大的问题,我们说 Hash 函数是输入的样本量很大的时候,其输出结果在输出域上是均匀分布的,但是这里假如只有三个输入,就很难保证分布是均匀的,有可能产生下图所示的分布,就导致负载极其不均衡

![16-murmurHash_5](/Users/apple/Nustore%20Files/%E6%88%91%E7%9A%84%E5%9D%9A%E6%9E%9C%E4%BA%91/%E8%AF%BE%E7%A8%8B%E7%A0%94%E5%8F%91/Lars/%E8%AE%B2%E4%B9%89/pictures/16-murmurHash_5.png)

​        更加优化的一致性哈希算法引入了虚拟节点机制,即对每一台机器产生多个结点,称为虚拟节点。具体做法可以在机器 ip 或主机名的后面增加编号或端口号来实现。假设一台机器有 1000 个虚拟节点,3 台机器就有 3000 个结点,3000 个结点映射到哈希域上就相对比较均匀了.

11 Lars-LbAgentV0.2-Api目录结构创建

​        为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。具体做法可以在服务器ip或主机名的后面增加编号来实现。例如上面的情况,可以为每台服务器计算三个虚拟节点,于是可以分别计算 “Node A#1”、“Node A#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”的哈希值,于是形成六个虚拟节点:

![17-murmurHash_6](/Users/apple/Nustore%20Files/%E6%88%91%E7%9A%84%E5%9D%9A%E6%9E%9C%E4%BA%91/%E8%AF%BE%E7%A8%8B%E7%A0%94%E5%8F%91/Lars/%E8%AE%B2%E4%B9%89/pictures/17-murmurHash_6.png)



> 更加详细的一致性hash介绍参考: <https://www.jianshu.com/p/92588bbe8a22>
 

12 Lars-LbAgentV0.2-Api创建udp连接实现-lars-lbagent启动失败修正

13 Lars-LbAgentV0.2-Api-getHost请求实现

14 Lars-LbAgentV0.2-loadBalance-选择主机业务实现

15 Lars-LbAgentV0.3-api-get_hostAPI接口测试

16Lars-LbAgentV0.3-api-get_hostAPI流程总结

17 Lars-LbAgentV0.4-api-上报业务实现

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

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

相关文章

2025系统架构师---论软件的设计模式论文

2023 年,我所在的公司承担了某部网络靶场的研发任务。我作为公司的技 术总监,希望能打造基于网络靶场的系列产品,参与到项目的设计中,以期开发 扩展性和可维护性良好的网络靶场,为以后的产品开发打下基础。网络靶场是网 络安全技术研究的基础支撑平台,它利用虚拟的和实物…

Kubernetes排错(七)-节点排错

1、节点 Crash 与 Vmcore 分析 kdump 介绍​ 目前大多 Linux 发新版都会默认开启 kdump 服务&#xff0c;以方便在内核崩溃的时候, 可以通过 kdump 服务提供的 kexec 机制快速的启用保留在内存中的第二个内核来收集并转储内核崩溃的日志信息(vmcore 等文件), 这种机制需要服务…

【QT】QT中的软键盘设计

QT的软键盘设计 1.软键盘制作步骤2.介绍有关函数的使用3.出现的编译错误及解决办法示例代码1&#xff1a;按键事件实现软键盘现象&#xff1a;示例代码2&#xff1a;按键事件实现软键盘&#xff08;加特殊按键&#xff09;现象&#xff1a; 软键盘移植到新的工程的步骤&#xf…

【LaTeX+VSCode本地Win11编译教程】

LaTeXVSCode本地编译教程参考视频&#xff1a; LaTeXVSCode本地编译教程 下面提供一种Win11的Latex环境配置和设置方案&#xff0c;首先vscode安装参考博客&#xff1a;【VscodeGit教程】&#xff0c;然后准备安装Latex相关组件 在 https://miktex.org/download 下载 miktex 并…

2025五一杯数学建模ABC题赛题已出

2025五一杯数学建模ABC题赛题已出 A: B: C:

Springclound常用五大组件及其使用原理

注册中心Eureka Eureka-Server&#xff1a;就是服务注册中心&#xff08;可以是一个集群&#xff09;&#xff0c;对外暴露自己的地址。 提供者&#xff1a;启动后向Eureka注册自己信息&#xff08;地址&#xff0c;服务名称等&#xff09;&#xff0c;并且定期进行服务续约 …

Docker —— 隔离的基本操作(2)

Docker —— 隔离的基本操作&#xff08;2&#xff09; unshareunshare 命令详解基本语法常用选项常用示例实际应用场景注意事项与 Docker 的关系1. 执行命令2. 修改主机名3. 退出命名空间4. 验证宿主机主机名关键原理类比 Docker 容器总结 实战操作一&#xff08;PID 隔离&…

Java List分页工具

PageUtil.java import com.google.common.collect.Lists; import com.jd.platform.hotkey.dashboard.common.domain.Page; import org.springframework.util.CollectionUtils;import java.util.ArrayList; import java.util.List;public class PageUtil {/*** 通用分页工具类*…

中阳策略:如何从K线行为中提取交易逻辑信号?

中阳策略&#xff1a;如何从K线行为中提取交易逻辑信号&#xff1f; 在量化趋势研究中&#xff0c;中阳形态常被视作市场动能变化的重要标志。它不仅代表价格的强势上行&#xff0c;更隐含着主力资金换手与情绪转换的信号。将“中阳”这一结构元素抽象为模型中的“强动能突破”…

Java SE(8)——继承

1.继承的概念&作用 在Java中&#xff0c;继承是面向对象编程的三大基本特性之一&#xff08;还有封装和多态&#xff09;&#xff0c;允许一个类&#xff08;子类/继承类&#xff09;继承另一个类&#xff08;父类/基类&#xff09;的属性和方法 继承的核心目的是&#xf…

Python爬虫(18)反爬攻防战:动态IP池构建与代理IP实战指南(突破95%反爬封禁率)

目录 引言一、背景&#xff1a;为什么代理IP是爬虫的“第二生命”&#xff1f;1.1 反爬系统的IP检测三把刀1.2 代理IP的核心价值 二、基础实战&#xff1a;快速搭建代理IP系统2.1 免费代理IP的获取与筛选2.2 代理IP的智能容错机制 三、高阶攻防&#xff1a;突破企业级反爬封锁3…

LFU算法解析

文章目录 LFU缓存中关键变量的访问与更新机制1. min_freq - 最小频率访问时机更新时机更新示例 2. capacity - 缓存容量访问时机更新时机访问示例 3. key_to_node - 键到节点的映射访问时机更新时机更新示例 4. freq_to_dummy - 频率到链表哑节点的映射访问时机更新时机更新示例…

ByteArrayInputStream 类详解

ByteArrayInputStream 类详解 ByteArrayInputStream 是 Java 中用于从字节数组读取数据的输入流&#xff0c;位于 java.io 包。它允许将内存中的字节数组当作输入流来读取&#xff0c;是处理内存数据的常用工具。 1. 核心特性 内存数据源&#xff1a;从字节数组&#xff08;b…

rvalue引用()

一、先确定基础:左值(Lvalue)和右值(Rvalue) 理解Rvalue引用,首先得搞清楚左值和右值的概念。 左值(Lvalue):有明确内存地址的表达式,可以取地址。比如变量名、引用等。 复制代码 int a = 10; // a是左值 int& ref = a; // ref也是左值右值(Rval…

吴恩达深度学习作业 RNN模型——字母级语言模型

一. 简单复习一下RNN RNN RNN适用于处理序列数据&#xff0c;令是序列的第i个元素&#xff0c;那么就是一个长度为的序列&#xff0c;NLP中最常见的元素是单词&#xff0c;对应的序列是句子。 RNN使用同一个神经网络处理序列中的每一个元素。同时&#xff0c;为了表示序列的…

基于python的哈希查表搜索特定文件

Python有hashlib库&#xff0c;支持多种哈希算法&#xff0c;比如MD5、SHA1、SHA256等。通常SHA256比较安全&#xff0c;但MD5更快&#xff0c;但可能存在碰撞风险&#xff0c;得根据自己需求决定。下面以SHA256做例。 import hashlib import os from typing import Dict, Lis…

idea创建springboot项目无法创建jdk8原因及多种解决方案

idea创建springboot项目无法创建jdk8原因及多种解决方案 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&#x…

【C++进阶十】多态深度剖析

【C进阶十】多态深度剖析 1.多态的概念及条件2.虚函数的重写3.重写、重定义、重载区别4.C11新增的override 和final5.抽象类6.虚表指针和虚表6.1什么是虚表指针6.2指向谁调用谁&#xff0c;传父类调用父类&#xff0c;传子类调用子类 7.多态的原理8.单继承的虚表状态9.多继承的…

面向网络安全的开源 大模型-Foundation-Sec-8B

1. Foundation-Sec-8B 整体介绍 Foundation-Sec-8B 是一个专注于网络安全领域的大型语言模型 (LLM),由思科的基础人工智能团队 (Foundation AI) 开发 。它基于 Llama 3.1-8B 架构构建,并通过在一个精心策划和整理的网络安全专业语料库上进行持续预训练而得到增强 。该模型旨在…

Python爬虫的基础用法

Python爬虫的基础用法 python爬虫一般通过第三方库进行完成 导入第三方库&#xff08;如import requests &#xff09; requests用于处理http协议请求的第三方库,用python解释器中查看是否有这个库&#xff0c;没有点击安装获取网站url&#xff08;url一定要解析正确&#xf…