华为云CES监控与飞书通知

华为云负载均衡连接数监控与飞书通知

在云服务的日常运维中,持续监控资源状态是保障系统稳定性的关键步骤之一。本文通过一个实际案例展示了如何使用华为云的Go SDK获取负载均衡器的连接数,并通过飞书Webhook发送通知到团队群组,以便运维人员及时获取最新的监控信息。本来准备直接使用ces告警,但是看了一下模版以及最佳实践貌似没有很好的支持webhook,就直接自己使用go sdk实现了!

背景知识

在华为云上,负载均衡服务(ELB)用于分发来自客户端的网络请求到多个云服务器,确保系统在面对不同的负载情况时,仍能够提供稳定、可靠的服务。ELB的性能指标,如每分钟连接数(CPS),是反映当前系统承载能力的重要数据。通常情况下,我们希望能够实时监控这些关键指标。

随着云服务技术的成熟,大型企业往往会将监控数据集成到实时通讯工具中,便于团队成员即时查看和响应潜在的问题。本案例中选择的通讯工具是飞书,华为云Go SDK则是我们与华为云服务交互的媒介。

环境准备

华为云提供的Go SDK是一套围绕华为云API构建的开发工具包,使得开发者可以在Go语言环境中便捷地调用云服务。在这里,我们利用Cloud Eye Service (CES) 的API,通过SDK检索ELB的CPS指标数据。

安装华为云Go SDK

首先需要安装华为云Go SDK。可以通过go get命令安装所需的SDK包:

go get -u github.com/huaweicloud/huaweicloud-sdk-go-v3

安装完成后,即可在项目中引入相关的SDK模块。

初始化客户端

要与华为云的服务交互,我们需要创建并初始化一个SDK客户端。如下示例中,我们创建了用于CES(Cloud Eye Service)服务的客户端,并使用了之前提到的AK和SK进行了认证。

package main// 导入相关的包
import ("fmt""bytes""json""http""ioutil""time""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1"ces "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model"
)const (feishuWebhookURL = "xxxx" // 飞书Webhook URLak               = "xxx"  // Access Keysk               = "xxxxx" // Secret Key
)func main() {// 构建认证信息auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()// 初始化CES客户端client := ces.NewCesClient(ces.CesClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())// ...后续代码
}

设置定时器和执行任务

我们通过一个定时器来定期检查负载均衡器的最大连接数,例如:

    ticker := time.NewTicker(1 * time.Minute) // 每分钟触发检查for {select {case t := <-ticker.C:currentHour := t.Hour()// 只在既定的时间范围内执行if currentHour >= 7 && currentHour < 24 {// 我们设定在59分时收集数据if t.Minute() == 59 {go collectDataAndSendToFeishu(client)}}}}

这里限制了定时器发送的时间范围早上7点到24点执行,0点-7点默认不执行。并且执行的时间是每个小时的59分执行!

收集和发送数据

一旦定时器触发并满足条件,我们会收集负载均衡的最大连接数并发送给飞书,参考 华为云ces ShowMetricData接口:
image.png
具体实现如下,注意**ShowMetricDataRequest **中具体参数:

func collectDataAndSendToFeishu(client *ces.CesClient) {currentTime := time.Now().UTC()startTime := currentTime.Truncate(time.Hour).Add(time.Minute * 58)endTime := startTime.Add(time.Minute)startTimestamp := startTime.UnixNano() / int64(time.Millisecond)endTimestamp := endTime.UnixNano() / int64(time.Millisecond)request := &model.ShowMetricDataRequest{Namespace:  "SYS.ELB",MetricName: "m1_cps",Dim0:       "lbaas_instance_id,xxxxxx",Filter:     model.GetShowMetricDataRequestFilterEnum().MAX,Period:     int32(1),From:       startTimestamp,To:         endTimestamp,}response, err := client.ShowMetricData(request)if err != nil {fmt.Println("Error querying CES data:", err)return}fmt.Printf("CES response: %+v\n", response)// Extract max value and timestamp from the responsevar maxConnection float64var timestamp int64if response.Datapoints != nil && len(*response.Datapoints) > 0 {datapoints := *response.DatapointsmaxConnection = *datapoints[0].Maxtimestamp = datapoints[0].Timestamp}// Format the timestamp to a readable formreadableTime := time.Unix(timestamp/1000, (timestamp%1000)*int64(time.Millisecond)).Format("2006-01-02 15:04:05")// Prepare the message to send to FeishufeishuMessage := fmt.Sprintf("当前时间 %s 负载均衡最大连接数是 %.2f", readableTime, maxConnection)if err := sendToFeishuWebhook(feishuWebhookURL, feishuMessage); err != nil {fmt.Println("Error sending to Feishu webhook:", err)}
}

发送Webhook通知

最后,实现sendToFeishuWebhook方法以将消息推送到飞书。

func sendToFeishuWebhook(webhookURL string, message string) error {webhookMessage := FeishuWebhookMessage{MsgType: "text",}webhookMessage.Content.Text = messagejsonData, err := json.Marshal(webhookMessage)if err != nil {return fmt.Errorf("failed to marshal webhook message: %v", err)}req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))if err != nil {return fmt.Errorf("failed to create HTTP request: %v", err)}req.Header.Set("Content-Type", "application/json")client := &http.Client{}resp, err := client.Do(req)if err != nil {return fmt.Errorf("failed to send HTTP request: %v", err)}defer resp.Body.Close()responseBody, err := ioutil.ReadAll(resp.Body)if err != nil {return fmt.Errorf("failed to read webhook response body: %v", err)}fmt.Println("Feishu webhook response:", string(responseBody))return nil
}

完整代码:

每小时59分统计58-59分最大值发送统计到飞书:

package main
type FeishuWebhookMessage struct {MsgType string `json:"msg_type"`Content struct {Text string `json:"text"`} `json:"content"`
}const (// 定时器间隔,用于根据特定时间点触发数据检索。例如:59分时执行任务,就是(59 - 当前时间的分钟数) x 每分钟的秒数feishuWebhookURL = "xxxx"ak               = "xxx"sk               = "xxxxx"
)func main() {auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()client := ces.NewCesClient(ces.CesClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())ticker := time.NewTicker(1 * time.Minute) // Check every 10 minutes to adjust for the next 59th minute.for {select {case t := <-ticker.C:// 这里设置只在7-24点执行currentHour := t.Hour()if currentHour >= 7 && currentHour < 24 {if t.Minute() == 59 {go collectDataAndSendToFeishu(client)}}}}
}
func collectDataAndSendToFeishu(client *ces.CesClient) {currentTime := time.Now().UTC()startTime := currentTime.Truncate(time.Hour).Add(time.Minute * 58)endTime := startTime.Add(time.Minute)startTimestamp := startTime.UnixNano() / int64(time.Millisecond)endTimestamp := endTime.UnixNano() / int64(time.Millisecond)request := &model.ShowMetricDataRequest{Namespace:  "SYS.ELB",MetricName: "m1_cps",Dim0:       "lbaas_instance_id,xxxxxx",Filter:     model.GetShowMetricDataRequestFilterEnum().MAX,Period:     int32(1),From:       startTimestamp,To:         endTimestamp,}response, err := client.ShowMetricData(request)if err != nil {fmt.Println("Error querying CES data:", err)return}fmt.Printf("CES response: %+v\n", response)// Extract max value and timestamp from the responsevar maxConnection float64var timestamp int64if response.Datapoints != nil && len(*response.Datapoints) > 0 {datapoints := *response.DatapointsmaxConnection = *datapoints[0].Maxtimestamp = datapoints[0].Timestamp}// Format the timestamp to a readable formreadableTime := time.Unix(timestamp/1000, (timestamp%1000)*int64(time.Millisecond)).Format("2006-01-02 15:04:05")// Prepare the message to send to FeishufeishuMessage := fmt.Sprintf("当前时间 %s 负载均衡最大连接数是 %.2f", readableTime, maxConnection)if err := sendToFeishuWebhook(feishuWebhookURL, feishuMessage); err != nil {fmt.Println("Error sending to Feishu webhook:", err)}
}// sendToFeishuWebhook sends a message to Feishu webhook
func sendToFeishuWebhook(webhookURL string, message string) error {webhookMessage := FeishuWebhookMessage{MsgType: "text",}webhookMessage.Content.Text = messagejsonData, err := json.Marshal(webhookMessage)if err != nil {return fmt.Errorf("failed to marshal webhook message: %v", err)}req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))if err != nil {return fmt.Errorf("failed to create HTTP request: %v", err)}req.Header.Set("Content-Type", "application/json")client := &http.Client{}resp, err := client.Do(req)if err != nil {return fmt.Errorf("failed to send HTTP request: %v", err)}defer resp.Body.Close()responseBody, err := ioutil.ReadAll(resp.Body)if err != nil {return fmt.Errorf("failed to read webhook response body: %v", err)}fmt.Println("Feishu webhook response:", string(responseBody))return nil
}

运行以上代码:
img_v3_026i_b57d3d26-178b-4f64-8ade-5ecfcd3917dg.jpg

其它的扩展玩法:

每分钟检查一次,当连接数大于100报警触发

package mainimport ("bytes""encoding/json""fmt""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"ces "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/region""io/ioutil""net/http""time"
)type FeishuWebhookMessage struct {MsgType string `json:"msg_type"`Content struct {Text string `json:"text"`} `json:"content"`
}const (feishuWebhookURL = "xxxx"ak               = "xxxx"sk               = "xxxxx"
)func main() {auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()client := ces.NewCesClient(ces.CesClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())ticker := time.NewTicker(1 * time.Minute) // Check every 10 minutes to adjust for the next 59th minute.for {select {case t := <-ticker.C:// 这里设置只在7-24点执行currentHour := t.Hour()if currentHour >= 7 && currentHour < 24 {go collectDataAndSendToFeishu(client)}}}
}
func collectDataAndSendToFeishu(client *ces.CesClient) {currentTime := time.Now().UTC().Truncate(time.Minute)startTime := currentTime.Add(-1 * time.Minute)endTime := currentTimestartTimestamp := startTime.UnixNano() / int64(time.Millisecond)endTimestamp := endTime.UnixNano() / int64(time.Millisecond)request := &model.ShowMetricDataRequest{Namespace:  "SYS.ELB",MetricName: "m1_cps",Dim0:       "lbaas_instance_id,xxxxx",Filter:     model.GetShowMetricDataRequestFilterEnum().MAX,Period:     int32(1),From:       startTimestamp,To:         endTimestamp,}response, err := client.ShowMetricData(request)if err != nil {fmt.Println("Error querying CES data:", err)return}fmt.Printf("CES response: %+v\n", response)// Extract max value and timestamp from the responsevar maxConnection float64var timestamp int64if response.Datapoints != nil && len(*response.Datapoints) > 0 {datapoints := *response.DatapointsmaxConnection = *datapoints[0].Maxtimestamp = datapoints[0].Timestamp}// Format the timestamp to a readable formreadableTime := time.Unix(timestamp/1000, (timestamp%1000)*int64(time.Millisecond)).Format("2006-01-02 15:04:05")// Prepare the message to send to Feishuif maxConnection > 100 {// Prepare the alert message to send to FeishufeishuMessage := fmt.Sprintf("警告:当前时间 %s 负载均衡连接数超越100,当前数值是 %.2f", readableTime, maxConnection)if err := sendToFeishuWebhook(feishuWebhookURL, feishuMessage); err != nil {fmt.Println("Error sending to Feishu webhook:", err)}}
}// sendToFeishuWebhook sends a message to Feishu webhook
func sendToFeishuWebhook(webhookURL string, message string) error {webhookMessage := FeishuWebhookMessage{MsgType: "text",}webhookMessage.Content.Text = messagejsonData, err := json.Marshal(webhookMessage)if err != nil {return fmt.Errorf("failed to marshal webhook message: %v", err)}req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))if err != nil {return fmt.Errorf("failed to create HTTP request: %v", err)}req.Header.Set("Content-Type", "application/json")client := &http.Client{}resp, err := client.Do(req)if err != nil {return fmt.Errorf("failed to send HTTP request: %v", err)}defer resp.Body.Close()responseBody, err := ioutil.ReadAll(resp.Body)if err != nil {return fmt.Errorf("failed to read webhook response body: %v", err)}fmt.Println("Feishu webhook response:", string(responseBody))return nil
}

为了方便代码的复用性,可读性。将100作为一个可配置常量提取出来:

package mainimport ("bytes""encoding/json""fmt""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"ces "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/region""io/ioutil""net/http""time"
)type FeishuWebhookMessage struct {MsgType string `json:"msg_type"`Content struct {Text string `json:"text"`} `json:"content"`
}const (// 定时器间隔,用于根据特定时间点触发数据检索。例如:59分时执行任务,就是(59 - 当前时间的分钟数) x 每分钟的秒数feishuWebhookURL                = "xxxxx"ak                              = "xxxx"sk                              = "xxxx"loadBalancerConnectionThreshold = 100.00 // 负载均衡连接数阈值
)func main() {auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()client := ces.NewCesClient(ces.CesClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())ticker := time.NewTicker(1 * time.Minute) // Check every 10 minutes to adjust for the next 59th minute.for {select {case t := <-ticker.C:// 这里设置只在7-24点执行currentHour := t.Hour()if currentHour >= 7 && currentHour < 24 {go collectDataAndSendToFeishu(client)}}}
}
func collectDataAndSendToFeishu(client *ces.CesClient) {currentTime := time.Now().UTC().Truncate(time.Minute)startTime := currentTime.Add(-1 * time.Minute)endTime := currentTimestartTimestamp := startTime.UnixNano() / int64(time.Millisecond)endTimestamp := endTime.UnixNano() / int64(time.Millisecond)request := &model.ShowMetricDataRequest{Namespace:  "SYS.ELB",MetricName: "m1_cps",Dim0:       "lbaas_instance_id,xxxx",Filter:     model.GetShowMetricDataRequestFilterEnum().MAX,Period:     int32(1),From:       startTimestamp,To:         endTimestamp,}response, err := client.ShowMetricData(request)if err != nil {fmt.Println("Error querying CES data:", err)return}fmt.Printf("CES response: %+v\n", response)// Extract max value and timestamp from the responsevar maxConnection float64var timestamp int64if response.Datapoints != nil && len(*response.Datapoints) > 0 {datapoints := *response.DatapointsmaxConnection = *datapoints[0].Maxtimestamp = datapoints[0].Timestamp}// Format the timestamp to a readable formreadableTime := time.Unix(timestamp/1000, (timestamp%1000)*int64(time.Millisecond)).Format("2006-01-02 15:04:05")// Prepare the message to send to Feishuif maxConnection > loadBalancerConnectionThreshold {// Prepare the alert message to send to FeishufeishuMessage := fmt.Sprintf("警报:在%s,负载均衡器的连接数超过了%.2f,当前连接数:%.2f", readableTime, loadBalancerConnectionThreshold, maxConnection)if err := sendToFeishuWebhook(feishuWebhookURL, feishuMessage); err != nil {fmt.Println("Error sending to Feishu webhook:", err)}}
}// sendToFeishuWebhook sends a message to Feishu webhook
func sendToFeishuWebhook(webhookURL string, message string) error {webhookMessage := FeishuWebhookMessage{MsgType: "text",}webhookMessage.Content.Text = messagejsonData, err := json.Marshal(webhookMessage)if err != nil {return fmt.Errorf("failed to marshal webhook message: %v", err)}req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))if err != nil {return fmt.Errorf("failed to create HTTP request: %v", err)}req.Header.Set("Content-Type", "application/json")client := &http.Client{}resp, err := client.Do(req)if err != nil {return fmt.Errorf("failed to send HTTP request: %v", err)}defer resp.Body.Close()responseBody, err := ioutil.ReadAll(resp.Body)if err != nil {return fmt.Errorf("failed to read webhook response body: %v", err)}fmt.Println("Feishu webhook response:", string(responseBody))return nil
}

注意loadBalancerConnectionThresholdfloat64.

增加 MetricName多个条件

这里以弹性IP EIP与负载均衡为例,我想查询负载均衡连接数大于100报警,并根据负载均衡对应eip的四个指标:“upstream_bandwidth_usage”,“downstream_bandwidth_usage”,“upstream_bandwidth”,"downstream_bandwidth"报警,完整代码如下:

package mainimport ("bytes""encoding/json""fmt""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"ces "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/region""io/ioutil""net/http""time"
)type FeishuWebhookMessage struct {MsgType string `json:"msg_type"`Content struct {Text string `json:"text"`} `json:"content"`
}const (// 定时器间隔,用于根据特定时间点触发数据检索。例如:59分时执行任务,就是(59 - 当前时间的分钟数) x 每分钟的秒数feishuWebhookURL                = "xxxxxxx"ak                              = "xxx"sk                              = "xxxx"upstreamBandwidthThreshold      = 40    // 出网带宽阈值,单位MbpsdownstreamBandwidthThreshold    = 80    // 入网带宽阈值,单位Mbps(示例中以百分比为单位,根据实际单位调整)upstreamUsageThreshold          = 20    // 出网带宽使用率阈值,单位百分比downstreamUsageThreshold        = 40    // 入网带宽使用率阈值,单位百分比
)var metricNames = []string{"upstream_bandwidth_usage","downstream_bandwidth_usage","upstream_bandwidth","downstream_bandwidth",
}func main() {auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()client := ces.NewCesClient(ces.CesClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())ticker := time.NewTicker(time.Minute) // Check every minute.for {select {case <-ticker.C:// 每分钟执行go collectDataAndSendToFeishu(client)}}
}func collectDataAndSendToFeishu(client *ces.CesClient) {currentTime := time.Now().UTC().Truncate(time.Minute)startTime := currentTime.Add(-1 * time.Minute)endTime := currentTimestartTimestamp := startTime.UnixMilli()endTimestamp := endTime.UnixMilli()dimensionValues := "bandwidth_id,xxxx"for _, metricName := range metricNames {request := &model.ShowMetricDataRequest{Namespace:  "SYS.VPC",MetricName: metricName,Dim0:       dimensionValues, // Replace with actual dimension valueFilter:     model.GetShowMetricDataRequestFilterEnum().MAX,Period:     int32(1),From:       startTimestamp,To:         endTimestamp,}response, err := client.ShowMetricData(request)if err != nil {fmt.Printf("Error querying CES data for %s: %v\n", metricName, err)continue}if response.Datapoints == nil || len(*response.Datapoints) == 0 {fmt.Printf("No datapoints received for %s\n", metricName)continue}datapoints := *response.Datapointsvar maxUsage float64for _, point := range datapoints {if point.Max != nil {if metricName == "upstream_bandwidth" || metricName == "downstream_bandwidth" {// Convert from bits to MbitsmaxUsage = *point.Max / 1000000.0} else {maxUsage = *point.Max // for utilization metrics, which are percentages}break // Assuming there's only 1 datapoint with MAX filter}}if (metricName == "upstream_bandwidth" && maxUsage > upstreamBandwidthThreshold) ||(metricName == "downstream_bandwidth" && maxUsage > downstreamBandwidthThreshold) ||(metricName == "upstream_bandwidth_usage" && maxUsage > upstreamUsageThreshold) ||(metricName == "downstream_bandwidth_usage" && maxUsage > downstreamUsageThreshold) {alertMessage := createAlertMessage(metricName, maxUsage, endTime)if err := sendToFeishuWebhook(feishuWebhookURL, alertMessage); err != nil {fmt.Printf("Error sending to Feishu webhook: %v\n", err)}}}
}func createAlertMessage(metricName string, usage float64, endTime time.Time) string {readableTime := endTime.Add(+8 * time.Hour).Format("2006-01-02 15:04:05")var alertMessage string// 注意阈值和单位已更新,具体文本格式根据实际需要调整switch metricName {case "upstream_bandwidth":alertMessage = fmt.Sprintf("警报:在%s,出网带宽超过了%.2fMbps,当前带宽:%.2fMbps", readableTime, upstreamBandwidthThreshold, usage)case "downstream_bandwidth":alertMessage = fmt.Sprintf("警报:在%s,入网带宽超过了%.2fMbps,当前带宽:%.2fMbps", readableTime, downstreamBandwidthThreshold, usage)case "upstream_bandwidth_usage":alertMessage = fmt.Sprintf("警报:在%s,出网带宽使用率超过了%.2f%%,当前使用率:%.2f%%", readableTime, upstreamUsageThreshold, usage)case "downstream_bandwidth_usage":alertMessage = fmt.Sprintf("警报:在%s,入网带宽使用率超过了%.2f%%,当前使用率:%.2f%%", readableTime, downstreamUsageThreshold, usage)}return alertMessage
}func sendToFeishuWebhook(webhookURL string, message string) error {webhookMessage := FeishuWebhookMessage{MsgType: "text",}webhookMessage.Content.Text = messagejsonData, err := json.Marshal(webhookMessage)if err != nil {return fmt.Errorf("failed to marshal webhook message: %v", err)}req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))if err != nil {return fmt.Errorf("failed to create HTTP request: %v", err)}req.Header.Set("Content-Type", "application/json")client := &http.Client{}resp, err := client.Do(req)if err != nil {return fmt.Errorf("failed to send HTTP request: %v", err)}defer resp.Body.Close()responseBody, err := ioutil.ReadAll(resp.Body)if err != nil {return fmt.Errorf("failed to read webhook response body: %v", err)}fmt.Printf("Feishu webhook response: %s\n", responseBody)return nil
}

测试报警如下:
image.png

其他

  1. 遍历负载均衡列表,批量查询所有负载均衡连接数?发送告警时候传入负载均衡的名称?
  2. 根据负载均衡列表查询绑定的eip实例,查询所有eip对应bandwidth_id,输出所有eip的指标?

总结

此文为你展示了如何通过Go SDK获取华为云上的负载均衡最大连接数and eip指标的多个条件查询,并通过飞书Webhook发送通知的过程。以上的实现可以根据你自己的需求进行调整,比如改变监测的指标或者消息发送的方式。希望本文能帮助你更好地监控和管理华为云上的资源。

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

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

相关文章

Js的String的replace(和replaceAll(

EcmaJavascriptJs的String的 replace( 和 replaceAll( 方法 String.prototype.replaceString.prototype.replaceAll 相同点 都是String.prototype的函数都是用于字符串替换都是两个参数第一个参数都可以是正则或字符串第二参数都可以是字符串或者回调函数, 回调会传入一个参…

使用Kafka与Spark Streaming进行流数据集成

在当今的大数据时代&#xff0c;实时数据处理和分析已经变得至关重要。为了实现实时数据集成和分析&#xff0c;组合使用Apache Kafka和Apache Spark Streaming是一种常见的做法。本文将深入探讨如何使用Kafka与Spark Streaming进行流数据集成&#xff0c;以及如何构建强大的实…

zlib.decompressFile报错 【Bug已解决-鸿蒙开发】

文章目录 项目场景:问题描述原因分析:解决方案:方案1方案2此Bug解决方案总结寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了zlib.decompressFile报错 的问题。 问题: zlib.decompressFile报错,怎么解…

光伏逆变器MPPT的作用、原理及算法

MPPT是逆变器非常核心的技术&#xff0c;MPPT电压在进行光伏电站设计时一项非常关键的参数。 一、什么是MPPT&#xff1f; &#xff08;单块光伏组件的I-V、P-V曲线&#xff09; 上图中&#xff0c;光伏组件的输出电压和电流遵循I-V曲线(绿色)、P-V曲线(蓝色)&#xff0c;如果…

一篇文章学会Vim

一篇文章学会Vim 声明&#xff1a;以下内容均为我个人的理解&#xff0c;如果发现错误或者疑问可以联系我共同探讨 简介 Vim是一个高度可定制的终端文本编辑器&#xff0c;它可以很方便的创建和修改任何类型的文本。作为vi的升级版&#xff0c;有许多新的特性(以下列出的特性…

基于metersphere和supper-jacoco 测试覆盖率落地实践

一、背景及目标 背景 1、技术研发流程为测试 提供冒烟用例-开发根据用例自测-提测-开始测试&#xff0c;这一套流程&#xff0c;但是中间开发是否真实执行冒烟&#xff0c;测试并不知晓&#xff0c;而且测试提供冒烟用例是否符合标准也没法进行量化 2、公司产品属于saas产品&…

日常工作 经验总结

1,在使用vue2开发项目时,快捷有效的组件化component 若有参数传递时,可以通过这样传递 在component中: 2,上拉加载,下拉刷新 若是使用局部进行上拉加载 下拉刷新 且需要用到scroll-view时 那么需要切记scroll-view在内被mescroll-uni包裹。若场景有限 对于无数据显示…

PyTorch数据并行(DP/DDP)浅析

一直以来都是用的单机单卡训练模型&#xff0c;虽然很多情况下已经足够了&#xff0c;但总有一些情况得上分布式训练&#xff1a; 模型大到一张卡放不下&#xff1b;单张卡batch size不敢设太大&#xff0c;训练速度慢&#xff1b;当你有好几张卡&#xff0c;不想浪费&#xf…

YOLOv8改进 | 检测头篇 | ASFF改进YOLOv8检测头(全网首发)

一、本文介绍 本文给大家带来的改进机制是利用ASFF改进YOLOv8的检测头形成新的检测头Detect_ASFF,其主要创新是引入了一种自适应的空间特征融合方式,有效地过滤掉冲突信息,从而增强了尺度不变性。经过我的实验验证,修改后的检测头在所有的检测目标上均有大幅度的涨点效果,…

设计模式 七大原则

1.单一职责原则 单一职责原则&#xff08;SRP&#xff1a;Single responsibility principle&#xff09;又称单一功能原则 核心&#xff1a;解耦和增强内聚性&#xff08;高内聚&#xff0c;低耦合&#xff09;。 描述&#xff1a; 类被修改的几率很大&#xff0c;因此应该专注…

Vue: 多个el-select不能重复选择相同属性

一、场景 1.需求&#xff1a; 用户可自由选择需要修改的对象并同时修改多个属性&#xff0c;需要校验修改对象不能重复选择&#xff0c;但是可供修改属性是固定的 2.目标效果&#xff1a; 二、实现 1.主要代码&#xff1a; <template><el-selectv-model"se…

开源一套原创文本处理工具:Java+Bat脚本实现自动批量处理对账单工具

原创/朱季谦 这款工具是笔者在2018年初开发完成的&#xff0c;时隔两载&#xff0c;偶然想起这款小工具&#xff0c;于是&#xff0c;决定将其开源&#xff0c;若有人需要做类似Java批处理实现整理文档的工具&#xff0c;可参考该工具逻辑思路来实现。 该工具是运行在windos系统…

vercel部署Gemini pro

一、注册一个vercel账号&#xff08;这个东西类似于第三方的github pages&#xff0c;能部署github中的项目&#xff09; 二、注册结束后&#xff0c;填写github的账号&#xff08;需要事先在该github账号中fork一个gemini的repository&#xff09; 三、babaohuang/GeminiPro…

ssm基于vue框架和elementui组件的手机官网论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本手机官网就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&#x…

用C语言采集游戏平台数据并做行业分析

游戏一直深受90/00后的喜爱&#xff0c;有些人因为对游戏的热爱还专门成立了工作室做游戏赚钱&#xff0c;但是游戏行业赚钱走不好就会被割一波韭菜&#xff0c;那么现在什么游戏挣钱&#xff0c;什么游戏好玩认可度高&#xff1f;带着这样的问题我将利用我毕生所学&#xff0c…

【React系列】Redux(一)管理状态

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 在React的开发过程中&#xff0c;Redux对于我们是非常重要的。 但是对于很多人来说&#xff0c;初次接触redux会感觉r…

2024年HCIE认证有什么用?华为HCIE好考吗?

随着信息技术的迅速发展&#xff0c;网络工程师的需求越来越高&#xff0c;而HCIE作为华为认证体系中的最高级别认证&#xff0c;备受从业者关注。本文将深入研究2024年HCIE认证的价值、考试难度以及报名费用等方面的信息。 2024年HCIE认证有什么用? 新的一年即将到来&#x…

jmeter关联依赖---三种

1.正则表达式提取器 2.xpath取样器 3.json提取器

听GPT 讲Rust源代码--compiler(11)

File: rust/compiler/rustc_mir_transform/src/simplify.rs 在Rust源代码中&#xff0c;rust/compiler/rustc_mir_transform/src/simplify.rs文件是Rust编译器中一系列进行MIR&#xff08;中间表示&#xff09;简化的转换的实现。MIR是Rust编译器中用于进行优化和代码生成的中间…

QT_02 窗口属性、信号槽机制

QT - 窗口属性、信号槽机制 1. 设置窗口属性 窗口设置 1,标题 2,大小 3,固定大小 4,设置图标在 widget.cpp 文件中&#xff1a; //设置窗口大小,此时窗口是可以拉大拉小的 //1参:宽度 //2参:高度 this->resize(800, 600); //设置窗口标题 this->setWindowTitle("…