MperReduce学习笔记下

自定义InputFormat合并小文件

案例需求

无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案。

案例分析

小文件的优化无非以下几种方式:

  1. 在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS
  2. 在业务处理之前,在HDFS上使用mapreduce程序对小文件进行合并
  3. 在mapreduce处理时,可采用combineInputFormat提高效率

案例实现

本节实现的是上述第二种方式

  1. 首先继承FileInputFormat类自定义MyInputFormat方法,在自定义的MyInputFormat类中需重写RecordReader方法。
  2. 然后自定义MyRecordReader继承RecordReader,在自定义的MyRecordReader类中需重新initialize(初始化方法)、nextKeyValue(该方法用于获取 <k1,v1>,读取源数据转换为<k1,v1>)、getCurrentKey(返回k1)、getCurrentValue(返回v1)、getProgress(获取文件读取进度)、close(释放资源)等方法。
  3. 然后在MyInputFormat类中实例化自定义的MyRecordReader类并传递源数据,设置文件是否允许被切割(本案例不允许被切割)。
  4. Mapper代码按照正常逻辑实现,可以省略Reduce代码,最后主类JobMain中设置文件的读取类为自定义的MyInputFormat。

程序的核心机制:

  1. 自定义一个InputFormat
  2. 改写RecordReader,实现一次读取一个完整文件封装为KV
  3. 在输出时使用SequenceFileOutPutFormat输出合并文件
// 第一步package myinput_format;import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;import java.io.IOException;public class MyRecordReader extends RecordReader<NullWritable, BytesWritable> {private Configuration configuration = null;private FileSplit fileSplit = null;// 定义标志位判断文件是否处理完成 ---false表示文件没有被读取完private boolean processed = false;private BytesWritable bytesWritable = new BytesWritable();private FileSystem fileSystem = null;private FSDataInputStream inputStream = null;// 初始化@Overridepublic void initialize(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {// inputSplit----文件切片包含文件名信息fileSplit = (FileSplit)inputSplit;// 获取Configuration 对象 ---向上提取(以便nextKeyValue函数使用)configuration = taskAttemptContext.getConfiguration();}// 该方法用于获取 <k1,v1>,读取源数据转换为<k1,v1>/** k1-------->NullWritable* v1-------->BytesWritable* */@Overridepublic boolean nextKeyValue() throws IOException, InterruptedException {// 判断文件是否读取完成if (!processed){// 1.获取源文件字节输入流// 1.1 获取源文件的文件系统(FileSystem)fileSystem = FileSystem.get(configuration);// 1.2 通过(FileSystem)获取文件字节输入流 ---源文件路径inputStream = fileSystem.open(fileSplit.getPath());// 2.获取源文件数据到普通的字节数组(byte[])long a = fileSplit.getLength();byte[] bytes = new byte[(int) a];
//            byte[] bytes = new byte[(int) fileSplit.getLength() ];// 需要容纳下小文件字节大小,强行装换为int类型//2.1源文件数据读取到上述自定义的字节数组IOUtils.readFully(inputStream,bytes,0,(int) fileSplit.getLength());// 3.普通的字节数组转换封装到BytesWritable,得到 v1bytesWritable.set(bytes,0,(int) fileSplit.getLength());processed = true;return true;}return false;}//返回 k1@Overridepublic NullWritable getCurrentKey() throws IOException, InterruptedException {return NullWritable.get();}//返回 v1@Overridepublic BytesWritable getCurrentValue() throws IOException, InterruptedException {return bytesWritable;}// 获取文件读取进度@Overridepublic float getProgress() throws IOException, InterruptedException {return 0;}// 进行资源释放@Overridepublic void close() throws IOException {// 关闭输入流inputStream.close();fileSystem.close();}
}
// 第二步
package myinput_format;import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;import java.io.IOException;public class MyInputFormat extends FileInputFormat<NullWritable, BytesWritable> {// RecordReader抽象类返回子类,需要自定义LineRecordReader类@Overridepublic RecordReader<NullWritable, BytesWritable> createRecordReader(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {// 1.创建自定义RecordReader对象MyRecordReader myRecordReader = new MyRecordReader();// 2.将源数据InputSplit和TaskAttemptContext传递给自定义RecordReader对象myRecordReader.initialize(inputSplit,taskAttemptContext);return myRecordReader;}// 设置文件是否可以被切割(功能实现小文件合并设置为不可被切割)@Overrideprotected boolean isSplitable(JobContext context, Path filename) {return false;}
}
// 第三步
package myinput_format;import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;import java.io.IOException;public class SequenceFileMapper extends Mapper<NullWritable, BytesWritable, Text,BytesWritable> {@Overrideprotected void map(NullWritable key, BytesWritable value, Context context) throws IOException, InterruptedException {// <k1,v1>转为<k2,v2>// 1.获取文件名作为k2// 根据 context 获取文件切片--其中包含文件名FileSplit fileSplit = (FileSplit) context.getInputSplit();String fileName = fileSplit.getPath().getName();// 2.v2就是v1写入上下文context.write(new Text(fileName),value);}
}
// 第四步
package myinput_format;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;import java.net.URI;public class JobMain extends Configured implements Tool {//该方法用于指定一个job任务@Overridepublic int run(String[] strings) throws Exception {// 1.创建 job任务对象 两个参数 1.configuration  2.job任务名称Job job = Job.getInstance(super.getConf(), "input_format");// 打包运行出错添加job.setJarByClass(JobMain.class);// 2.配置 job任务对象(八个步骤)// 2.1 读取文件 ---指定读取类job.setInputFormatClass(MyInputFormat.class);// 指点源文件路径MyInputFormat.addInputPath(job,new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myinput_format"));// 2.2 进入指定map阶段处理方式和数据类型// 设置map阶段用的类job.setMapperClass(SequenceFileMapper.class);// 设置Map阶段K2的类型 --- 单词(字符串)job.setMapOutputKeyClass(Text.class);// 设置Map阶段V2的类型 ---job.setMapOutputValueClass(BytesWritable.class);// 2.3(4,5,6) 进入Shuffle阶段 --先采用默认方式处理// 2.7 指定Reduce阶段的数据类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(BytesWritable.class);// 2.8 设置输出类型 -- 保存在二进制文件中job.setOutputFormatClass(SequenceFileOutputFormat.class);// 设置输出路径
//        TextOutputFormat.setOutputPath(job,new Path("hdfs://hadoop01:9000/wordcount_out"));// 判断目标目录是否存在,存在则删除Path path = new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myinput_format_out");SequenceFileOutputFormat.setOutputPath(job,path);// 获取hdfs文件系统FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop01:9000/hadoop_mapreduce/"), new Configuration());// --本地测试--
//        FileSystem fileSystem = FileSystem.get(new URI("file:///D:\\output"), new Configuration());// 判断目录是否存在boolean exists = fileSystem.exists(path);if (exists){// 删除目标目录fileSystem.delete(path,true);}// 等待任务结束boolean bl = job.waitForCompletion(true);return bl ? 0:1;}public static void main(String[] args) throws Exception {Configuration configuration = new Configuration();// 启动 job任务 --记录任务执行状态 0表示成功int run = ToolRunner.run(configuration, new JobMain(), args);System.exit(run);}
}

自定义outputFormat格式输出文件

案例需求

现在有一些订单的评论数据,需求,将订单的好评与差评进行区分开来,将最终的数据分开到不同的文件夹下面去,数据内容参见资料文件夹,其中数据第九个字段表示好评,中评,差评。0:好评,1:中评,2:差评

案例分析

程序的关键点是要在一个mapreduce程序中根据数据的不同输出两类结果到不同目录,这类灵活的输出需求可以通过自定义outputformat来实现。

案例实现
  1. 首先继承FileOutputFormat类自定义MyOutputFormat类,在自定义的MyOutputFormat类中需重写RecordWriter方法。
  2. 然后自定义MyRecordWriter继承RecordWriter,在自定义的MyRecordWriter类中需重新write(具体输出数据的方法)、close(释放资源)等方法。
  3. 然后在MyOutputFormat类中实例化自定义的MyRecotdWriter类(有参构造传递)传递源数据
  4. Mapper代码按照正常逻辑实现,可以省略Reduce代码,最后主类JobMain中设置文件的输出类为自定义的MyOutputFormat。
// 第一步
package myoutput_format;import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;import java.io.IOException;public class MyRecordWriter extends RecordWriter<Text,NullWritable> {private FSDataOutputStream goodCommentsOutputStream;private FSDataOutputStream badCommentsOutputStream;public MyRecordWriter() {}public MyRecordWriter(FSDataOutputStream goodCommentsOutputStream, FSDataOutputStream badCommentsOutputStream) {this.goodCommentsOutputStream = goodCommentsOutputStream;this.badCommentsOutputStream = badCommentsOutputStream;}/**** @param text  行文本内容* @param nullWritable* @throws IOException* @throws InterruptedException*/@Overridepublic void write(Text text, NullWritable nullWritable) throws IOException, InterruptedException {//1:从行文本数据中获取第9个字段String[] split = text.toString().split("\t");String numStr = split[9];//2:根据字段的值,判断评论的类型,然后将对应的数据写入不同的文件夹文件中if(Integer.parseInt(numStr) <= 1){//好评或者中评goodCommentsOutputStream.write(text.toString().getBytes());// 添加换行符goodCommentsOutputStream.write("\r\n".getBytes());}else{//差评badCommentsOutputStream.write(text.toString().getBytes());badCommentsOutputStream.write("\r\n".getBytes());}}@Overridepublic void close(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {IOUtils.closeStream(goodCommentsOutputStream);IOUtils.closeStream(badCommentsOutputStream);}
}
// 第二步
package myoutput_format;import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException;public class MyOutputFormat extends FileOutputFormat<Text, NullWritable> {@Overridepublic RecordWriter<Text, NullWritable> getRecordWriter(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {// 1.获取目标文件输出流(两个)FileSystem fileSystem = FileSystem.get(taskAttemptContext.getConfiguration());// 文件写入路径FSDataOutputStream goodCommentsOutputStream = fileSystem.create(new Path("hdfs://hadoop01:9000/hadoop_mapreduce/good_comments/good_comments.txt"));FSDataOutputStream badCommentsOutputStream = fileSystem.create(new Path("hdfs://hadoop01:9000/hadoop_mapreduce/bad_comments/bad_comments.txt"));// 2.传递给----->MyRecotdWriter类使用(有参构造传递)MyRecordWriter myRecordWriter = new MyRecordWriter(goodCommentsOutputStream,badCommentsOutputStream);return myRecordWriter;}}
// 第三步
package myoutput_format;import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;public class MyOutputFormatMapper extends Mapper<LongWritable, Text,Text, NullWritable> {@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {context.write(value,NullWritable.get());}
}
// 第四步
package myoutput_format;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;import java.net.URI;public class JobMain extends Configured implements Tool {//该方法用于指定一个job任务@Overridepublic int run(String[] strings) throws Exception {// 1.创建 job任务对象 两个参数 1.configuration  2.job任务名称Job job = Job.getInstance(super.getConf(), "output_format");// 打包运行出错添加job.setJarByClass(JobMain.class);// 2.配置 job任务对象(八个步骤)// 2.1 读取文件 ---指定读取类job.setInputFormatClass(TextInputFormat.class);// 指点源文件路径TextInputFormat.addInputPath(job,new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myoutput_format"));// 2.2 进入指定map阶段处理方式和数据类型// 设置map阶段用的类job.setMapperClass(MyOutputFormatMapper.class);// 设置Map阶段K2的类型 --- 单词(字符串)job.setMapOutputKeyClass(Text.class);// 设置Map阶段V2的类型 ---job.setMapOutputValueClass(NullWritable.class);// 2.3(4,5,6) 进入Shuffle阶段 --先采用默认方式处理// 2.7 指定Reduce阶段的数据类型// 2.8 设置输出类型 -- 保存在二进制文件中job.setOutputFormatClass(MyOutputFormat.class);// 设置输出路径
//        TextOutputFormat.setOutputPath(job,new Path("hdfs://hadoop01:9000/wordcount_out"));// 判断目标目录是否存在,存在则删除Path path = new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myoutput_format_out");SequenceFileOutputFormat.setOutputPath(job,path);// 获取hdfs文件系统FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop01:9000/hadoop_mapreduce/"), new Configuration());// --本地测试--
//        FileSystem fileSystem = FileSystem.get(new URI("file:///D:\\output"), new Configuration());// 判断目录是否存在boolean exists = fileSystem.exists(path);if (exists){// 删除目标目录fileSystem.delete(path,true);}// 等待任务结束boolean bl = job.waitForCompletion(true);return bl ? 0:1;}public static void main(String[] args) throws Exception {Configuration configuration = new Configuration();// 启动 job任务 --记录任务执行状态 0表示成功int run = ToolRunner.run(configuration, new JobMain(), args);System.exit(run);}
}

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

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

相关文章

中国汽车出海风口下,智能网联供应商如何掘金海外市场?

中国智能网联供应链出海掘金潮已至。 中国汽车工业协会最新发布的数据显示&#xff0c;2024年1-8月乘用车累计出口317.5万辆&#xff0c;同比增长29.4%。2023年中国汽车出口量近500万台&#xff0c;出口的销量对中国汽车总销量增长的贡献率达到55.7%。 根据各大车企披露的规划…

react + antd desgin 使用form功能时upload,radio,checkbox不能回显的问题

最近使用react开发 遇到form回显的问题 &#xff0c;处理upload回显的问题&#xff0c;提示 react-refresh:160 Warning: [antd: Upload] value is not a valid prop, do you mean fileList? 查看文档后&#xff0c;在form.item 组件下有一个特殊属性 valuePropName 子节点的值…

Visual Studio开发lua脚本环境搭建

在Visual Studio上开发lua脚本环境搭建 1、下载lua的jdk安装&#xff0c;以及环境变量配置 下载LuaForWindows_v5.1.5-52.exe安装&#xff0c; 安装好之后&#xff0c;检查是否路径自动。 下载地址&#xff1a; https://github.com/rjpcomputing/luaforwindows/releases (1…

Elasticsearch ILM 故障排除:常见问题及修复

作者&#xff1a;来自 Elastic Stef Nestor 大家好&#xff01;我们的 Elasticsearch 团队正在不断改进我们的索引生命周期管理 (index Lifecycle Management - ILM) 功能。当我第一次加入 Elastic Support 时&#xff0c;我通过我们的使用 ILM 实现自动滚动教程快速上手。在帮…

初步简单的理解什么是库,什么是静态库,什么是动态库

库是什么 库根据名字我们应该很容易理解&#xff0c;在我们日常生活种&#xff0c;包含库的东西有很多&#xff0c;像仓库&#xff0c;库房那些&#xff0c;库是拿来存放&#xff0c;方便管理东西的&#xff0c;在我们编程当中&#xff0c;库的定义也是如此 那么为什么要有库…

建筑行业数据分析如何做?

导读&#xff1a;在谈数字化转型之前&#xff0c;先来谈谈数据的价值。数字化转型的基础是数据&#xff0c;是数字化的基本的生产资料&#xff0c;数据的质量直接决定了数字化的能力、所能达到的深度和广度。目前做的数据可视化项目总感觉只是数据展现而已&#xff0c;而不达不…

服务器监控工具哪吒探针 v1 版本上线 全新设计带来新体验

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 上周黑五期间&#xff0c;哪吒探针进行了一次颇有争议的 Breaking Change 更新&#xff0c;将面板和 Agent 升级到了 v1 版本&#xff0c;并且与原来的 v0.x 版本完全不兼容。 同时&#xff0c;将 v0.x 的…

QNX的资源管理器:resmgr

参考资料: QNX官网文档 openqnx源码参考 这篇文章借用一下openqnx中的trunk/services/dumper/dumper.c作为参考 以下代码参考openqnx,现在的QNX许多机制或许有大致改进和调整,但是基本上不会跳出这个框架 在Linux中,一切设备皆文件,在/dev目录下,一个文件标识一个或多…

Node.js 中的文件系统(fs)模块详解与代码示例

Node.js 中的文件系统&#xff08;fs&#xff09;模块详解与代码示例 Node.js 的 fs 模块提供了与文件系统交互的能力&#xff0c;包括文件的读写、目录的管理等。以下是 fs 模块中一些常用方法的详细解释和代码示例&#xff1a; 1. 异步读取文件内容 作用&#xff1a;异步读…

LabVIEW密码保护与反编译的安全性分析

在LabVIEW中&#xff0c;密码保护是一种常见的源代码保护手段&#xff0c;但其安全性并不高&#xff0c;尤其是在面对专业反编译工具时。理论上&#xff0c;所有软件的反编译都是可能的&#xff0c;尽管反编译不一定恢复完全的源代码&#xff0c;但足以提取程序的核心功能和算法…

灰狼算法与蚁群算法的结合:一种新颖的优化方法

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【前端学习路线】(超详细版本)

先附上学习路线图&#xff1a;前端学习路线 第一阶段&#xff1a;前端入门&#xff08;htmlcss&#xff09; 前端最基本的知识&#xff0c;需要先将这些内容融汇贯通&#xff0c;学习后面内容才会不吃力。学习完可以做几个静态页练习一下。 推荐视频学习链接&#xff1a; 黑马程…

四、自然语言处理_03LSTM与GRU

0、前言 随着循环神经网络&#xff08;RNN&#xff09;在各种序列数据处理任务中被广泛应用&#xff0c;研究人员逐渐发现了其在处理长序列数据时会容易出现梯度消失&#xff08;vanishing gradient&#xff09;和梯度爆炸&#xff08;exploding gradient&#xff09;问题&…

类加载过程Java虚拟机(JVM)详细

类加载过程是Java虚拟机&#xff08;JVM&#xff09;将类的字节码文件加载到内存中&#xff0c;并生成对应的类对象的过程。这个过程主要包括加载、验证、准备、解析和初始化五个阶段&#xff0c;每个阶段都有其特定的任务和作用。以下是对每个阶段的详细解释&#xff1a; 1. …

基于灰色神经网络的订单需求预测

灰色神经网络&#xff08;Grey Neural Network, GNN&#xff09; 是将灰色系统理论与人工神经网络相结合的一种模型&#xff0c;旨在处理不完全信息和小样本问题。灰色神经网络利用灰色系统的预测优势和神经网络的学习能力&#xff0c;能够在信息不完整或数据不充分的情况下实现…

nerdctl:与 Docker 兼容的 containerd CLI

nerdctl 是一个用于容器管理的命令行工具&#xff0c;它旨在提供与 Docker CLI 相似的用户体验&#xff0c;但却是为 containerd 这样的低级容器运行时设计的。containerd 是一个行业标准的容器运行时&#xff0c;被广泛用作 Kubernetes 等容器编排平台的一部分。nerdctl 通过简…

java基础教程第16篇( 正则表达式)

Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言&#xff0c;但是在每种语言中有细微的差别。 Java 提供了 java.util.regex 包&#xff0c;它包含了 Pattern 和 Matcher 类&#xff0c;用于处理正…

百问FB显示开发图像处理 - 图像调整

2.4 图像调整 2.4.1 图像的缩放 2.4.1.1 图像缩放算法浅析 图像缩放算法有很多种&#xff0c;这里参考网友"lantianyu520"所著的"图像缩放算法"。 原理浅析 ​ 要理解这个图像缩放算法的原理&#xff0c;最重要的是需要理解&#xff1a;对于图像上的每…

部署项目报错

vue2项目部署后 Error: Cannot find module /views/*** 1.起因 登录页、首页等静态页面可以正常进入&#xff0c;后端访问也正常&#xff0c;可以获取到验证码。 但是登录之后会发现首页空白或者进入不到首页 F12查看有报错信息&#xff1a;Error: Cannot find module ‘/v…

怎麼解決路由器IP地址衝突?

路由器IP地址衝突通常發生在網路中有兩個設備嘗試使用相同的IP地址時。這種衝突會導致網路連接問題&#xff0c;因為每個設備需要一個唯一的IP地址才能正常通信。 1. 重啟設備 重啟路由器和設備&#xff1a;有時候簡單的重啟可以解決問題&#xff0c;設備重新獲取一個新的IP地…