Maven-依赖管理机制

一、背景和起源

依赖管理是Maven的一个核心功能。管理单个模块项目的依赖相对比较容易,但是如果是多模块项目或者有几百个模块的项目就是一个巨大的挑战。
如果手动构建项目,那么就先需要梳理各个模块pom中定义的依赖和版本,然后进行下载到本地,并且还需要依赖中pom定义的依赖和版本进行下载,如此反复。这中间需要解决相同依赖版本不同的情况、一些依赖需要排除等。

二、依赖配置

项目对外部库的依赖,可以配置在pom文件的dependency节点,需要提供依赖的groupId,artifactId,version。例如:

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-mapreduce-client-core</artifactId>
    <version>3.2.2</version>
    <scope>provided</scope>
    <exclusions>
       <exclusion>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
       </exclusion>
    </exclusions>
</dependency>

三、传递依赖

传递依赖机制是指项目只需要在POM中定义直接依赖、不需要定义任何间接依赖。Maven会读取各直接依赖的POM,将必要的间接依赖引入到当前项目。传递依赖机制简化了POM的配置,也将开发者从依赖的复杂传递关系中解脱出来。

1.依赖仲裁机制

当项目出现多版本依赖时,maven就需要通过依赖仲裁机制决定选择哪个版本依赖。

  • 路径优先:依赖层级越浅优先越高,层级越深优先级越低
  • 声明优先:当依赖所在层级相同,声明靠前的依赖优先级高于声明靠后的优先级

2.依赖范围

依赖范围会限制一些依赖在传递依赖机制中的传递,也就是一些间接依赖可能不会引入到当前项目中。传递范围Scope主要分为六种:

  • compile: 编译期,scope默认范围。也就是从编译期直到运行期都需要此依赖。
  • provided: 表示运行容器或者jdk提供的依赖,只需要在编译期引入此依赖,打包成运行程序时不需要包含此依赖。
  • runtime: 表示测试和运行期需要引入此依赖,编译期不需要此依赖,但打包时需要包含此依赖。
  • test: 测试期需要引入此依赖,编译期和打包时都不需要包含此依赖
  • system: 与provided类似,运行期间由用户指定的系统路径提供依赖
  • import:用于引入外部定义的依赖版本管理文件,相当于将依赖版本声明在pom的dependencyManagement节点。

以上依赖范围的依赖在整个构建和运行期间起作用范围如下:
在这里插入图片描述

3.依赖范围对传递的限制

项目A的pom中定义依赖项目B并且Scope为X,项目B中pom中定义依赖项目C并且Scope为Y。根据Maven传递依赖的机制,项目A不仅会加载直接依赖B还会加载间接依赖C,但是以上Scope X和Y会对是否加载依赖C以及依赖C的作用范围产生影响。

传递性依赖范围影响受到Scope X和Scop Y的影响如下:
在这里插入图片描述
注意:列为Scope X,行为Scope Y,交叉部分为项目A中针对依赖C的作用范围,当表格中为‘-’时,表示项目A不会引入依赖C。

4.排除依赖

如果当前项目只想引入直接依赖和部份间接依赖,这样需要将某个间接依赖排除掉,这样可以通过设置exclusions来实现。

比如以下例子就是排除间接依赖guava包。

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-mapreduce-client-core</artifactId>
    <version>3.2.2</version>
    <scope>provided</scope>
    <exclusions>
       <exclusion>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
       </exclusion>
    </exclusions>
</dependency>

5.可选依赖

如果当前项目在被依赖时,默认情况下想将当前项目的直接依赖不被加载可以用可选依赖。功能相当于当前项目被引用时配置了exclusions节点。

比如以下例子就是排除间接依赖guava包。

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<!-- 配置不透明 -->
	<optional>true</optional>
</dependency>

四、依赖集中管理

pom中dependencies节点可以定义项目需要引用的依赖,如果是一个多module项目,那么每个module中pom定义的依赖可能出现版本不一致,可能会出现版本冲突并且在升级版本时也不方便集中管理。所以可以在pom中的dependencyManagement节点对依赖的版本、范围、排除项等进行集中管理,这样整个项目中的版本可以保持一致并且方便进行版本管控。

1.父pom集中管理

当项目中有多个module时,可以在项目pom的dependencyManagement节点对依赖进行集中管理,来决定引入依赖的版本、排除间接依赖、依赖范围等。module中的pom将项目pom作为父pom,module中的pom只定义dependencies节点来决定引入哪些依赖。

1.1 不使用dependencyManagement对接点进行管理

如果项目不是用dependencyManagement管理,则两个项目的pom可以如下进行配置,其中依赖必须包含{groupId, artifactId, type}。
Project A POM:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-a</artifactId>
      <version>1.0</version>
      <exclusions>
        <exclusion>
          <groupId>group-c</groupId>
          <artifactId>excluded-artifact</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <version>1.0</version>
      <type>bar</type>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

Project B POM:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>group-c</groupId>
      <artifactId>artifact-b</artifactId>
      <version>1.0</version>
      <type>war</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <version>1.0</version>
      <type>bar</type>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

1.2 使用dependencyManagement对接点进行管理

为了简化和统一管理,可以将以上两个项目所有的依赖版本管理统一放到父pom中,这样两个项目中依赖定义可以只定义 {groupId, artifactId}。
Parent Project POM:

<project>
  ...
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-a</artifactId>
        <version>1.0</version>
        <exclusions>
          <exclusion>
            <groupId>group-c</groupId>
            <artifactId>excluded-artifact</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
 
      <dependency>
        <groupId>group-c</groupId>
        <artifactId>artifact-b</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
 
      <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-b</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

两个项目中的pom配置可以简化为:
Project A POM:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-a</artifactId>
    </dependency>
 
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <!-- This is not a jar dependency, so we must specify type. -->
      <type>bar</type>
    </dependency>
  </dependencies>
</project>

Project B POM:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>group-c</groupId>
      <artifactId>artifact-b</artifactId>
      <!-- This is not a jar dependency, so we must specify type. -->
      <type>war</type>
    </dependency>
 
    <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-b</artifactId>
      <!-- This is not a jar dependency, so we must specify type. -->
      <type>bar</type>
    </dependency>
  </dependencies>
</project>

2.当前pom和父pom一起集中管理

依赖集中管理也支持传递依赖,也就是集中管理当pom和父pom都配置了,这两个都会对依赖起到管理作用。
例如Project B继承了Project A,并且两个都定义了依赖管理。
Project A POM:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>maven</groupId>
 <artifactId>A</artifactId>
 <packaging>pom</packaging>
 <name>A</name>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.2</version>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>b</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>c</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>d</artifactId>
       <version>1.2</version>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>

Project B POM:

<project>
  <parent>
    <artifactId>A</artifactId>
    <groupId>maven</groupId>
    <version>1.0</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>maven</groupId>
  <artifactId>B</artifactId>
  <packaging>pom</packaging>
  <name>B</name>
  <version>1.0</version>
 
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>test</groupId>
        <artifactId>d</artifactId>
        <version>1.0</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
 
  <dependencies>
    <dependency>
      <groupId>test</groupId>
      <artifactId>a</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>test</groupId>
      <artifactId>c</artifactId>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

当构建项目B时,依赖a、依赖b、依赖c 都是版本1.0被使用。

  • 依赖a:由于在项目B中直接定义了版本号和scope,所以最终是加载的依赖a版本号为1.0、scope为runtime。
  • 依赖c:由于在项目B中只定义了scope,所以版本号需要由dependencyManagement节点决定,所以最终是加载的依赖c版本号为1.0、scope为runtime。
  • 依赖b:如果依赖b被依赖a或者依赖c间接引用,那么依赖b的版本由父pom中dependencyManagement节点决定,所以最终是加载的依赖b版本号为1.0、scope为compile。
  • 依赖d:因为项目B和父pom都在dependencyManagement节点定义了依赖d,所以管理节点是项目B中为准。

3.引入外部集中管理

如果项目module过多,没办法继承同一个父pom。这样可以通过引入一个外部的pom,这个pom只有dependencyManagement节点。

五、依赖版本确定流程

依赖版本的查找与依赖传递的解决机制都是基于项目Pom,也就是当项目有多个module时,是会按照每个module的pom为基本单位进行依赖的查找和传递。
例如:有父项目ProjectA,下边有子项目ProjectB和ProjectC。子项目ProjectC依赖ProjectB。

Project A POM:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>maven</groupId>
 <artifactId>A</artifactId>
 <packaging>pom</packaging>
 <name>A</name>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.2</version>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>b</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>c</artifactId>
       <version>1.0</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>test</groupId>
       <artifactId>d</artifactId>
       <version>1.2</version>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>

Project B POM:

<project>
  <parent>
    <artifactId>A</artifactId>
    <groupId>maven</groupId>
    <version>1.0</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>maven</groupId>
  <artifactId>B</artifactId>
  <packaging>pom</packaging>
  <name>B</name>
  <version>1.0</version>
 
  <dependencyManagement>
    <dependencies>
      <dependency>
      <groupId>test</groupId>
      <artifactId>a</artifactId>
      <version>2.4</version>
      <scope>runtime</scope>
    </dependency>
     <dependency>
      <groupId>test</groupId>
      <artifactId>a</artifactId>
      <version>2.5</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
       <groupId>test</groupId>
       <artifactId>c</artifactId>
       <version>2.1</version>
       <scope>compile</scope>
     </dependency>
      <dependency>
        <groupId>test</groupId>
        <artifactId>d</artifactId>
        <version>1.0</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
 
  <dependencies>
    <dependency>
      <groupId>test</groupId>
      <artifactId>a</artifactId>
      <version>3.6</version>
      <scope>runtime</scope>
    </dependency>
     <dependency>
      <groupId>test</groupId>
      <artifactId>a</artifactId>
      <version>3.7</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>test</groupId>
      <artifactId>c</artifactId>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

Project C POM:

<project>
  <parent>
    <artifactId>A</artifactId>
    <groupId>maven</groupId>
    <version>1.0</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>maven</groupId>
  <artifactId>B</artifactId>
  <packaging>pom</packaging>
  <name>B</name>
  <version>1.0</version>
 
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>test</groupId>
        <artifactId>d</artifactId>
        <version>1.0</version>
      </dependency>
      <dependency>
        <groupId>test</groupId>
        <artifactId>a</artifactId>
        <version>2.3</version>
      <scope>runtime</scope>
    </dependency>
    </dependencies>
  </dependencyManagement>
 
  <dependencies>
    <dependency>
      <groupId>test</groupId>
      <artifactId>a</artifactId>
      <version>3.0</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>test</groupId>
      <artifactId>c</artifactId>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</project>

1.配置优先级

1.1 不同节点优先级

同一个Pom中dependencies优先级高于dependencyManagement。比如在Project C中dependencies中定义了依赖a的版本和scope,所以会忽略dependencyManagement中依赖a的版本和scope。依赖a会采用版本3.0。

1.2 不同pom中dependencyManagement优先级

父子Pom中子Pom中dependencyManagement优先级高于父Pom中的dependencyManagement。比如在Project B中dependencies中没有定义了依赖c的版本,并且dependencyManagement定义了依赖c版本为2.1, 所以会忽略ProjectA中dependencyManagement中依赖c的版本和scope。

1.3 重复定义优先级

dependency在同一个dependencies或dependencyManagement中,如果出现相同{groupId,artifactId},则后出现的会覆盖先出现。
比如在Project B中dependencies和dependencyManagement中重复定义了依赖a,所以在各自节点中,起作用的都是后定义的版本。按照目前Pom,依赖a会是3.7,如果删除dependencies对依赖a的定义,则依赖a会采用版本2.5。

2.版本确定流程

2.1 对Pom的dependencies中定义的{groupId,artifactId}组合顺序遍历,如果有相同组合以后定义的信息为主。
2.2 针对以上去重后每个租户,如果version和exclusions都明确定义了,则确定了此依赖。
2.3 如果version和exclusions有一个没有定义,如果本Pom中dependencyManagement中定义了此依赖信息,则进行加载此依赖。
2.4 如果本Pom中dependencyManagement中没有定义了此依赖,则去父Pom的dependencyManagement中查找此依赖定义,如果没有会一直查找到默认Pom文件对应节点
2.5 将依赖的Pom的dependencies按照 2.1进行处理后,还需要去掉exclusions的租户后跳转到2.2。
2.6 如果加载完成所有依赖,出现了相同{groupId,artifactId},则需要根据仲裁机制的路径优先和声明优先进行选择。
在这里插入图片描述

3.版本冲突

maven有完善的版本管理和冲突解决机制,但是为什么实际工程中还会出现依赖多版本和冲突问题。主要是因为maven的冲突仲裁机制是以Pom为单位进行的,如果一个项目有很大module,而对依赖版没有进行统一管理,就会出现相同的依赖在不同module的版本不一致问题。
例如上边的例子依赖a在Project B中引入的是2.5版本,在Project C中引入的是3.0版本。所以针对整个项目在运行过程中可能会优先加载2.5版本,这就导致Project C中调用依赖3.0版本a的一些方法缺失或者实现有差异,导致功能异常。

3.1 版本统一管理

将所有版本管理统一到父Pom的dependencyManagement中,子项目中不要配置dependencyManagement。

3.2 排除依赖

可以在子项目定义依赖时通过exclusions将一些间接依赖排除掉,解决版本冲突。

总结

主要是对maven依赖传递机制的介绍、依赖管理的的配置、依赖版本和范围确定机制、依赖冲突解决等。

参考

1.maven文档-依赖机制

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】表的增删改查(强化)

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《MySQL》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&a…

物奇平台耳机宕机恢复功能实现

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;可加我微信hezkz17, 本群提供音频技术答疑服务&#xff0c;群赠送语音信号处理降噪算法&#xff0c;蓝牙音频&#xff0c;DSP音频项目核心开发资料, 物奇平台耳机宕机恢复功能实现 一 需求与场景 1 使…

TortoiseSVN 状态图标不显示的两种解决办法

文章目录 TortoiseSVN 方式解决注册表方式解决 TortoiseSVN 方式解决 在桌面或者资源管理器中鼠标右键打开 TortoiseSVN 设置选择 Icon Overlays (图标覆盖)Status cache&#xff08;状态缓存&#xff09; 选择 ‘Shell’ 选择 Icon Overlays&#xff08;图标覆盖&#xff09;…

基于AI智能分析网关的智慧视频监控系统一站式解决方案

1、功能概述 TSINGEE智能分析网关EasyCVR智慧视频监控系统基于云-边-端一体化协同架构&#xff0c;可兼容多协议、多类型的设备接入&#xff0c;实现视频数据采集、海量视频汇聚与处理、按需调阅、全网分发、 告警消息推送、数据级联共享、AI智能分析接入等视频能力服务&#…

我敢打赌,这个架构你一定知道!

大家好&#xff0c;我是鱼皮。开发后端项目时&#xff0c;我们最常见的一种架构模式就是 分层架构 。 所谓的分层架构&#xff0c;就是把系统自上而下分为多个不同的层&#xff0c;每一层都有特定的功能和职责&#xff0c;且只和自己的直接上层与直接下层 “打交道”。 分层架…

MySQL 数据库表格创建、数据插入及获取插入的 ID:Python 教程

创建表格 要在MySQL中创建表格&#xff0c;请使用"CREATE TABLE"语句。 确保在创建连接时定义了数据库的名称。 示例创建一个名为 “customers” 的表格&#xff1a; import mysql.connectormydb mysql.connector.connect(host"localhost",user"…

LDR6023AQ-PDHUB最简外围成本低搂到底就是干

USB-C PD协议里&#xff0c;SRC和SNK双方之间通过CC通信来协商请求确定充电功率及数据传输速率。当个设备需要充电时&#xff0c;它会发送消息去给适配器请求充电&#xff0c;此时充电器会回应设备的请求&#xff0c;并告知其可提供的档位功率&#xff0c;设备端会根据适配器端…

Java集合面试题

常见的java集合&#xff1f; 主要分为三类&#xff0c;List Map Set 列表 映射 集 集合相关的接口都在 java.util中 java集合的主要关系 List 特性&#xff1a; 存储的元素有序&#xff0c;可重复 Set 特性&#xff1a;存储的元素无序&#xff0c;不可重复 Map 特性…

【Proteus仿真】【51单片机】汽车尾灯控制设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用按键、LED模块等。 主要功能&#xff1a; 系统运行后&#xff0c;系统运行后&#xff0c;系统开始运行&#xff0c;K1键控制左转向灯&#xff1b;…

外贸企业GMS认证|SD-WAN专线解决方案支持 IPv6、IPv4

IP地址是英文internet protocol的缩写&#xff0c;是网络之间互连的协议。互联网诞生后&#xff0c;很长一段时间都是使用v4版本的IP协议&#xff0c;也就是 IPv4 &#xff0c;目前全球使用互联网的人数达到了48.8亿&#xff0c;而IPv4的地址库总共约43亿个地址&#xff0c;每个…

相同的树(C++解法)

题目 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true示例 …

结构体内存对齐(三板斧解决结构体的大小)

文章目录 前言一、结构体对齐规则二、结构体大小计算 - 三板斧一板斧二板斧三板斧 三、为什么存在内存对齐&#xff1f;四、修改默认对齐数 前言 我们知道&#xff0c;整型变量有自己的大小&#xff0c;浮点型变量有自己的大小&#xff0c;数组也有自己的大小&#xff0c;只要…

linux下搭建gperftools工具分析程序瓶颈

1. 先安装 unwind //使用root wget https://github.com/libunwind/libunwind/archive/v0.99.tar.gz tar -xvf v0.99.tar.gz cd libunwind-0.99 autoreconf --force -v --install ./configure make sudo make install2. 安装gperftools wget https://github.com/gp…

操作系统第一次实验——短作业优先调度算法(SJF)

一、实验目的&#xff1a; 目的&#xff1a;了解并掌握作业调度的功能&#xff0c;熟悉并掌握各种作业调度算法。 任务&#xff1a;模拟实现先来先服务或者短作业优先调度算法。 二、实验内容&#xff1a; 1、实验内容 模拟实现SJF调度。 设置作业体&#xff1a;作业名&#x…

关于mac下pycharm旧版本没删除的情况下新版本2023安装之后闪退

先说结论&#xff0c;我用的app cleaner 重新删除的pycharm &#xff0c;再重新安装即可。在此记录一下 之前安装的旧版的2020的pycharm&#xff0c;因为装不了新的插件&#xff0c;没办法就升级了。新装2023打开之后闪退&#xff0c;重启系统也不行&#xff0c;怀疑是一起破解…

类图复习:类图简单介绍

入职新公司在看新项目的代码&#xff0c;所以借助类图梳理各个类之间的关系&#xff0c;奈何知识已经还给了老师&#xff0c;不得不重新学习下类图的相关知识&#xff0c;此处将相关内容记录下方便后续使用。 文章目录 类图语法类与类的关系画类图 类图语法 语法描述public-pr…

C语言--typedef的使用

前言 在C语言中使用结构体时必须加上struct这个关键字,那有没有办法省略这个呢?要想达到这个目的就 需要用到关键字typedef,顾名思义”类型定义”。 typedef 数据类型 新的别名; 它是用来操作数据类型。其主要作用有两个: 1.给一个较长较复杂的类型取一个简单的别名。 2.给类…

MySQL其他集群类型介绍

常用的/常见的Mysql集群方案 1.MySQL Replication2.MySQL Fabric3.MySQL NDB Cluster4.MGR&#xff08;MySQL Group Replication&#xff09;5.心跳检测SAN共享存储&#xff08;heartbeat SAN&#xff09;6.心跳检测DRBD磁盘复制&#xff08;heartbeat DRBD&#xff09;7.MMM…

大桌子想传大文件

受高手指导说服务器想传大点的文件&#xff0c;得把两个地方改改 先是这里 然后这里也要改 哦。对了&#xff0c;改完之后要重启服务器。别忘了。

网络爬虫代理ip有什么好处?爬虫工作使用代理IP有哪些优势?

在爬虫工作中&#xff0c;使用代理IP有很多好处&#xff0c;可以帮助爬虫程序更加高效地完成任务。以下是使用代理IP的几个优势&#xff1a; 1. 增加匿名性 使用代理IP可以隐藏爬虫程序的真正IP地址&#xff0c;增加匿名性&#xff0c;避免被目标网站封禁。通过代理IP&#xff…