C++负载均衡远程调用学习之负载均衡算法与实现

news2025/5/9 23:59:22

目录

01 lars 系统架构回顾

02 lars-lbAgentV0.4-route_lb处理report业务流程

03 lars-lbAgentV0.4-负责均衡判断参数配置

04 lars-lbAgentV0.4-负载均衡idle节点的失败率判断

05 lars-lbAgentV0.4-负载均衡overload节点的成功率判断

06 lars-lbAgentV0.4-负载均衡上报提交模块

07 lars-lbAgentV0.4-数据问题修改-上报业务测试

08 lars-lbAgentV0.4-模拟器测试工具

09 lars-lbAgentV0.5-idle连续成功-overload连续失败的定期窗口重置机制

10 lars-lbAgentV0.6-loadbalance主动更新主机信息功能

11 昨日回顾

12 Lars-LbAgentV0.7-GetRouteAPI实现

13 Lars-LbAgentV0.7-Udp-server-获取路由服务业务注册

14 Lars-LbAgentV0.7-Udp-server-API和udpserver的测试


01 lars 系统架构回顾

**启动 Lars Reporter**

```bash
$ ./run_lars reporter
 

        ▄▄                                               
        ██                                               
        ██         ▄█████▄   ██▄████  ▄▄█████▄           
        ██         ▀ ▄▄▄██   ██▀      ██▄▄▄▄ ▀           
        ██        ▄██▀▀▀██   ██        ▀▀▀▀██▄           
        ██▄▄▄▄▄▄  ██▄▄▄███   ██       █▄▄▄▄▄██           
        ▀▀▀▀▀▀▀▀   ▀▀▀▀ ▀▀   ▀▀        ▀▀▀▀▀▀            
    Load balance And Remote service schedule System 
                                                         
        _____                       _                       
       |  __ \                     | |
       | |__) |___ _ __   ___  _ __| |_ ___ _ __
       |  _  // _ \ '_ \ / _ \| '__| __/ _ \ '__|
       | | \ \  __/ |_) | (_) | |  | ||  __/ |
       |_|  \_\___| .__/ \___/|_|   \__\___|_|
                  | |
                  |_|

            ITCAST(https://www.itcast.cn)
         ------------------------------------ 

create 0 thread
create 1 thread
create 2 thread
create 3 thread
create 4 thread
add msg cb msgid = 3
```





**启动 Lars dns**

```bash
$ ./run_lars dns
 

        ▄▄                                               
        ██                                               
        ██         ▄█████▄   ██▄████  ▄▄█████▄           
        ██         ▀ ▄▄▄██   ██▀      ██▄▄▄▄ ▀           
        ██        ▄██▀▀▀██   ██        ▀▀▀▀██▄           
        ██▄▄▄▄▄▄  ██▄▄▄███   ██       █▄▄▄▄▄██           
        ▀▀▀▀▀▀▀▀   ▀▀▀▀ ▀▀   ▀▀        ▀▀▀▀▀▀            
    Load balance And Remote service schedule System 
                                                         
                _____ 
               |  __ \ 
               | |  | |_ __  ___ 
               | |  | | '_ \/ __|
               | |__| | | | \__ \ 
               |_____/|_| |_|___/ 

            ITCAST(https://www.itcast.cn)
         ------------------------------------ 

create 0 thread
create 1 thread
create 2 thread
create 3 thread
create 4 thread
add msg cb msgid = 1
lars dns service ....
now route version is 1574674421
```



**启动 Lars Lb Agent**

```c
$ ./run_lars lbagent

        ▄▄                                               
        ██                                               
        ██         ▄█████▄   ██▄████  ▄▄█████▄           
        ██         ▀ ▄▄▄██   ██▀      ██▄▄▄▄ ▀           
        ██        ▄██▀▀▀██   ██        ▀▀▀▀██▄           
        ██▄▄▄▄▄▄  ██▄▄▄███   ██       █▄▄▄▄▄██           
        ▀▀▀▀▀▀▀▀   ▀▀▀▀ ▀▀   ▀▀        ▀▀▀▀▀▀            
    Load balance And Remote service schedule System 
                                                         
      _      _                                _  
     | |    | |         /\                   | | 
     | |    | |__      /  \   __ _  ___ _ __ | |_ 
     | |    | '_ \    / /\ \ / _` |/ _ \ '_ \| __| 
     | |____| |_) |  / ____ \ (_| |  __/ | | | |_ 
     |______|_.__/  /_/    \_\__, |\___|_| |_|\__| 
                              __/ | 
                             |___/  

            ITCAST(https://www.itcast.cn)
         ------------------------------------ 

```

02 lars-lbAgentV0.4-route_lb处理report业务流程

![4-Lars-agent](./pictures/4-Lars-agent.png)



LB Agent拥有5个线程,一个LB算法:

- UDP Server服务,并运行LB算法,对业务提供节点获取和节点调用结果上报服务;为了增大系统吞吐量,使用3个UDP Server服务互相独立运行LB算法:`modid+cmdid % 3 = i`的那些模块的服务与调度,由第`i+1`个UDP Server线程负责
- Dns Service Client:是dnsserver的客户端线程,负责根据需要,向dnsserver获取一个模块的节点集合(或称为获取路由);UDP Server会按需向此线程的MQ写入获取路由请求,DSS Client将MQ到来的请求转发到dnsserver,之后将dnsserver返回的路由信息更新到对应的UDP Server线程维护的路由信息中
- Report Service Client:是reporter的客户端线程,负责将每个模块下所有节点在一段时间内的调用结果、过载情况上报到reporter Service端,便于观察情况、做报警;本身消费MQ数据,UDP Server会按需向MQ写入上报状态请求

03 lars-lbAgentV0.4-负责均衡判断参数配置

## 2) 构建Lars-Agent项目    

### 2.1 构建目录结构

依次创建如下目录:

> Lars/lars_loadbalance_agent



```bash
lars_loadbalance_agent/
├── bin/
├── conf/
│   └── lars_lb_agent.conf
├── include/
├── Makefile
└── src/
```



其中Makefile如下:

```makefile
TARGET= bin/lars_lb_agent
CXX=g++
CFLAGS=-g -O2 -Wall -Wno-deprecated

BASE=../base
BASE_H=$(BASE)/include

PROTO = $(BASE)/proto
PROTO_H = $(BASE)/proto

LARS_REACTOR=../lars_reactor
LARS_REACTOR_H =$(LARS_REACTOR)/include
LARS_REACTOR_LIB=$(LARS_REACTOR)/lib  -llreactor

MYSQL=$(BASE)/mysql-connector-c
MYSQL_H=$(MYSQL)/include
MYSQL_LIB=$(MYSQL)/lib/libmysqlclient.a

OTHER_LIB = -lpthread -ldl -lprotobuf
SRC= ./src
INC= -I./include -I$(BASE_H) -I$(LARS_REACTOR_H) -I$(MYSQL_H) -I$(PROTO_H)

LIB= $(MYSQL_LIB) -L$(LARS_REACTOR_LIB) $(OTHER_LIB) 


OBJS = $(addsuffix .o, $(basename $(wildcard $(SRC)/*.cpp)))
OBJS += $(PROTO)/lars.pb.o

$(TARGET): $(OBJS)
        mkdir -p bin
        $(CXX) $(CFLAGS) -o $(TARGET) $(OBJS) $(INC) $(LIB)

%.o: %.cpp
        $(CXX) $(CFLAGS) -c -o $@ $< $(INC) 

.PHONY: clean

clean:
        -rm -f src/*.o  $(PROTO)/lars.pb.o $(TARGET)
```

​        实际上reporter、dns相似。

> conf/lars_lb_agent.conf

```ini
[reporter]
ip = 127.0.0.1
port = 7779

[dnsserver]
ip = 127.0.0.1
port = 7778
```

​        目前的基本配置文件,因为loadbalance_agent是充当reporter和dnsserver的客户端,所以需要知道对应的reporter和dnsserver的ip和port信息。

04 lars-lbAgentV0.4-负载均衡idle节点的失败率判断

### 2.2 主模块业务搭建

![19-lars-agent_1](./pictures/19-lars-agent_1.png)

​        首先我们要在主线程中,启动3个UDP Server线程,这个是提供业务层/API层的服务。然后分别启动report_client线程,用来和reporter Service进行通信,将请求上报信息发送给Reporter Service。 然后再启动dns_client线程,用来和dns service通信。

> lars_loadbalance_agent/include/main_server.h 

```c
#pragma once
#include "lars_reactor.h"
#include "lars.pb.h"


//与report_client通信的thread_queue消息队列
extern thread_queue<lars::ReportStatusRequest>* report_queue;
//与dns_client通信的thread_queue消息队列
extern thread_queue<lars::GetRouteRequest>* dns_queue;


// 启动udp server服务,用来接收业务层(调用者/使用者)的消息
void start_UDP_servers(void);

// 启动lars_reporter client 线程
void start_report_client(void);

// 启动lars_dns client 线程
void start_dns_client(void);
```

05 lars-lbAgentV0.4-负载均衡overload节点的成功率判断

> lars_loadbalance_agent/src/main_server.cpp 

```c
#include "main_server.h"
#include "lars.pb.h"

//与report_client通信的thread_queue消息队列
thread_queue<lars::ReportStatusRequest>* report_queue = NULL;
//与dns_client通信的thread_queue消息队列
thread_queue<lars::GetRouteRequest>* dns_queue = NULL;

int main(int argc, char **argv)
{
    //1 加载配置文件
    
    //2 启动udp server服务,用来接收业务层(调用者/使用者)的消息
    start_UDP_servers();
    
    //3 启动lars_reporter client 线程
    report_queue = new thread_queue<lars::ReportStatusRequest>();
    if (report_queue == NULL) {
        fprintf(stderr, "create report queue error!\n");
        exit(1);
    }
    start_report_client();
    
    //4 启动lars_dns client 线程
    dns_queue = new thread_queue<lars::GetRouteRequest>();
    if (dns_queue == NULL) {
        fprintf(stderr, "create dns queue error!\n");
        exit(1);
    }
    start_dns_client();
    

    std::cout <<"done!" <<std::endl;
    while (1) {
        sleep(10);
    }

    return 0;
}
```

06 lars-lbAgentV0.4-负载均衡上报提交模块

这里我们分别在main()中 ,开启以上线程。

​        其中`report_client`线程需要携带`thread_queue<lars::ReportStatusRequest>`消息队列通道。`agent`负责将上报请求消息`lars::ReportStatusRequest`通过thread_queue发送给reporter service。

​        其中`dns_client`线程需要携带`thread_queue<lars::GetRouteRequest>`。`agent`负责将请求modid/cmdid的route消息`lars::GetRouteRequest`通过thread_queue发送给dns service。



3个udp server的线程开辟实现如下:

> lars_loadbalance_agent/src/agent_udp_server.cpp

```c
#include "lars_reactor.h"
#include "main_server.h"


void * agent_server_main(void * args)
{
    int *index = (int*)args;
    short port = *index + 8888;
    event_loop loop;

    udp_server server(&loop, "0.0.0.0", port);

    //TODO 给server注册消息分发路由业务

    printf("agent UDP server :port %d is started...\n", port);
    loop.event_process();

    return NULL;
}

07 lars-lbAgentV0.4-数据问题修改-上报业务测试

void start_UDP_servers(void)
{
    for (int i = 0; i < 3; i ++) {
        pthread_t tid;
        
        int ret = pthread_create(&tid, NULL, agent_server_main, &i);
        if (ret == -1) {
            perror("pthread_create");
            exit(1);
        }

        pthread_detach(tid);

    }
}
```



reporter thread创建实现如下:

> lars_loadbalance_agent/src/reporter_client.cpp

```c
#include "lars_reactor.h"
#include "main_server.h"
#include <pthread.h>

void *report_client_thread(void* args)
{
    printf("report client thread start\n");
#if 0
    event_loop loop;

    //1 加载配置文件得到repoter ip + port
    std::string ip = config_file::instance()->GetString("reporter", "ip", "");
    short port = config_file::instance()->GetNumber("reporter", "port", 0);

    //2 创建客户端
    tcp_client client(&loop, ip.c_str(), port, "reporter client");

    //3 将 thread_queue消息回调事件,绑定到loop中
    report_queue->set_loop(&loop);
    report_queue->set_callback()

    //4 启动事件监听
    loop.event_process();
#endif

    return NULL;
}

08 lars-lbAgentV0.4-模拟器测试工具

void start_report_client()
{
    //开辟一个线程
    pthread_t tid;

    //启动线程业务函数
    int ret = pthread_create(&tid, NULL, report_client_thread, NULL);
    if (ret == -1) {
        perror("pthread_create");
        exit(1);
    }

    //设置分离模式
    pthread_detach(tid);
}
```



dns thread创建实现如下:

> lars_loadbalance_agent/src/dns_client.cpp

```c
#include "lars_reactor.h"
#include "main_server.h"
#include <pthread.h>

void *dns_client_thread(void* args)
{
    printf("dns client thread start\n");

    return NULL;
}

void start_dns_client()
{
    //开辟一个线程
    pthread_t tid;

    //启动线程业务函数
    int ret = pthread_create(&tid, NULL, dns_client_thread, NULL);
    if (ret == -1) {
        perror("pthread_create");
        exit(1);
    }

    //设置分离模式
    pthread_detach(tid);
}
```

09 lars-lbAgentV0.5-idle连续成功-overload连续失败的定期窗

口重置机制

### 2.3 测试lb_agentV0.1开发

编译,然后我们简单启动一下`./bin/lars_lb_agent`

```bash
$ ./bin/lars_lb_agent 
dns client thread start
report client thread start
done!
msg_router init...
server on 0.0.0.0:8888 is running...
agent UDP server :port 8888 is started...
msg_router init...
server on 0.0.0.0:8888 is running...
agent UDP server :port 8888 is started...
msg_router init...
server on 0.0.0.0:8888 is running...
agent UDP server :port 8888 is started...
...
```
 

10 lars-lbAgentV0.6-loadbalance主动更新主机信息功能

## 3) Report Client设计与实现

​        report client主要是实现thread_queue的回调业务,udp server会定期的上传上报数据到reporter,那么请求对于report client就是透传给reporter serivce即可。

> lars_loadbalance_agent/src/reporter_client.cpp

```c
#include "lars_reactor.h"
#include "main_server.h"
#include <string>
#include <pthread.h>

//typedef void io_callback(event_loop *loop, int fd, void *args);
//只要thread_queue有数据,loop就会触发此回调函数来处理业务
void new_report_request(event_loop *loop, int fd, void *args)
{
    tcp_client *client = (tcp_client*)args;

    //1. 将请求数据从thread_queue中取出,
    std::queue<lars::ReportStatusRequest>  msgs;

    //2. 将数据放在queue队列中
    report_queue->recv(msgs);
    
    //3. 遍历队列,通过client依次将每个msg发送给reporter service
    while (!msgs.empty()) {
        lars::ReportStatusRequest req = msgs.front();
        msgs.pop();

        std::string requestString;
        req.SerializeToString(&requestString);

        //client 发送数据
        client->send_message(requestString.c_str(), requestString.size(), lars::ID_ReportStatusRequest);
    }
}

11 昨日回顾

void *report_client_thread(void* args)
{
    printf("report client thread start\n");
    
    event_loop loop;

    //1 加载配置文件得到repoter ip + port
    std::string ip = config_file::instance()->GetString("reporter", "ip", "");
    short port = config_file::instance()->GetNumber("reporter", "port", 0);

    //2 创建客户端
    tcp_client client(&loop, ip.c_str(), port, "reporter client");

    //3 将 thread_queue消息回调事件,绑定到loop中
    report_queue->set_loop(&loop);
    report_queue->set_callback(new_report_request, &client);

    //4 启动事件监听
    loop.event_process();

    return NULL;
}

12 Lars-LbAgentV0.7-GetRouteAPI实现

void start_report_client()
{
    //开辟一个线程
    pthread_t tid;

    //启动线程业务函数
    int ret = pthread_create(&tid, NULL, report_client_thread, NULL);
    if (ret == -1) {
        perror("pthread_create");
        exit(1);
    }

    //设置分离模式
    pthread_detach(tid);
}
```



## 4) Dns Client设计与实现

​        dns client 和report client的业务十分相似,只是针对的协议不同了。dns client的thread_queue 回调业务主要是透传`lars::GetRouteRequest`数据包。

> lars_loadbalance_agent/src/dns_client.cpp

```c
#include "lars_reactor.h"
#include "main_server.h"
#include <pthread.h>


//typedef void io_callback(event_loop *loop, int fd, void *args);
//只要thread_queue有数据,loop就会触发此回调函数来处理业务
void new_dns_request(event_loop *loop, int fd, void *args)
{
    tcp_client *client = (tcp_client*)args;

    //1. 将请求数据从thread_queue中取出,
    std::queue<lars::GetRouteRequest>  msgs;

    //2. 将数据放在queue队列中
    dns_queue->recv(msgs);
    
    //3. 遍历队列,通过client依次将每个msg发送给reporter service
    while (!msgs.empty()) {
        lars::GetRouteRequest req = msgs.front();
        msgs.pop();

        std::string requestString;
        req.SerializeToString(&requestString);

        //client 发送数据
        client->send_message(requestString.c_str(), requestString.size(), lars::ID_GetRouteRequest);
    }

}

13 Lars-LbAgentV0.7-Udp-server-获取路由服务业务注册

void *dns_client_thread(void* args)
{
    printf("dns client thread start\n");
    event_loop loop;

    //1 加载配置文件得到dns service ip + port
    std::string ip = config_file::instance()->GetString("dnsserver", "ip", "");
    short port = config_file::instance()->GetNumber("dnsserver", "port", 0);

    //2 创建客户端
    tcp_client client(&loop, ip.c_str(), port, "dns client");

    //3 将thread_queue消息回调事件,绑定到loop中
    dns_queue->set_loop(&loop);
    dns_queue->set_callback(new_dns_request, &client);

    //4 启动事件监听
    loop.event_process(); 

    return NULL;
}


void start_dns_client()
{
    //开辟一个线程
    pthread_t tid;

    //启动线程业务函数
    int ret = pthread_create(&tid, NULL, dns_client_thread, NULL);
    if (ret == -1) {
        perror("pthread_create");
        exit(1);
    }

    //设置分离模式
    pthread_detach(tid);
}
```

14 Lars-LbAgentV0.7-Udp-server-API和udpserver的测试

## 5) 负载均衡模块基础设计(V0.2)



### 5.1 基础

​        每个模块`modid/cmdid`下有若干节点,节点的集合称为此模块的路由; 对于每个节点,有两种状态:

- `idle`:此节点可用,可作为API**(相当于Agent的客户端)**请求的节点使用;

- `overload`:此节点过载,暂时不可作为API请求的节点使用

  ​    在请求节点时,有几个关键属性:

- 虚拟成功次数`vsucc`,API汇报节点调用结果是成功时,该值+1
- 虚拟失败次数`verr`,API汇报节点调用结果是失败时,该值+1
- 连续成功次数`contin_succ`,连续请求成功的次数
- 连续失败次数`contin_err`,连续请求失败的次数

这4个字段,在节点状态改变时(idle<—>overload),会被重置。
 

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

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

相关文章

缓存(1):三级缓存

三级缓存是指什么 我们常说的三级缓存如下&#xff1a; CPU三级缓存Spring三级缓存应用架构&#xff08;JVM、分布式缓存、db&#xff09;三级缓存 CPU 基本概念 CPU 的访问速度每 18 个月就会翻 倍&#xff0c;相当于每年增⻓ 60% 左右&#xff0c;内存的速度当然也会不断…

Cursor —— AI编辑器 使用详解

Cursor - The AI Code Editor 一、Cursor 是什么&#xff1f; Cursor 是一款优秀的AI代码编辑器&#xff0c;它内置了 Deepseek-R1、GPT-4、Claude等 AI 模型。 简单说&#xff0c;就是&#xff1a;Cursor VS Code 编辑器 AI 大模型 Cursor 功能特性&#xff08;代码补全、…

Pytorch-CUDA版本环境配置

Pytorch-CUDA版本环境配置 电脑如果是Windows平台下的Nvidia GPU的用户&#xff0c;需配置Pytorch的CUDA版本&#xff0c;分为三步&#xff1a; 1. 安装或更新NVIDA显卡驱动 官方驱动下载地址&#xff1a; https://www.nvidia.cn/Download/index.aspx?langcn 2. 安装CUDA Too…

OpenCV 图形API(77)图像与通道拼接函数-----对图像进行几何变换函数remap()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 对图像应用一个通用的几何变换。 函数 remap 使用指定的映射对源图像进行变换&#xff1a; dst ( x , y ) src ( m a p x ( x , y ) , m a p y…

Spring AI 入门(持续更新)

介绍 Spring AI 是 Spring 项目中一个面向 AI 应用的模块&#xff0c;旨在通过集成开源框架、提供标准化的工具和便捷的开发体验&#xff0c;加速 AI 应用程序的构建和部署。 依赖 <!-- 基于 WebFlux 的响应式 SSE 传输 --> <dependency><groupId>org.spr…

QUIC协议优化:HTTP_3环境下的超高速异步抓取方案

摘要 随着 QUIC 和 HTTP/3 的普及&#xff0c;基于 UDP 的连接复用与内置加密带来了远超 HTTP/2 的性能提升&#xff0c;可显著降低连接握手与拥塞恢复的开销。本文以爬取知乎热榜数据为目标&#xff0c;提出一种基于 HTTPX aioquic 的异步抓取方案&#xff0c;并结合代理 IP设…

uni-app实现完成任务解锁拼图功能

界面如下 代码如下 <template><view class"puzzle-container"><view class"puzzle-title">任务进度 {{completedCount}}/{{totalPieces}}</view><view class"puzzle-grid"><viewv-for"(piece, index) in…

数据链路层(MAC 地址)

目录 一、前言&#xff1a; 二、以太网&#xff1a; 三、MAC 地址的作用&#xff1a; 四、ARP协议&#xff1a; 一、前言&#xff1a; 数据链路层主要负责相邻两个节点之间的数据传输&#xff0c;其中&#xff0c;最常见数据链路层的协议有 以太网&#xff08;通过光纤 / 网…

基于DQN的自动驾驶小车绕圈任务

1.任务介绍 任务来源: DQN: Deep Q Learning &#xff5c;自动驾驶入门&#xff08;&#xff1f;&#xff09; &#xff5c;算法与实现 任务原始代码: self-driving car 最终效果&#xff1a; 以下所有内容&#xff0c;都是对上面DQN代码的改进&#…

【Linux】Linux工具(1)

3.Linux工具&#xff08;1&#xff09; 文章目录 3.Linux工具&#xff08;1&#xff09;Linux 软件包管理器 yum什么是软件包关于 rzsz查看软件包——yum list命令如何安装软件如何卸载软件补充——yum如何找到要安装软件的下载地址 Linux开发工具Linux编辑器-vim使用1.vim的基…

基于 Spring Boot 瑞吉外卖系统开发(十一)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;十一&#xff09; 菜品启售和停售 “批量启售”、“批量停售”、操作列的售卖状态绑定单击事件&#xff0c;触发单击事件时&#xff0c;最终携带需要修改售卖状态的菜品id以post请求方式向“/dish/status/{params.status}”发送…

深入理解负载均衡:传输层与应用层的原理与实战

目录 前言1. 传输层&#xff08;Layer 4&#xff09;负载均衡1.1 工作层级与核心机制1.2 实现方式详解1.3 优缺点分析1.4 典型实现工具 2. 应用层&#xff08;Layer 7&#xff09;负载均衡2.1 工作层级与核心机制2.2 实现方式解析2.3 优缺点分析2.4 常用实现工具 3. Layer 4 与…

WPF之Slider控件详解

文章目录 1. 概述2. 基本属性2.1 值范围属性2.2 滑动步长属性2.3 刻度显示属性2.4 方向属性2.5 选择范围属性 3. 事件处理3.1 值变化事件3.2 滑块拖动事件 4. 样式和模板自定义4.1 基本样式设置4.2 控件模板自定义 5. 数据绑定5.1 绑定到ViewModel5.2 同步多个控件 6. 实际应用…

企业微信自建消息推送应用

企业微信自建应用来推送消息 前言 最近有个给特定部门推送消息的需求&#xff0c;所以配置一个应用专门用来推送消息。实现过程大致为&#xff1a;服务器生成每天的报告&#xff0c;通过调用API来发送消息。以前一直都是发邮件&#xff0c;整个邮箱里全是报告文件&#xff0c…

日志之ClickHouse部署及替换ELK中的Elasticsearch

文章目录 1 ELK替换1.1 Elasticsearch vs ClickHouse1.2 环境部署1.2.1 zookeeper 集群部署1.2.2 Kafka 集群部署1.2.3 FileBeat 部署1.2.4 clickhouse 部署1.2.4.1 准备步骤1.2.4.2 添加官方存储库1.2.4.3 部署&启动&连接1.2.4.5 基本配置服务1.2.4.6 测试创建数据库和…

解构与重构:自动化测试框架的进阶认知之旅

目录 一、自动化测试的介绍 &#xff08;一&#xff09;自动化测试的起源与发展 &#xff08;二&#xff09;自动化测试的定义与目标 &#xff08;三&#xff09;自动化测试的适用场景 二、什么是自动化测试框架 &#xff08;一&#xff09;自动化测试框架的定义 &#x…

DockerDesktop替换方案

背景 由于DockerDesktop并非开源软件&#xff0c;如果在公司使用&#xff0c;可能就有一些限制&#xff0c;那是不是除了使用DockerDesktop外&#xff0c;就没其它办法了呢&#xff0c;现在咱们来说说替换方案。 WSL WSL是什么&#xff0c;可自行百度&#xff0c;这里引用WS…

力扣热题100之搜索二维矩阵 II

题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 代码 方法一&#xff1a;直接全体遍历 这个方法很直接&#xff0c;但是居然没有超时&#xff0c…

docker操作镜像-以mysql为例

Docker安装使用-CSDN博客 docker操作镜像-以mysql为例 当安装一个新的镜像时可以登录https://hub.docker.com/直接搜索想要安装的镜像&#xff0c;查看文档 1&#xff09;拉取镜像 docker pull mysql 或者 docker pull mysql:版本号 然后直接跳到第4&#xff09;步即可 2…

使用OpenCV 和 Dlib 进行卷积神经网络人脸检测

文章目录 引言1.准备工作2.代码解析2.1 导入必要的库2.2 加载CNN人脸检测模型2.3 加载并预处理图像2.4 进行人脸检测2.5 绘制检测结果2.6 显示结果 3.完整代码4.性能考虑5.总结 引言 人脸检测是计算机视觉中最基础也最重要的任务之一。今天我将分享如何使用dlib库中的CNN人脸检…