flink类加载器原理与隔离(flink jar包冲突)

news/发布时间2024/5/14 14:30:48

flink类加载器原理与隔离

  • Java 类加载器解决类冲突基本思想
    • 什么是 Classpath?
    • Jar 包中的类什么时候被加载?
    • 哪些行为会触发类的加载?
    • 什么是双亲委派机制?
    • 如何打破双亲委派机制?
  • Flink 类加载隔离的方案
    • Flink是如何避免类泄露的?
    • Flink 卸载用户代码中动态加载的类
    • Flink 卸载 Classloader 源码
  • flinkx 如何实现类加载隔离
    • Flink jar 的上传时机
    • Yarn 的分布式缓存
    • Flink BlobServer
    • 如何快速提交,减少上传 jar 包
    • 类加载隔离遇到的问题分析
    • Flink JobGraph Classpath 的使用
  • 遇到的问题和排查方案?

本文是转载自袋鼠云公众号的文章
不知道大家有没有遇到过,flink发布任务遇到一些奇奇怪怪的报错,很奇怪的某个类就开始报错,一步一步点击去查看,发现不知道是哪个类包的那个类在报错,其实这种情况很有可能就是jar包版本冲突。
首先为大家介绍一下Java类加载器解决类冲突的基本思想。

Java 类加载器解决类冲突基本思想

什么是 Classpath?

Classpath是JVM用到的一个环境变量,它用来指示JVM如何搜索Class。
因为Java是编译型语言,源码文件是.java,而编译后的.class文件才是真正可以被JVM执行的字节码。因此,JVM需要知道,如果要加载一个com.dtstack.HelloWorld的类,应该去哪搜索对应的HelloWorld.class文件。

所以,Classpath就是一组目录的集合,它设置的搜索路径与操作系统相关,例如:
在Windows系统上,用;分隔,带空格的目录用""括起来,可能长这样:
C:****
在MacOS & Linux系统上,用:分隔,可能长这样:
/usr*****

启动JVM时设置Classpath变量, 实际上就是给java命令传入-Classpath或-cp参数.
java -Classpath .;/Users/lzq/Java/a;/Users/lzq/Java/b com.dtstack.HelloWorld
没有设置系统环境变量,也没有传入-cp参数,那么JVM默认的Classpath为,即当前目录:
java com.dtstack.HelloWorld

Jar 包中的类什么时候被加载?

在这里插入图片描述

  • jar包准备
    Jar 包就是 zip 包,只不过后缀名字不同。用于管理分散的 .class 类。
    生成 jar 包可以用 zip 命令 zip -r ChunJun.zip ChunJun
    java -cp ./ChunJun.zip com.dtstack.HelloWorld
  • 加载
    “加载”(Loading) 阶段是整个“类加载”(Class Loading) 过程中的一个阶段,希望读者没有混淆这两个看起来很相似的名词。在加载阶段,Java虚 拟机需要完成以下三件事情:
    1.通过一个类的全限定名来获取定义此类的二进制字节流;
    2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
    3.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
  • 解析
    类或接口的解析
    假设当前代码所处的类为D,如果要把一个从未解析过的符号引用N解析为一个类或接口C的直接引用,那虚拟机完成整个解析的过程需要包括以下3个步骤:
    1.如果C不是一个数组类型,那虚拟机将会把代表N的全限定名传递给D的类加载器去加载这个类C。
    在加载过程中,由于元数据验证、字节码验证的需要,又可能触发其他相关类的加载动作,例如加载这个类的父类或实现的接口。一旦这个加载过程出现了任何异常,解析过程就将宣告失败。
    2.如果C是一个数组类型,并且数组的元素类型为对象,也就是N的描述符会是类
    似“[Ljava/lang/Integer的形式,那将会按照第一点的规则加载数组元素类型。
    如果N的描述符如前面所假设的形式,需要加载的元素类型就是“java.lang.Integer",接着由虚拟机生成一个代表该数组维度和元素的数组对象。
    3.如果上面两步没有出现任何异常,那么C在虚拟机中实际上已经成为一个有效的类或接口了,但在解析完成前还要进行符号引用验证,确认D是否具备对C的访问权限。如果发现不具备访问权限,将抛出java.lang,llegalAccessEror异常。

哪些行为会触发类的加载?

关于在什么情况下需要开始类加载过程的第一个阶段“加载”,《Java虚拟机规范》中并没有进行 强制约束,这点可以交给虚拟机的具体实现来自由把握。但是对于初始化阶段,《Java虚拟机规范》 则是严格规定了有且只有六种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之 前开始)
在这里插入图片描述 - 场景一
遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类型没有进行过初始 化,则需要先触发其初始化阶段。能够生成这四条指令的典型Java代码场景有:
1.使用new关键字实例化对象的时候。
2.读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外) 的时候。
3.调用一个类型的静态方法的时候。

  • 场景二
    使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需 要先触发其初始化。
  • 场景三
    当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  • 场景四
    当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先 初始化这个主类
  • 场景五
    当使用JDK 7新加入的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。
  • 场景六
    当一个接口中定义了JDK 8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。
    对于以上这六种会触发类型进行初始化的场景,《Java虚拟机规范》中使用了一个非常强烈的限定语 ——“有且只有”,这六种场景中的行为称为对一个类型进行主动引用。除此之外,所有引用类型的方 式都不会触发初始化,称为被动引用。

什么是双亲委派机制?

双亲委派机制,是按照加载器的层级关系,逐层进行委派,例如下图中的自定义类加载器想要加载类,它首先不会想要自己去加载,它会通过层级关系逐层进行委派,从自定义类加载器 -> App ClassLoader -> Ext ClassLoader -> BootStrap ClassLoader,如果在BootStrap ClassLoader中没有找到想要加载的类,又会逆循环加载。
在这里插入图片描述

如何打破双亲委派机制?

那么如何打破双亲委派机制呢?其实可以通过重写 loadclass 方法来实现,具体过程大家可通过更多学习了解,这里就不过多赘述。
在这里插入图片描述
在这里插入图片描述

Flink 类加载隔离的方案

接下来我们来介绍下Flink 类加载隔离的方案,Flink有两种类加载器Parent-First和Child-First,他们的区别是:

  • Parent-First:
    类似 Java 中的双亲委派的类加载机制。Parent First ClassLoader 实际的逻辑就是一个 URL ClassLoader。

  • Child-First:
    先用 classloader.parent-first-patterns.default 和 classloader.parent-first-patterns.additional 拼接的list做匹配,如果类名前缀匹配了,先走双亲委派。否则就用 ChildFirstClassLoader 先加载。

  • Child-First 存在的问题:
    每次新 new 一个 ChildFirstClassLoader,如果运行时间久的话,类似 Session 这种 TaskManager 一直不关闭的情况。任务运行多次以后,会出现元数据空间爆掉,导致任务失败。

  • Child-First 加载原理:
    在这里插入图片描述
    在这里插入图片描述

Flink是如何避免类泄露的?

大家可以参考Flink中的jira,这里面包含一些bug和处理方法:
https://issues.a@pache.org/jira/br@owse/FLINK-16245
https://issues.a@pache.org/jira/br@owse/FLINK-11205

Flink如何避免类泄露,主要是通过以下两种方法:

  1. 增加一层委派类加载器,将真正的 UserClassloader 包裹起来。

  2. 增加一个回调钩子,当任务结束的时候可以提供给用户一个接口,去释放未释放的资源。
    KinesisProducer 使用了这个钩子

final RuntimeContext ctx = getRuntimeContext();
ctx.registerUserCodeClassLoaderReleaseHookIfAbsent(KINESIS_PRODUCER_RELEASE_HOOK_NAME,()-> this.runClassLoaderReleaseHook(ctx.getUserCodeClassLoader()));

Flink 卸载用户代码中动态加载的类

卸载用户代码中动态加载的类,所有涉及动态用户代码类加载(会话)的场景都依赖于再次卸载的类。

类卸载指垃圾回收器发现一个类的对象不再被引用,这时会对该类(相关代码、静态变量、元数据等)进行移除。

当TaskManager启动或重启任务时会加载指定任务的代码,除非这些类可以卸载,否则就有可能引起内存泄露,因为更新新版本的类可能会随着时间不断的被加载积累。这种现象经常会引起OutOfMemoryError: Metaspace这种典型异常。

类泄漏的常见原因和建议的修复方式:
● Lingering Threads
确保应用代码的函数/sources/sink关闭了所有线程。延迟关闭的线程不仅自身消耗资源,同时会因为占据对象引用,从而阻止垃圾回收和类的卸载。

● Interners
避免缓存超出function/sources/sinks生命周期的特殊结构中的对象。比如Guava的Interner,或是Avro的序列化器中的类或对象。

● JDBC
JDBC驱动会在用户类加载器之外泄漏引用。为了确保这些类只被加载一次,可以将驱动JAR包放在Flink的 lib/ 目录下,或者将驱动类通过 classloader-parent-first-patterns-additional 加到父级优先加载类的列表中。

释放用户代码类加载器的钩子(hook)可以帮助卸载动态加载的类,这种钩子在类加载器卸载前执行,通常情况下最好把关闭和卸载资源作为正常函数生命周期操作的一部分(比如典型的close()方法)。有些情况下(比如静态字段)最好确定类加载器不再需要后就立即卸载。

释放类加载器的钩子可以通过
RuntimeContext.registerUserCodeClassLoaderReleaseHookIfAbsent()方法进行注册。

Flink 卸载 Classloader 源码

BlobLibraryCacheManager$ResolvedClassLoaderprivate void runReleaseHooks() {Set<map.entry> hooks = releaseHooks.entrySet();if (!hooks.isEmpty()) {for (Map.EntryhookEntry : hooks) {try {LOG.debug("Running class loader shutdown hook: {}.", hookEntry.getKey());hookEntry.getValue().run();} catch (Throwable t) {LOG.warn("Failed to run release hook '{}' for user code class loader.",hookEntry.getValue(),t);}}releaseHooks.clear();}
}

flinkx 如何实现类加载隔离

Flink jar 的上传时机

首先我们需要上传Jar包,整体流程如下图所示:

在这里插入图片描述
● Yarn Perjob
提交任务的时候上传 jar 包,会放到
hd@fs://flink03:9000/@user/root/.flink/@application_1654762357754_0140。

● Yarn Session
启动 Session 的时候,Yarn 的 App 上传 Jar 包机制,往 Session 提交任务的时候,Flink 的 Blob Server 负责收。

Yarn 的分布式缓存

在这里插入图片描述
分布式缓存机制是由各个NM实现的,主要功能是将应用程序所需的文件资源缓存到本地,以便后续任务的使用。资源缓存是用时触发的,也就是第一个用到该资源的任务触发,后续任务无需再进行缓存,直接使用即可。

根据资源类型和资源可见性,NM可将资源分成不同类型:
● 资源可见性分类
● Public
节点上所有的用户都可以共享该资源,只要有一个用户的应用程序将着这些资源缓存到本地,其他所有用户的所有应用程序都可以使用。

● Private
节点上同一用户的所有应用程序共享该资源,只要该用户其中一个应用程序将资源缓存到本地,该用户的所有应用程序都可以使用。

● Application
节点上同一应用程序的所有Container共享该资源

● 资源类型分类
● Archive
归档文件,支持.jar、.zip、.tar.gz、.tgz、.tar的5种归档文件。
● File
普通文件,NM只是将这类文件下载到本地目录,不做任何处理

● Pattern
以上两种文件的混合体

YARN是通过比较resource、type、timestamp和pattern四个字段是否相同来判断两个资源请求是否相同的。如果一个已经被缓存到各个节点上的文件被用户修改了,则下次使用时会自动触发一次缓存更新,以重新从HDFS上下载文件。

分布式缓存完成的主要功能是文件下载,涉及大量的磁盘读写,因此整个过程采用了异步并发模型加快文件下载速度,以避免同步模型带来的性能开销。

NodeManager采用轮询的分配策略将这三类资源存放在yarn.nodemanager.local-dirs指定的目录列表中,在每个目录中,资源按照以下方式存放:
● Public资源
存放在${yarn.nodemanager.local-dirs}/filecache/目录下,每个资源将单独存放在以一个随机整数命名的目录中,且目录的访问权限均为0755。

● Private资源
存放在 y a r n . n o d e m a n a g e r . l o c a l − d i r s / u s e r c a c h e / {yarn.nodemanager.local-dirs}/usercache/ yarn.nodemanager.localdirs/usercache/{user}/filecache/目录下,(其中${user}是应用程序提交者,默认情况下均为NodeManager启动者),每个资源将单独存放在以一个随机整数命名的目录中,且目录的访问权限均为0710。

● Application资源
存放在 y a r n . n o d e m a n a g e r . l o c a l − d i r s / u s e r c a c h e / {yarn.nodemanager.local-dirs}/usercache/ yarn.nodemanager.localdirs/usercache/{user}/ a p p c a c h e / {appcache}/ appcache/{appid}/filecache/目录下(其中${appid}是应用程序ID),每个资源将单独存放在以一个随机整数命名的目录中,且目录的访问权限均为0710;

其中Container的工作目录位于 y a r n . n o d e m a n a g e r . l o c a l − d i r s / u s e r c a c h e / {yarn.nodemanager.local-dirs}/usercache/ yarn.nodemanager.localdirs/usercache/{user}/ a p p c a c h e / {appcache}/ appcache/{appid}/${containerid}目录下,其主要保存jar包文件、字典文件对应的软链接。
在这里插入图片描述

Flink BlobServer

在这里插入图片描述

如何快速提交,减少上传 jar 包

Flink libs 下面 jar包、Flink Plugins 下面的 jar 包、Flink 任务的 jar 包(对于 ChunJun 来说就是所有 connector 和 core), Flink jar 用户自定义 jar 包。
● Perjob
如果可以提前上传到 HDFS:

  1. 提前把 Flink lib 、Flink plugins、ChunJun jar 上传到 HDFS 上面。
  2. 提交任务的时候通过 yarn.provided.lib.dirs 指定 HDFS 上面的路径即可。

如果不可以提前上传到 HDFS:

  1. 任务提交上传到 HDFS 固定位置,提交的时候检查 HDFS 上如果有对应的 jar(有缓存策略),就把本地路径替换成远程路径。
  2. 利用回调钩子,清楚异常任务结束的垃圾文件。

● Seeion
如果可以提前上传到 HDFS:

  1. 提前把 Flink lib 、Flink plugins、ChunJun jar 上传到 HDFS 上面。
  2. 启动 session 的时候通过 yarn.provided.lib.dirs 指定 HDFS 上面的路径即可。
  3. 提交任务的时候不需要上传 core 包。

如果不可以提前上传到 HDFS:

  1. Session 启动的时候就上传所有 jar 到 HDFS 上面。通过 yarnship 指定。
  2. Flink 任务提交到 Session 的时候,不需要提交任何 jar 包。在这里插入图片描述

类加载隔离遇到的问题分析

● 思路分析

  1. 首先要把不同插件(connector) 放到不同的 Classloader 里面。
  2. 然后使用 child-first 的加载策略。
  3. 确保不会发生 x not cast x 错误。
  4. 元数据空间不会内存泄露,导致任务报错。
  5. 要缓存 connector jar 包。

● 遇到的问题

  1. Flink 一个 job 可能有多个算子,一个 connector 就是一个算子。Flink 原生是为 job 级别新生成的 Classloader,无法把每个 connector 放在一个独立的 Classloader 里面。

  2. child-first 加载策略在 Session 模式下每次都新 new 一个 Classloader,导致元数据空间内存泄露。

  3. connecotor 之间用到公有的类会报错。

  4. 和问题2类似,主要是因为有些线程池,守护线程会拿着一些类对象,或者类 class 对象的引用。

  5. 如果用原生 -yarnship 去上传,会放到 App Classloader 里面。那么就会导致某些不期望用 App Classloader 加载的类被加载。在这里插入图片描述

Flink JobGraph Classpath 的使用

/** Set of JAR files required to run this job. */
private final ListuserJars = new ArrayList();/** Set of custom files required to run this job. */
private final MapuserArtifacts = new HashMap<>();/** List of Classpaths required to run this job. */
private ListClasspaths = Collections.emptyList();
  1. 客户端处理,JobGraph 处理 userJars、userArtifacts、Classpaths 这三个属性。
  2. Classpath 只留下 connector 的层级目录。
  3. 启动 Session 的时候上传 jar,jar 缓存在 Yarn 的所有的 NodeManager 节点。
  4. jobmanager 和 taskmanager 构建 Classloader 的时候去修改 Classpath 的路径,替换成当前节点 NodeManager 的缓存路径。
  5. 根据不同 connecotr 去构建Flink Job 的 Classloader。
  6. 把构建出来的 classlaoder 进行缓存,下次任务还有相同的 Classloader。避免内存泄露。
  7. 重写新的 ChildFirstCacheClassloader 里面的 loadclass 方法,根据不同的 connector url 去生成 单独的 Classloader。

遇到的问题和排查方案?

jar包冲突常见的异常为找不到类(java.lang.ClassNotFoundException)、找不到具体方法(java.lang.NoSuchMethodError)、字段错误( java.lang.NoSuchFieldError)或者类错误(java.lang.LinkageError)。

● 常见的解决方法如下
1、首先做法是打出工程文件的依赖树,将根据jar包依赖情况判定是不是同一个jar包依赖了多个版本,如果确认问题所在,直接exclusion其中错误的jar包即可。

2、如果通过看依赖树不能确定具体冲突的jar包,可以使用添加jvm参数的方式启动程序,将类加载的具体jar信息打印出来;-verbose:class 。

3、经过上述步骤基本就可以解决jar包冲突问题,具体的问题要具体分析。

● 常用工具推荐
1.Maven-helper
主要排查类冲突的 IDEA 插件。
亲测,真的嘎嘎好用,我几乎99%的jar包冲突都能解决,
在这里插入图片描述

2.Jstack
死锁的一些问题可以通过这个工具查看 jstack 调用栈。

3.Arthas
排查一些性能问题和 Classloader 泄露问题。

4.VisualVM
排查一些对象内存泄露、dump 文件分析等。

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

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

相关文章

Mysql第二关之存储引擎

简介 所有关于Mysql数据库优化的介绍仿佛都有存储引擎的身影。本文介绍Mysql常用的有MyISAM存储引擎和Innodb存储引擎&#xff0c;还有常见的索引。 Mysql有两种常见的存储引擎&#xff0c;MyISAM和Innodb&#xff0c;它们各有优劣&#xff0c;经过多次优化和迭代&#xff0c;…

【华为 OD 机考 C 卷 D卷】11月份华为od机试 C 卷 D卷 已来 ,如何刷题?

提示 2023年11月份&#xff0c;华为官方已经将 华为OD机考&#xff1a;OD统一考试&#xff08;A卷 / B卷&#xff09;切换到 OD统一考试&#xff08;C卷&#xff09;和 OD统一考试&#xff08;D卷&#xff09; 。 目前在考C卷&#xff0c;经过两个月的收集整理&#xff0c;C…

YOLOv7(目标检测)入门教程详解---检测,推理,训练

目录 一.前言 二.yolov7源码下载 三.detect&#xff08;检测&#xff09; 四.Train&#xff08;训练&#xff09; 数据准备&#xff1a; labellmg: 配置训练的相关文件 配置数据集文件 正式训练&#xff1a; 推理&#xff1a; 推理效果&#xff1a; 五.总结 一.前言 …

【python】爬取百度热搜排行榜Top50+可视化【附源码】【送数据分析书籍】

英杰社区https://bbs.csdn.net/topics/617804998 一、导入必要的模块&#xff1a; 这篇博客将介绍如何使用Python编写一个爬虫程序&#xff0c;从斗鱼直播网站上获取图片信息并保存到本地。我们将使用requests模块发送HTTP请求和接收响应&#xff0c;以及os模块处理文件和目录操…

如何将OpenAI Sora生成的普通AI视频转化为Vision Pro的空间视频,沉浸式体验

【基于AI的Vision Pro空间视频】工作流:这个工作流程用于将2D视频转换为适用于 Vision Pro的Spatial视频: 1、使用Deep3D将2D视频转换为3D SBS: 使用Deep3D工具将2D视频转换为3D SBS格式: 转换例子:Prediction– lucataco/deep3d – Replicatehttps://replicate.com/…

Shiro-11-web 介绍

配置 将Shiro集成到任何web应用程序的最简单方法是在web.xml中配置一个Servlet ContextListener和过滤器&#xff0c;该Servlet了解如何读取Shiro的INI配置。 INI配置格式本身的大部分是在配置页面的INI部分中定义的&#xff0c;但是我们将在这里介绍一些额外的特定于web的部…

js设计模式:建造者模式

作用: 将众多功能独立封装,然后用一个大类将其全部收纳,形成一个完整的功能 这个是很常见的设计模式 示例: function render(h){}function h(){}function $mount(dom){console.log(dom,绑定的根节点)console.log(this,this是vue实例)}function use(plugin){}function $attr(…

编程笔记 Golang基础 007 第一个程序:hello world 使用Goland

编程笔记 Golang基础 007 第一个程序&#xff1a;hello world 使用Goland 步骤1&#xff1a;启动GoLand并创建新项目步骤2&#xff1a;创建主包和主函数步骤3&#xff1a;运行程序小结 开始在Goland环境中编程go语言代码啦。 步骤1&#xff1a;启动GoLand并创建新项目 打开GoL…

相机图像质量研究(32)常见问题总结:图像处理对成像的影响--振铃效应

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

vue3-组合式 API

什么是组合式 API&#xff1f; 组合式 API (Composition API) 是一系列 API 的集合&#xff0c;使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语&#xff0c;涵盖了以下方面的 API&#xff1a; 响应式 API&#xff1a;例如 ref() 和 reactive()&a…

Aster实现一台电脑当两台使——副屏搭配键鼠

前言&#xff1a;笔者每年回家&#xff0c;都面临着想要和小伙伴一起玩游戏&#xff0c;但小伙伴没有电脑/只有低配电脑的问题。与此同时&#xff0c;笔者自身的电脑是高配置的电脑&#xff0c;因此笔者想到&#xff0c;能否在自己的电脑上运行游戏&#xff0c;在小伙伴的电脑上…

用HTML5 Canvas创造视觉盛宴——动态彩色线条效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- 声明文档类型为XHTML 1.0 Transitional -…

计算机网络-局域网和城域网(二)

1.局域网互联设备&#xff1a; 2层网桥&#xff08;生成树、源路由&#xff09;、3层交换机、路由器。网桥要求3层以上协议相同&#xff0c;1、2层协议不同可互联。 2.生成树网桥&#xff1a; 又叫透明网桥&#xff0c;IEEE802.1d&#xff0c;生成树算法。基本思想是在网桥之…

什么是HTTP代理,socks5代理?它们的区别是什么?

什么是HTTP代理&#xff1f; HTTP代理是一种常见的网络代理方式&#xff0c;它通过在客户端和服务器之间建立一个中间层&#xff0c;将客户端的请求转发给服务器&#xff0c;并将服务器的响应返回给客户端。HTTP代理通常用于访问受限制的网站&#xff0c;或者在网络中隐藏客户…

小迪安全25WEB 攻防-通用漏洞SQL 读写注入MYSQLMSSQLPostgreSQL

#知识点&#xff1a; 1、SQL 注入-MYSQL 数据库 2、SQL 注入-MSSQL(SQL server) 数据库 3、SQL 注入-PostgreSQL 数据库 #详细点&#xff1a; Access 无高权限注入点-只能猜解&#xff0c;还是暴力猜解 因为access的数据库是独立存在的&#xff0c;不存在统一管理 …

Docker再学习 - 阿里加速配置篇

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 知…

Imagewheel私人图床搭建结合内网穿透实现无公网IP远程访问教程

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

Docker镜像加速

前言 众所周知&#xff0c;我们常用的一些工具或系统的下载源都是国外的&#xff0c;这就会导致我们在下载一些东西时&#xff0c;会导致下载巨慢或者下载失败的情况&#xff0c;下面便是docker换下载源的教程 镜像加速 下面是几个常用的国内的镜像 科大镜像&#xff1a;ht…

SpringBoot原理篇

文章目录 SpingBoot原理1. 配置优先级2. Bean管理2.1 获取Bean2.2 Bean作用域2.3 第三方Bean 3. SpringBoot原理3.1 起步依赖3.2 自动配置3.2.1 概述3.2.2 常见方案3.2.2.1 概述3.2.2.2 方案一3.2.2.3 方案二 3.2.3 原理分析3.2.3.1 源码跟踪3.2.3.2 Conditional 3.2.4 案例3.2…

小米4A路由器如何刷OpenWRT并结合内网穿透实现公网远程访问

文章目录 推荐前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 推荐 前些天发现了一个巨牛的人工智…
推荐文章