当前位置: 首页 > news >正文

深入探索Flink的复杂事件处理CEP

深入探索Flink的复杂事件处理CEP

引言

在当今大数据时代,实时数据处理变得愈发关键。Apache Flink作为一款强大的流处理框架,其复杂事件处理(CEP)组件为我们从海量实时数据中提取有价值信息提供了有力支持。本文将详细介绍Flink CEP的相关概念、核心API以及实际应用案例,帮助读者深入理解并掌握这一强大的技术。

一、CEP基础概念

复杂事件处理(CEP)定义

CEP是一种基于流处理的技术,它将系统产生的数据看作是不同类型的事件。通过深入分析这些事件之间的内在关系,构建起多样化的事件关系序列库。在此基础上,运用过滤、关联、聚合等先进技术手段,能够从简单的基础事件中衍生出高级事件。并且,借助模式规则,我们可以精准地对重要信息进行跟踪和深度分析,从而在实时数据的海洋中发掘出隐藏的、具有高价值的信息宝藏。CEP在多个领域展现出了强大的应用潜力,例如在防范网络欺诈方面,能够实时监测异常的交易行为模式;在设备故障检测中,及时发现设备运行数据中的异常事件序列,提前预警故障风险;在风险规避领域,帮助企业快速识别潜在的市场风险因素;在智能营销场景下,精准捕捉客户的行为模式,实现个性化的营销策略制定。

Flink CEP简介

Flink基于其强大的DataStrem API构建了专门用于复杂事件处理的Flink CEP组件栈。这个组件栈为用户提供了一套完整且高效的工具集,使得用户能够方便快捷地从流式数据中挖掘出那些具有关键价值的信息。Flink CEP的出现,极大地丰富了Flink在实时数据处理领域的应用场景和处理能力,让用户能够更加灵活地应对各种复杂多变的业务需求。

CEP底层原理

CEP的底层核心是状态(stat)机制。通过对事件流中的事件进行状态管理,CEP能够有效地跟踪事件的发生顺序、次数以及事件之间的关联关系等关键信息。这种基于状态的设计使得CEP能够处理复杂的事件模式,并且在面对大规模、高并发的事件流时,依然能够保持高效、稳定的性能表现。

二、CEP关键要素

配置依赖

在正式开始使用Flink CEP组件之前,我们需要将Flink CEP的依赖库准确无误地引入到项目工程中。这一步骤是确保后续CEP功能正常运行的基础,就如同建造高楼大厦前需要准备好坚实的基石一样。只有正确配置了依赖,我们才能在项目中顺利地调用Flink CEP提供的各种强大功能。

事件定义

简单事件

简单事件广泛存在于我们的现实业务场景之中。其最显著的特点是专注于处理单一的事件个体。这类事件的定义通常较为直观,我们可以通过直接观察和简单的业务规则来明确其内涵。在实际的数据处理过程中,简单事件不需要我们过多地关注多个事件之间的复杂关联关系。相反,我们可以运用一些基本的、常见的数据处理方法和工具,轻松地将我们所需要的结果计算出来。例如,在一个简单的电商订单系统中,记录用户下单这一事件就可以看作是一个简单事件,我们只需要关注订单的基本信息,如订单号、用户ID、下单时间等,通过简单的数据库查询或数据筛选操作,就能获取与该订单相关的统计信息。

复杂事件

相较于简单事件,复杂事件的处理范畴更加广泛和深入。它不仅仅局限于对单一事件的处理,而是将重点放在了由多个事件组合而成的复合事件上。复杂事件处理的核心任务是对事件流(Event Streaming)进行全面、细致的监测和深入分析。当特定的事件组合或事件序列发生时,复杂事件处理机制能够及时、准确地触发相应的业务动作。例如,在一个物流配送系统中,我们可以定义一个复杂事件:当一个包裹的“发货事件”发生后,在一定时间内相继出现“运输途中事件”和“到达目的地事件”,则触发通知收件人准备收件的动作。这种基于多个事件关联的处理方式,能够更加精准地反映业务流程的实际情况,为企业提供更有价值的决策依据。

三、Pattern API详解

Flink CEP中提供的Pattern API是实现复杂事件处理的关键所在。它为我们提供了一种简洁而强大的方式,用于对输入流数据的复杂事件规则进行精确、灵活的定义,并能够从事件流中高效地抽取我们所关注的事件结果。整个Pattern API的使用过程主要包含以下四个核心步骤:

输入事件流的创建

这是整个流程的起始步骤,其主要任务是读取数据源中的数据,并将其转化为Flink能够处理的事件流形式。在实际操作中,我们可以根据数据源的类型和特点,选择合适的Flink数据源连接器,如从Kafka、文件系统、数据库等数据源中读取数据,并通过一系列的数据转换操作,将原始数据转换为具有明确业务含义的事件对象流。例如,我们可以从Kafka主题中读取用户行为日志数据,每条日志记录经过解析和封装后,成为一个代表用户行为的事件对象,进而形成一个持续不断的事件流,为后续的复杂事件处理提供数据基础。

Pattern的定义

这一步骤是Pattern API中最为关键和复杂的部分,也是整个CEP处理过程中的核心环节之一。在这一步中,我们需要根据具体的业务需求,运用Pattern API提供的丰富方法和语法,精确地定义出我们所期望的事件模式。例如,我们可以定义一个模式来检测用户在短时间内连续多次登录失败的情况,或者定义一个模式来寻找在一定时间范围内,某个设备的多个传感器数据出现异常波动的事件序列。在定义模式时,我们可以灵活地设置事件的发生次数、事件之间的顺序关系、事件的属性条件等关键要素,从而构建出高度定制化的事件模式,以满足各种复杂多变的业务场景需求。

Pattern应用在事件流上检测

在完成了模式的定义之后,我们需要将定义好的模式应用到实际的事件流上,进行实时的模式匹配检测。这一步骤的实现相对较为固定,主要是通过调用Flink CEP提供的特定方法,将事件流和模式进行关联,并启动CEP的内部检测机制。在检测过程中,CEP会自动对事件流中的每一个事件进行分析和判断,根据模式定义的规则,确定哪些事件序列符合我们预先设定的模式要求。一旦发现匹配的事件序列,CEP会将其标记并记录下来,以便后续进行结果提取和进一步的业务处理。

选取结果

当CEP完成了对事件流的模式检测后,我们就需要从检测结果中选取我们真正感兴趣的事件信息,这一步骤也是Pattern API使用过程中的一个重要环节。目前,在Flink CEP中,为我们提供了多种灵活的方法来从PatternStream中提取事件结果事件,例如select和flatSelect方法等。这些方法允许我们根据自己的业务逻辑和数据处理需求,对匹配到的事件序列进行进一步的加工和转换,最终提取出我们所需要的关键数据和业务信息。例如,我们可以通过select方法将匹配到的事件序列中的某些特定属性提取出来,进行统计分析或业务规则判断;或者通过flatSelect方法,对匹配事件进行更复杂的处理,如将多个相关事件进行合并、拆分或转换,以生成更符合业务需求的结果数据结构。

四、CEP应用案例剖析

案例一:连续登录失败的用户检测

假设我们拥有一份log4j日志数据,记录了用户的登录行为信息。我们的目标是检测出那些连续多次登录失败的用户账号,以便及时采取相应的安全措施,如锁定账号、发送验证码或通知用户修改密码等。

在实现这个案例时,我们需要运用Flink CEP的Pattern API来定义相应的事件模式。具体的语法如下:

  • times:通过times方法,我们可以明确要求某个事件(如登录失败事件)必须连续出现指定的次数,例如3次。这使得我们能够精准地捕捉到连续登录失败的行为模式,而不仅仅是偶尔的一次登录失败情况。
  • consecutive:该方法用于强调事件的连续性。当我们使用consecutive()方法时,CEP会严格按照事件的发生顺序,寻找连续出现的符合条件的事件序列。如果没有添加此方法,则表示事件在时间上可以不连续,只要满足其他条件即可,这为我们提供了更灵活的模式定义方式,以适应不同的业务场景需求。
  • Pattern.begin(“first”,AfterMatchSkipStrategy.skipPastLastEvent()):这部分代码定义了模式的起始点,并指定了一种匹配后跳过策略。具体来说,begin(“first”)表示我们将这个模式的起始事件命名为"first",而AfterMatchSkipStrategy.skipPastLastEvent()则表示一旦某个事件序列被匹配成功,CEP将跳过已经匹配过的事件,从没有匹配的地方重新开始寻找下一个符合条件的事件序列。这种策略在处理连续登录失败的场景中非常重要,它能够确保我们不会对已经检测到的连续登录失败事件序列进行重复计算,从而提高检测的准确性和效率。
  • begin().where().next().where():这是一种常见的模式定义语法,用于匹配多个连续的事件,并且这些事件可以是不同类型的。例如,我们可以先定义一个起始事件(如登录请求事件),然后通过where方法设置该事件的一些属性条件(如登录结果为失败),接着使用next()方法表示下一个事件,再通过where方法设置下一个事件的条件,以此类推,逐步构建出一个完整的、复杂的事件模式。这种灵活的语法结构使得我们能够根据实际业务需求,精确地定义出各种复杂的事件序列模式,从而实现对特定业务场景的精准监测和分析。

案例二:两个事件且有超时情况的处理

在某些业务场景中,我们需要关注两个事件之间的时间间隔,并在时间间隔超过一定阈值时进行相应的处理。例如,在一个在线支付系统中,我们可能需要检测用户在发起支付请求后,如果在一定时间内(如10分钟)没有收到支付成功的回调通知,就需要采取一些措施,如主动查询支付状态、通知用户支付可能出现问题或进行支付超时的业务逻辑处理等。

在这个案例中,所谓的超时(或迟到)是指第一个事件(如支付请求事件)和第二个事件(如支付成功回调事件)之间的时间间隔大约为10分钟,但如果超过了10分钟05秒,则认为是触发了一种特殊的业务情况(如支付异常)。通过Flink CEP,我们可以轻松地定义这样的事件模式,并在超时情况发生时及时进行处理,从而确保业务系统的稳定性和可靠性,提升用户体验。

案例三:检测10分钟内同一卡号两笔消费位置不同

在金融领域的风险防控场景中,我们常常需要对信用卡或银行卡的消费行为进行实时监测,以防范盗刷等风险事件的发生。例如,我们希望检测出在10分钟内,同一银行卡号发生了两笔消费,且这两笔消费的地理位置不同的情况。这种异常的消费行为模式可能暗示着该银行卡存在被盗刷的风险,需要及时进行预警和处理。

虽然这个案例最初是通过SQL编写实现的,但我们也可以思考如何使用代码来实现同样的功能。通过Flink CEP,我们可以利用其强大的事件处理能力和灵活的模式定义语法,构建一个能够实时监测这种消费行为模式的CEP应用程序。具体的实现思路可能包括:首先,从数据源(如银行交易流水数据)中读取消费事件流,然后使用Pattern API定义一个模式,该模式要求在10分钟的时间窗口内,检测到同一银行卡号的两个消费事件,并且这两个事件的消费位置属性不同。最后,通过设置合适的结果选取方法,将符合条件的异常消费事件序列提取出来,并发送给相应的风险预警系统或业务处理模块,以便及时采取措施,如冻结账户、通知持卡人核实交易等,从而有效地降低金融风险。

五、自定义反序列化工具类示例

在Flink的实际应用中,数据的序列化和反序列化是一个非常重要的环节。特别是在与外部数据源(如Kafka)进行数据交互时,我们往往需要根据数据的格式和业务需求,自定义反序列化工具类,以确保数据能够正确地被Flink读取和处理。

以下是一个简单的Java代码示例,展示了如何在Flink项目中自定义反序列化工具类,用于将从Kafka主题中读取的JSON格式数据转换为我们自定义的事件对象(如PayEvent):

package com.bigdata.test;import com.alibaba.fastjson2.JSON;
import com.bigdata.bean.PayEvent;
import com.bigdata.schema.JSONDeserializationSchema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;import java.util.Properties;//{"userId":"1","type":"create","ts":"2023-07-18 10:10:10"}
//{"userId":"1","type":"create","ts":"2023-07-18 10:14:10"}
//{"userId":"1","type":"pay","ts":"2023-07-18 10:14:11"}
//{"userId":"1","type":"pay","ts":"2023-07-18 10:14:11"}
//{"userId":"1","type":"xxx","ts":"2023-07-18 10:14:12"}
public class TestCepDemo02 {public static void main(String[] args) throws Exception {StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setParallelism(1);Properties properties = new Properties();properties.setProperty("bootstrap.servers","bigdata01:9092");properties.setProperty("group.id","g1");//FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer("topic1",new SimpleStringSchema(), properties);FlinkKafkaConsumer<PayEvent> consumer = new FlinkKafkaConsumer("topic1",new JSONDeserializationSchema<PayEvent>(PayEvent.class), properties);DataStreamSource<PayEvent> ds1 = env.addSource(consumer);ds1.print();/*// 我们写了一个map算子就是为了将json字符串转换为实体,太不划算了。ds1.map(new MapFunction<String, PayEvent>() {@Overridepublic PayEvent map(String s) throws Exception {return JSON.parseObject(s, PayEvent.class);}}).print();*/env.execute();}
}

在上述代码中,我们首先创建了Flink的执行环境,并设置了相应的并行度。然后,我们配置了Kafka的连接属性,包括Kafka服务器地址和消费者组ID等信息。接下来,我们使用自定义的JSONDeserializationSchema来创建FlinkKafkaConsumer,该反序列化器能够将从Kafka主题中读取的JSON数据转换为我们定义的PayEvent对象。最后,我们将数据源添加到Flink的执行环境中,并通过print方法将处理后的数据输出到控制台,以便进行调试和查看。

通过这个示例,我们可以看到如何在Flink项目中灵活地自定义反序列化工具类,以满足不同数据源和数据格式的处理需求,从而确保整个数据处理流程的顺畅和高效。

六、总结

通过本文对Flink的复杂事件处理CEP的详细介绍,我们深入了解了CEP的基本概念、核心原理、关键要素以及实际应用案例。Flink CEP作为一种强大的实时数据处理技术,为我们在众多领域中应对复杂的业务场景提供了有效的解决方案。

相关文章:

深入探索Flink的复杂事件处理CEP

深入探索Flink的复杂事件处理CEP 引言 在当今大数据时代&#xff0c;实时数据处理变得愈发关键。Apache Flink作为一款强大的流处理框架&#xff0c;其复杂事件处理&#xff08;CEP&#xff09;组件为我们从海量实时数据中提取有价值信息提供了有力支持。本文将详细介绍Flink…...

clickhouse-数据库引擎

1、数据库引擎和表引擎 数据库引擎默认是Ordinary&#xff0c;在这种数据库下面的表可以是任意类型引擎。 生产环境中常用的表引擎是MergeTree系列&#xff0c;也是官方主推的引擎。 MergeTree是基础引擎&#xff0c;有主键索引、数据分区、数据副本、数据采样、删除和修改等功…...

力扣hot100——哈希

1. 两数之和 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> ans;map<int, int> mp;for (int i 0; i < nums.size(); i) {if (mp.count(target - nums[i])) {ans.push_back(mp[target - nums[i]])…...

少样本学习之CAML算法

上下文感知元学习&#xff08;Context-Aware Meta-Learning, CAML&#xff09; 概述 在机器学习和深度学习领域&#xff0c;元学习&#xff08;Meta-Learning&#xff09;旨在通过学习如何学习&#xff0c;使模型能够在面对新任务时快速适应。传统的元学习方法通常需要在特定…...

C# 中的闭包

文章目录 前言一、闭包的基本概念二、匿名函数中的闭包1、定义和使用匿名函数2、匿名函数捕获外部变量3、闭包的生命周期 三、Lambda 表达式中的闭包1、定义和使用 Lambda 表达式2、Lambda 表达式捕获外部变量3、闭包的作用域 四、闭包的应用场景1、事件处理2、异步编程3、迭代…...

网络编程 03:端口的定义、分类,端口映射,通过 Java 实现了 IP 和端口的信息获取

一、概述 记录时间 [2024-12-19] 前置文章&#xff1a; 网络编程 01&#xff1a;计算机网络概述&#xff0c;网络的作用&#xff0c;网络通信的要素&#xff0c;以及网络通信协议与分层模型 网络编程 02&#xff1a;IP 地址&#xff0c;IP 地址的作用、分类&#xff0c;通过 …...

制作项目之前的分析

对网页的分析可以从多个角度入手&#xff0c;具体包括内容分析、技术分析、用户体验分析。 以下是对网页分析的详细步骤&#xff0c;帮助你从不同维度评估一个网页的效果与质量&#xff1a; 1. 内容分析 内容是网页最核心的部分&#xff0c;确保其符合用户需求是网页设计的首…...

LeetCode 1925 统计平方和三元组的数目

探索平方和三元组&#xff1a;从问题到 Java 代码实现 在数学与编程的交叉领域&#xff0c;常常会遇到一些有趣且富有挑战性的问题。今天&#xff0c;就让我们深入探讨一下 “平方和三元组” 这个有趣的话题&#xff0c;并使用 Java 语言来实现计算满足特定条件的平方和三元组…...

java开发入门学习三-二进制与其他进制

常见的进制 常用的进制有二进制&#xff0c;八进制&#xff0c;十进制&#xff0c;十六进制。而我们最熟悉的是十进制&#xff0c;他们分别是怎么表达的呢&#xff1f; 定义不同的进制&#xff0c;写法不同 二进制&#xff08;Binary&#xff09;&#xff1a; 使用前缀 0b 或…...

C/S软件授权注册系统(Winform+WebApi+.NET8+EFCore版)

适用软件&#xff1a;C/S系统、Winform桌面应用软件。 运行平台&#xff1a;Windows .NETCore&#xff0c;.NET8 开发工具&#xff1a;Visual Studio 2022&#xff0c;C#语言 数据库&#xff1a;Microsoft SQLServer 2012&#xff0c;Oracle 21c&#xff0c;MySQL8&#xf…...

Linux —— 管理进程

一、查看进程 运行态&#xff08;Running&#xff09; 定义&#xff1a;处于运行态的进程正在 CPU 上执行指令。在单 CPU 系统中&#xff0c;同一时刻只有一个进程处于运行态&#xff1b;在多 CPU 或多核系统中&#xff0c;可能有多个进程同时处于运行态。示例&#xff1a; 当…...

Diffusino Policy学习note

Diffusion Policy—基于扩散模型的机器人动作生成策略 - 知乎 建议看看&#xff0c;感觉普通实验室复现不了这种工作。复现了也没有太大扩展的意义。 Diffusion Policy 是监督学习吗 Diffusion Policy 通常被视为一种基于监督学习的方法&#xff0c;但它的实际训练过程可能结…...

【Python】*args和**kwargs

【Python】*args和**kwargs 一、*args: 接收不定数量的位置参数示例1&#xff1a;简单的加法计算器示例2&#xff1a;转发参数给另一个函数 二、**kwargs: 接收不定数量的关键字参数示例3&#xff1a;创建用户配置文件示例4&#xff1a;合并多个字典 三、组合使用*args和**kwar…...

使用正则表达式提取PDF文件页数的实现方案

文章目录 背景介绍实现原理代码实现1. 基础函数结构2. 页数提取逻辑3. 使用示例 正则表达式解析优点与局限性优点局限性 错误处理建议性能优化建议最佳实践建议总结参考资源 背景介绍 在Web应用开发中,我们经常需要获取上传PDF文件的页数信息。虽然可以使用pdf.js等第三方库,但…...

Android实现RecyclerView边缘渐变效果

Android实现RecyclerView边缘渐变效果 1.前言&#xff1a; 是指在RecyclerView中实现淡入淡出效果的边缘效果。通过这种效果&#xff0c;可以使RecyclerView的边缘在滚动时逐渐淡出或淡入&#xff0c;以提升用户体验。 2.Recyclerview属性&#xff1a; 2.1、requiresFading…...

springboot443旅游管理系统(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统旅游管理系统信息管理难度大&#xff0c;容错率低&#…...

利用git上传项目到GitHub

GitHub是基于git实现的代码托管。git是目前最好用的版本控制系统了&#xff0c;非常受欢迎&#xff0c;比之svn更好。 GitHub可以免费使用&#xff0c;并且快速稳定。 利用GitHub&#xff0c;你可以将项目存档&#xff0c;与其他人分享交流&#xff0c;并让其他开发者帮助你一…...

Rust之抽空学习系列(四)—— 编程通用概念(下)

Rust之抽空学习系列&#xff08;四&#xff09;—— 编程通用概念&#xff08;下&#xff09; 1、函数 函数用来对功能逻辑进行封装&#xff0c;能够增强复用、提高代码的可读 以下是函数的主要组成部分&#xff1a; 名称参数返回类型函数体 1.1、函数名称 在Rust中&…...

K-Means 聚类:数据挖掘的瑞士军刀

引言 在数据科学领域&#xff0c;聚类算法是一种非常重要的无监督学习方法&#xff0c;它能够帮助我们发现数据中的自然分组或模式。其中&#xff0c;K-Means 聚类算法因其简单高效而成为最常用的聚类算法之一。无论是市场细分、社交网络分析&#xff0c;还是图像分割等领域&a…...

项目练习:若依-前端项目的目录结构介绍

文章目录 一、目录截图二、目录讲解 一、目录截图 二、目录讲解 1、首先&#xff0c;我们可以看到&#xff0c;这个VUE项目&#xff0c;只有一个App.vue&#xff0c;所以&#xff0c;它是一个单页面系统。 这个App.vue是根组件&#xff0c;root组件。 2、public目录 在Vue 3.…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

C# WPF 左右布局实现学习笔记(1)

开发流程视频&#xff1a; https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码&#xff1a; GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用&#xff08;.NET Framework) 2.…...

用 FFmpeg 实现 RTMP 推流直播

RTMP&#xff08;Real-Time Messaging Protocol&#xff09; 是直播行业中常用的传输协议。 一般来说&#xff0c;直播服务商会给你&#xff1a; ✅ 一个 RTMP 推流地址&#xff08;你推视频上去&#xff09; ✅ 一个 HLS 或 FLV 拉流地址&#xff08;观众观看用&#xff09;…...