Flume实战--Flume中的拦截器详解与操作

        在处理大规模数据流时,Apache Flume 是一款功能强大的数据聚合工具,它可以通过拦截器在运行时对Event进行修改或丢弃。本文将详细讲解Flume中的拦截器,包括时间戳拦截器、Host添加拦截器、静态拦截器以及如何自定义拦截器。

Flume入门到实践--Flume的安装与基础概念与安装实战-CSDN博客

拦截器

拦截器的作用

拦截器用于在事件流经Flume时,对其进行拦截、处理(比如修改、增强)、或者丢弃。

1. 时间戳拦截器

        时间戳拦截器是Flume中非常实用的一个功能,它会自动为每个Event的header添加一个当前的时间戳。这对于后续的数据存储和分析非常有用,尤其是在需要时间序列数据的场景中。

使用场景

        当数据需要带有时间戳存储到HDFS,并且HDFS的目录结构中包含时间转义字符时,这个拦截器非常有用。

配置示例

a1.sources.r1.interceptors = i1   
i1 是拦截器的名字,自己定义的
a1.sources.r1.interceptors.i1.type = timestamp   
指定i1 这个拦截器的类型

hdfs中,如果文件夹使用了时间相关的转义字符,比如

a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = hdfs
a1.sinks.k1.channel = c1
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minutea1.sinks.k1.hdfs.useLocalTimeStamp =true

也可以使用时间戳拦截器


a1.sources = r1
a1.channels = c1
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/data/c.txta1.sources.r1.channels = c1a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 10000a1.sinks = k1
a1.sinks.k1.type = hdfs
a1.sinks.k1.channel = c1
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/
# round 用于控制含有时间转义符的文件夹的生成规则
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minute
# i1 是拦截器的名字,自己定义的
a1.sources.r1.interceptors = i1    
a1.sources.r1.interceptors.i1.type = timestamp

因为必须保证header中有时间戳timestamp这个KV键值对。

假如hdfs中使用了时间转义字符,此时必须指定时间,两种方案

1)使用本地时间戳

a1.sinks.k1.hdfs.useLocalTimeStamp =true

2)使用时间拦截器

a1.sources.r1.interceptors = i1

a1.sources.r1.interceptors.i1.type = timestamp

2. Host添加拦截器

        Host拦截器可以将数据来源的主机名或IP地址添加到Event的header中。这对于追踪数据来源和进行数据分析时识别数据源非常有用。

配置示例

a1.sources = r1  
a1.channels = c1
a1.sinks = s1a1.sources.r1.type= http
a1.sources.r1.bind = bigdata01
a1.sources.r1.port = 6666a1.sources.r1.interceptors=i2a1.sources.r1.interceptors.i2.type=host
a1.sources.r1.interceptors.i2.preserveExisting=false
a1.sources.r1.interceptors.i2.useIP=true
a1.sources.r1.interceptors.i2.hostHeader=hostname
# hostname=192.168.233.128
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=/flume/%Y/%m/%d/%H%M
a1.sinks.s1.hdfs.filePrefix=%{hostname}
a1.sinks.s1.hdfs.fileSuffix=.loga1.sinks.s1.hdfs.rollInterval=60a1.sinks.s1.hdfs.round=true
a1.sinks.s1.hdfs.roundValue=10
a1.sinks.s1.hdfs.roundUnit=second
a1.sinks.s1.hdfs.useLocalTimeStamp=truea1.sources.r1.channels=c1
a1.sinks.s1.channel=c1这个例子可以完美的说明host拦截器是干嘛的,拦截住之后 在Header中添加一个 hostname=192.168.32.128
在hdfs想使用hostname的时候,就可以通过%{hostname}9870 hdfs的web访问端口
9820 是hdfs底层进行通信的端口jps -ml 查看java进行,带详细信息

 测试

curl 起始就是通过命令模拟浏览器
curl http://www.baidu.com
curl http://bigdata01:9870/dfshealth.html#tab-overview
curl -X POST -d '[{"headers":{"state":"USER"},"body":"this my multiplex to c1"}]' http://bigdata01:6666

3. 静态拦截器

        静态拦截器允许我们在Event的header中添加自定义的静态键值对。这在需要为数据添加额外信息时非常有用,比如添加特定的标签或分类信息。

配置示例

a1.sources.r1.interceptors = i3
a1.sources.r1.interceptors.i3.type = static
a1.sources.r1.interceptors.i3.key = name
a1.sources.r1.interceptors.i3.value = zhangsan

自定义拦截器

        Flume支持自定义拦截器,这为处理特定的数据格式或进行复杂的数据转换提供了可能。通过编写Java代码实现自定义的拦截器,我们可以对接收到的数据进行任意形式的处理。

实现步骤

  1. 创建Maven项目:导入必要的Flume和JSON处理库(如Jackson或Fastjson)。
  2. 实现Interceptor接口:编写拦截器逻辑。
  3. 打包:将编写的拦截器打包成JAR文件,并放入Flume的lib目录下。
  4. 在Flume配置文件中配置自定义拦截器。

需求

处理数据样例:
log='{
"host":"www.baidu.com",
"user_id":"13755569427",
"items":[{"item_type":"eat","active_time":156234},{"item_type":"car","active_time":156233}]
}'结果样例:
[{"active_time":156234,"user_id":"13755569427","item_type":"eat","host":"www.baidu.com"},
{"active_time":156233,"user_id":"13755569427","item_type":"car","host":"www.baidu.com"}]

创建一个maven项目

导入jar包

 xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.bigdata</groupId><artifactId>MyInterceptor</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!-- https://mvnrepository.com/artifact/org.apache.flume/flume-ng-core --><dependency><groupId>org.apache.flume</groupId><artifactId>flume-ng-core</artifactId><version>1.9.0</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.48</version></dependency></dependencies><!--可以使用maven中的某些打包插件,不仅可以帮助我们打包代码还可以打包所依赖的jar包--><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><configuration><!-- 禁止生成 dependency-reduced-pom.xml--><createDependencyReducedPom>false</createDependencyReducedPom></configuration><executions><!-- Run shade goal on package phase --><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><relocations><relocation><!-- 解决包冲突 进行转换--><pattern>com.google.protobuf</pattern><shadedPattern>shaded.com.google.protobuf</shadedPattern></relocation></relocations><artifactSet><excludes><exclude>log4j:*</exclude></excludes></artifactSet><filters><filter><!-- Do not copy the signatures in the META-INF folder.Otherwise, this might cause SecurityExceptions when using the JAR. --><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude></excludes></filter></filters><transformers><!-- 某些jar包含具有相同文件名的其他资源(例如属性文件)。 为避免覆盖,您可以选择通过将它们的内容附加到一个文件中来合并它们--><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>reference.conf</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>mainclass</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins></build></project>

打包插件: 

builder --> plugins --> plugin

插件
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.1.1</version><configuration><!-- 禁止生成 dependency-reduced-pom.xml--><createDependencyReducedPom>false</createDependencyReducedPom></configuration><executions><!-- Run shade goal on package phase --><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><relocations><relocation><!-- 解决包冲突 进行转换--><pattern>com.google.protobuf</pattern><shadedPattern>shaded.com.google.protobuf</shadedPattern></relocation></relocations><artifactSet><excludes><exclude>log4j:*</exclude></excludes></artifactSet><filters><filter><!-- Do not copy the signatures in the META-INF folder.Otherwise, this might cause SecurityExceptions when using the JAR. --><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude></excludes></filter></filters><transformers><!-- 某些jar包含具有相同文件名的其他资源(例如属性文件)。 为避免覆盖,您可以选择通过将它们的内容附加到一个文件中来合并它们--><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>reference.conf</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>mainclass</mainClass></transformer></transformers></configuration></execution></executions></plugin>
示例代码

先测试一下:

json --> java 代码解析 json --> 实体 ,实体-->json 字符串 都需要使用工具

jackson、fastjson(阿里巴巴)

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class TestJson {public static void main(String[] args) {String log="{\n" +"                 'host':'www.baidu.com',\n" +"                 'user_id':'13755569427',\n" +"                 'items':[\n" +"                     {\n" +"                         'item_type':'eat',\n" +"                         'active_time':156234\n" +"                        },\n" +"                     {\n" +"                         'item_type':'car',\n" +"                         'active_time':156233\n" +"                     }\n" +"                  ]\n" +"}";JSONObject jsonObject = JSON.parseObject(log);String host = jsonObject.getString("host");String user_id = jsonObject.getString("user_id");System.out.println(host);System.out.println(user_id);JSONArray items = jsonObject.getJSONArray("items");List list =new ArrayList<Map<String,String>>();for (Object item : items) {// {"active_time":156234,"item_type":"eat"}Map map = new HashMap<String,String>();String itemStr = item.toString();JSONObject jsonItem = JSON.parseObject(itemStr);String active_time = jsonItem.getString("active_time");String item_type = jsonItem.getString("item_type");System.out.println(active_time);System.out.println(item_type);map.put("active_time",active_time);map.put("user_id",user_id);map.put("item_type",item_type);map.put("host",host);list.add(map);}/***  需要转化为:*      *      * [{"active_time":156234,"user_id":"13755569427","item_type":"eat","host":"www.baidu.com"},*      *      * {"active_time":156233,"user_id":"13755569427","item_type":"car","host":"www.baidu.com"}]*/String jsonString = JSON.toJSONString(list);System.out.println(jsonString);}
}
package com.bigdata;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;public class DemoInterceptor implements Interceptor {@Overridepublic void initialize() {}// 只需要关注 这个方法的写法/***  需求:*  log='{* "host":"www.baidu.com",* "user_id":"13755569427",* "items":[*     {*         "item_type":"eat",*         "active_time":156234*     },*     {*         "item_type":"car",*         "active_time":156233*     }*  ]* }'** 需要转化为:* [{"active_time":156234,"user_id":"13755569427","item_type":"eat","host":"www.baidu.com"},* {"active_time":156233,"user_id":"13755569427","item_type":"car","host":"www.baidu.com"}]*/@Overridepublic Event intercept(Event event) {// 解析 文本数据变为另一种格式byte[] body = event.getBody();String content = new String(body);/***  {*      "host":"www.baidu.com",*      "user_id":"13755569427",*      "items":[*          {*              "item_type":"eat",*              "active_time":156234*          },*          {*              "item_type":"car",*              "active_time":156233*          }*       ]*   }*/// 将一个json字符串变为 json 对象JSONObject jsonObject = JSON.parseObject(content);// 通过对象 获取 json 中的值String host = jsonObject.getString("host");String user_id = jsonObject.getString("user_id");// 通过对象获取json 数组JSONArray items = jsonObject.getJSONArray("items");// 定义一个集合,集合中是mapArrayList<HashMap<String, String>> list = new ArrayList<>();for (Object object: items) {String obj = object.toString();JSONObject jobj = JSON.parseObject(obj);String item_type = jobj.getString("item_type");String active_time = jobj.getString("active_time");HashMap<String, String> map = new HashMap<>();map.put("active_time",active_time);map.put("item_type",item_type);map.put("host",host);map.put("user_id",user_id);list.add(map);}// 将对象变为字符串String s = JSON.toJSONString(list);event.setBody(s.getBytes());return event;}// 这个方法可以调取 上面这个方法@Overridepublic List<Event> intercept(List<Event> list) {for (int i=0;i<list.size();i++) {Event oldEvent = list.get(i);Event newEvent = intercept(oldEvent);list.set(i,newEvent);}return list;}@Overridepublic void close() {}// 作用只有一个,就是new 一个自定义拦截器的类public static class BuilderEvent implements Builder{@Overridepublic Interceptor build() {return new DemoInterceptor();}@Overridepublic void configure(Context context) {}}
}

打包,上传至 flume 下的lib 下。

测试

编写一个flume脚本文件

testInter.conf

a1.sources = s1
a1.channels = c1
a1.sinks = r1a1.sources.s1.type = TAILDIR#以空格分隔的文件组列表。每个文件组表示要跟踪的一组文件
a1.sources.s1.filegroups = f1
#文件组的绝对路径
a1.sources.s1.filegroups.f1=/home/b.log#使用自定义拦截器
a1.sources.s1.interceptors = i1
a1.sources.s1.interceptors.i1.type = com.bigdata.DemoInterceptor$BuilderEventa1.channels.c1.type = file
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100a1.sinks.r1.type = hdfs
a1.sinks.r1.hdfs.path = /flume/202409
a1.sinks.r1.hdfs.fileSuffix= .log# 将上传的数据格式使用text类型,便于查看
a1.sinks.r1.hdfs.fileType=DataStream
a1.sinks.r1.hdfs.writeFormat=Texta1.sources.s1.channels = c1
a1.sinks.r1.channel = c1
运行该脚本
flume-ng agent -c ./ -f testInterceptor.conf -n a1 -Dflume.root.logger=INFO,console

 出现错误

此时,说明我们打包的时候没有将这个jar包打包到自定义的jar包,可以通过手动的提交的方式解决这个问题。

将fast-json.jar 放入到 flume/lib

通过网盘分享的文件:fastjson-1.2.48.jar

假如你使用了打包插件,已经将这个 fast-json 打入了你的 jar 包中,无需该操作。

{"host":"www.baidu.com","user_id":"13755569427","items":[{"item_type":"eat","active_time":156234},{"item_type":"car","active_time":156233}]}

接着开始进行测试,必须先启动flume

编写一个脚本,模拟 b.log 中不断的产生json数据的场景。

#!/bin/bash
log='{
"host":"www.baidu.com",
"user_id":"13755569427",
"items":[
{
"item_type":"eat",
"active_time":156234
},
{
"item_type":"car",
"active_time":156233
}
]
}'
echo $log >> /home/b.log

保存,并且赋予权限:

chmod 777 createJson.sh执行这个脚本,就可以模拟不断的向  b.log中传输数据了
./createJson.sh

 视频链接

10-时间戳拦截器_哔哩哔哩_bilibili

11-host拦截器_哔哩哔哩_bilibili

12-静态拦截器_哔哩哔哩_bilibili

13-自定义拦截器一_哔哩哔哩_bilibili

14-自定义拦截器二_哔哩哔哩_bilibili

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

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

相关文章

Centos怎么执行脚本

方法一&#xff1a;切换到shell脚本所在的目录&#xff08;此时&#xff0c;称为工作目录&#xff09;执行shell脚本 cd /data/shell ./hello.sh 方法二&#xff1a;以绝对路径的方式去执行bash shell脚本 /data/shell/hello.sh 方法三&#xff1a;直接使用bash 或sh 来执行…

VGG原理与实战

VGG网络结构 这也更好的块状结构,256个卷积核 卷积就是我们的一个特征图啊往往都会缩小 &#xff0c;然后的话但它通道不会变.卷积一般是使用我们的通道C变大,磁化但是它的通道就是我们那个H和W一般都会变小.下采样的意思就是使分辨率变小 vgg—block内的卷积层都是同结构的意…

vite学习教程04、vue集成axios封装request工具类及应用

文章目录 前言1、安装axios2、封装request工具类3、封装api请求工具4、实战&#xff1a;vue中使用api请求工具类资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝3W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技…

k8s 中存储之 hostPath 卷

目录 1 hostPath 卷介绍 2 hostPath 卷实际应用操作 2.1 创建 pod 资源类型 2.2 修改清单文件增加 hostPath 对应的参数配置 2.3 查看是否创建 卷 和 pod 2.4 创建发布文件测试是否正常访问 1 hostPath 卷介绍 EmptyDir中数据不会被持久化&#xff0c;它会随着Pod的结束而销…

【数据结构】【链表代码】随机链表的复制

/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/typedef struct Node Node; struct Node* copyRandomList(struct Node* head) {if(headNULL)return NULL;//1.拷贝结点&#xff0c;连接到原结点的后面Node…

【工欲善其事】巧用 Sublime Text 生成带格式的 HTML 片段

文章目录 【工欲善其事】巧用 Sublime Text 生成带格式的 HTML 片段1 问题由来2 操作流程步骤1&#xff1a;打开代码片段定制页步骤2&#xff1a;在新标签页输入定制 XML步骤3&#xff1a;保存定义内容步骤4&#xff1a;功能测试 3 拓展 【工欲善其事】巧用 Sublime Text 生成带…

【Python】wxPython 高 DPI 缩放问题(笔记本上字体模糊问题)

问题 使用 wxPython 编写的程序在某些高 DPI 的电脑&#xff08;通常是笔记本&#xff09;上显示出来的字体会非常模糊&#xff1a; 事实上 wxPython 是支持高 DPI 的&#xff0c;但是由于我们的程序没有显式指明支持高 DPI&#xff0c;因此系统默认不支持高 DPI&#xff0c;…

【C++驾轻就熟】vector深入了解及模拟实现

​ 目录 ​编辑​ 一、vector介绍 二、标准库中的vector 2.1vector常见的构造函数 2.1.1无参构造函数 2.1.2 有参构造函数&#xff08;构造并初始化n个val&#xff09; 2.1.3有参构造函数&#xff08;使用迭代器进行初始化构造&#xff09; 2.2 vector iterator 的使…

【GC日志和OOM日志分析】JVM GC日志和OOM Dump文件分析

1 缘起 充电、充电、充电。 增加一些必备的知识&#xff0c;帮助后续使用。 2 配置JVM参数 为分析GC日志以及OOM相关信息&#xff0c;配置JVM参数&#xff0c;分为三个部分&#xff1a; &#xff08;1&#xff09;堆内存&#xff0c;包括年轻代、最大堆内存&#xff1b; &a…

VUE 开发——Node.js学习(一)

一、认识Node.js Node.js是一个跨平台JavaScript运行环境&#xff0c;使开发者可以搭建服务器端的JavaScript应用程序 使用Node.js编写服务器端程序——编写数据接口、前端工程化&#xff1b; Node.js环境没有BOM和DOM&#xff1b; Node.js安装&#xff1a;下载node-v16.19…

深度学习----------------------注意力机制

目录 心理学不随意线索随意线索 注意力机制非参注意力池化层Nadaraya-Watson核回归参数化的注意力机制 总结注意力汇聚&#xff1a;Nadaraya-Watson核回归代码生成数据集核回归非参数注意力汇聚注意力权重该部分总代码 带参数的注意力汇聚将训练数据集转换为键和值训练带参数的…

[Linux] 进程创建、退出和等待

标题&#xff1a;[Linux] 进程创建、退出和等待 个人主页水墨不写bug &#xff08;图片来源于AI&#xff09; 目录 一、进程创建fork&#xff08;&#xff09; 1&#xff09; fork的返回值&#xff1a; 2&#xff09;写时拷贝 ​编辑3&#xff09;fork常规用法 4&#xff…

线性代数书中求解齐次线性方程组、非齐次线性方程组方法的特点和缺陷(附实例讲解)

目录 一、克拉默法则 1. 方法概述 2. 例16(1) P45 3. 特点 (1) 只适用于系数矩阵是方阵 (2) 只适用于行列式非零 (3) 只适用于唯一解的情况 (4) 只适用于非齐次线性方程组 二、逆矩阵 1. 方法概述 2. 例16(2) P45 3. 特点 (1) 只适用于系数矩阵必须是方阵且可逆 …

计算机毕业设计 基于Python的无人超市管理系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

Leecode热题100-560.和为k的子数组

给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,2,3], k…

五、类与对象包访问权限

类与对象&包&访问权限 类的定义类的概念定义和使用类对象的初始化类的成员函数 再谈基本类型运算符重载函数中缀函数空值和空类型解构包和导入访问权限控制内部类 类的定义 在之前&#xff0c;我们一直在使用顶层定义&#xff1a; 在Kotlin中&#xff0c;顶层定义&…

计算机网络:计算机网络概述 —— 网络拓扑结构

文章目录 网络拓扑总线型拓扑特点缺陷 星型拓扑特点缺陷 环型拓扑特点缺陷 网状型拓扑优点缺陷 树型拓扑特点缺陷 网络拓扑 网络拓扑指的是计算机网络中节点&#xff08;计算机、交换机、路由器等&#xff09;之间物理或逻辑连接的结构。网络拓扑定义了节点之间的布局、连接方…

基于ssm 框架的java 开发语言的 在线教育学习平台系统设计与实现 源码 论文

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud等开发框架&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆…

【高等数学学习记录】函数的极限

一、知识点 &#xff08;一&#xff09;知识结构 #mermaid-svg-Dz0Ns0FflWSBWY50 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Dz0Ns0FflWSBWY50 .error-icon{fill:#552222;}#mermaid-svg-Dz0Ns0FflWSBWY50 .erro…

ROW_NUMBER

How to rewrite a query which uses the ROW_NUMBER() window function in versions 5.7 or earlier before window functions were supported e.g., SELECT ROW_NUMBER() OVER (PARTITION BY fieldA) AS rownum, myTable.* FROM myTable; index 用不上的 Solution Assuming…