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

arp报文及使用go实现

一、ARP协议报文格式及ARP表

ARP(Address Resolution Protocal,地址解析协议)是将IP地址解析为以太网的MAC地址(或者称为物理地址)的协议。在局域网中,当主机或其他网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即IP地址)。但是仅仅有IP地址还是不够的,因为IP数据报文必须封装成帧才能通过物理网络发送,因为发送站还必须有接收站的物理地址,所以需要一个从IP地址到物理地址的映射。ARP就是实现这个功能的协议。

ARP报文

ARP是一个独立的三层协议,所以ARP报文在向数据链路层传输时不需要经过IP协议的封装,而是直接生成自己的报文,其中包括ARP报头,到数据链路层后再由对应的数据链路层协议(如以太网协议)进行封装。ARP报文分为ARP请求和ARP应答报文两种,它们的报文格式可以统一为下图所示。

  • 硬件类型:占两字节,表示ARP报文可以在哪种类型的网络上传输,值为1时表示为以太网地址。
  • 上层协议类型:占两字节,表示硬件地址要映射的协议地址类型,映射IP地址时的值为0x0800
  • MAC地址长度:占一字节,标识mac地址长度,以字节为单位,此处为6.
  • IP协议地址长度:占一字节,标识IP地址长度,以字节为单位,此处为4
  • 操作类型:占两字节,指定本次ARP报文类型。1表示arp请求报文,2表示arp应答报文,3表示RARP请求,4表示RARP应答
  • 源MAC地址:占六字节,标识发送设备的硬件地址
  • 源IP地址:占4字节,标识发送方设备的IP地址
  • 目的MAC地址:占六字节,标识接收方设备的硬件地址,在请求报文中该字段全为0,即00-00-00-00-00-00,表示任意地址,因为现在不知道这个地址
  • 目的IP地址:占四字节,表示接收方的IP地址

ARP报文不是直接在网络层上发送的,它还是需要向下传输到数据链路层,所以当ARP报文传输到数据链路层之后,需要再次进行封装。以以太网为例,ARP报文传输到以太网数据链路层后会形成ARP帧。ARP帧如下图所示,他就是在ARP报文前面加了一个以太网帧头

以太网帧头的三个字段说明:

  • 目的MAC地址:占6字节,如果是ARP请求帧,因为它是一个广播帧,所以要填上广播MAC地址(FF-FF-FF-FF-FF-FF),其目标主机是网络上所有主机
  • 源MAC地址:占6字节,这是发送ARP帧的节点MAC地址
  • 帧类型:占两字节,这里用来标识 帧封装的上层协议,因为本帧的数据部分是ARP部分,所以直接用ARP的协议号0x0806表示就可以了。

ARP映射表

无论是主机,还是交换机都会有一个用来缓存同一网段设备IP地址和MAC地址的ARP映射表,用于数据帧的转发。设备通过ARP解析到目的MAC之后,将会在自己的ARP映射表中增加IP地址到MAC地址的映射表,以用于后续到同一目的地数据帧的转发。ARP表项分为动态ARP表项和静态ARP表项。

动态ARP表项

动态ARP表项由ARP协议通过ARP报文自动生成和维护,可以被老化,可以被新的ARP报文更新,也可以被静态ARP表项所覆盖。当到达老化时间或接口关闭时会删除相应的动态ARP表项

静态ARP表项

静态ARP表项通过手工配置(通过对应设备的IP地址与MAC地址绑定命定进行)和维护。不会被老化,也不会被动态ARP表项覆盖。配置静态ARP表项可以增加通信的安全性,因为静态ARP可以限定和指定IP地址的设备通信时只使用指定的MAC地址(也就是我们通常所说的IP地址和MAC地址的绑定),此时攻击报文无法修改此表项的IP地址和MAC地址的映射关系,从而保护了本设备和指定设备间正常通信。静态ARP表项又分为短静态ARP表项和长静态ARP表项

短静态ARP表项

在配置短静态ARP表项时,只需要配置IP地址和MAC地址项。如果出接口是三层以太网接口,短静态ARP表项可以直接用于报文转发;如果出接口是VLAN虚接口,短静态ARP表项不能直接用于报文转发,当要发送IP数据包时,先发送ARP请求报文,如果收到的相应报文中的源IP地址和源MAC地址与所配置的IP地址和MAC地址相同,则将接受ARP响应报文的接口加入该静态表项中,之后就可以用于IP数据包的转发了。

长静态ARP表项

在配置长静态ARP表项时,除了配置IP地址和MAC地址项外,还必须配置该ARP表所对应的VLAN(虚拟局域网)和出接口。也就是长静态ARP表项同事绑定了IP地址、MAC地址、VLAN和端口,可以直接用于报文转发。

二、arp解析过程

  1. 当PC1想发送数据给PC2,首先在自己的本地ARP缓存表中检查主机PC2匹配的MAC地址
  2. 如果PC1缓存中没有找到响应的条目,它将询问主机PC2的MAC地址,从而将ARP请求帧广播到本地网络的所有主机。该帧中包括源主机PC1的IP、MAC地址,本地网络中的所有主机都接收到ARP请求,并且检查是否与自己的ip地址相匹配。如果发现请求中的IP地址与自己的IP不匹配,则丢弃ARP请求
  3. 主机PC2确定ARP请求中的IP地址与自己的IP地址匹配,则将主机pc1的地址和mac地址添加到本地缓存表中。
  4. 主机PC2将包含其mac地址的ARP回复消息直接发送回主机pc1(数据帧为单播)
  5. 主机pc1收到PC2返回的ARP回复消息,将PC2的IP和MAC地址添加至自己的ARP缓存表中,本机缓存是有生存期的,默认ARP缓存表有效期120s。当超过该有效期后,则将重复上面过程。主机pc2的MAC地址一旦确定,主机PC1就能向主机PC2发送IP信息

rp中,如果内网IP10.10.10.10,访问外网IP 100.100.100.100, 网关为10.10.10.1, 网关对外映射IP 100.100.100.1 ,这是arp的过程是什么样子的?

  1. 主机发送数据包:

    • 主机在发送数据包时,发现目标 IP 地址(100.100.100.100)不在同一子网内。
    • 主机会查找其本地 ARP 缓存表,如果没有找到目标 IP 对应的 MAC 地址,则会尝试发送 ARP 请求以获取目标 MAC 地址。
  2. ARP 请求发送:

    • 主机将发送一个 ARP 请求,目标 IP 地址为网关的 IP 地址(10.10.10.1)。
    • ARP 请求中包含主机自身的 IP 地址(10.10.10.10)、MAC 地址(主机的物理地址)以及目标 IP 地址(10.10.10.1)。
  3. 网关收到 ARP 请求:

    • 网关接收到 ARP 请求,检查请求中的目标 IP 地址。
    • 网关发现自己的 IP 地址与 ARP 请求中的目标 IP 地址匹配(即10.10.10.1),因此它会作出响应。
  4. 网关发送 ARP 响应:

    • 网关将会发送一个 ARP 响应给主机,包含网关自身的 MAC 地址。
    • 这个 ARP 响应中会包含主机之前请求的目标 IP 地址(10.10.10.1)和网关的 MAC 地址。
  5. 主机收到 ARP 响应:

    • 主机接收到网关的 ARP 响应后,将该映射关系存储到 ARP 缓存表中,以备将来使用。
    • 接着,主机会更新自己要发送到目标 IP 地址(100.100.100.100)的数据包,使用网关的 MAC 地址作为目标 MAC 地址。
  6. 数据包转发:

    • 网关接收到主机发来的数据包,因为它知道如何到达外部的 100.100.100.100,所以它会根据自身的路由表进行转发。
    • 网关将该数据包重新封装,将目标 IP 地址更改为 100.100.100.100,并将数据包发送到下一个目标,即外部网络。

arp报文抓包分析

arp请求报文

arp返回报文

三、用go实现发送ARP包

package mainimport ("bytes""errors""fmt""log""net""time""github.com/google/gopacket""github.com/google/gopacket/layers""github.com/google/gopacket/pcap""github.com/google/gopacket/routing""github.com/jackpal/gateway""github.com/libp2p/go-netroute"
)func main() {//targetIP := net.IP{100, 100, 100, 100} //设置目标地址//device, _ := GetDevByIp(targetIP)device, _ := GetDevByIp(net.IP{10, 100, 100, 100})srcIP, srcMac, gw, device2, _ := GetIpFromRouter(net.IP{100, 100, 200, 100})fmt.Println(srcIP, srcMac, gw)fmt.Println(device, device2)//构建ARP请求包arpLayer := &layers.ARP{AddrType:          layers.LinkTypeEthernet,  //硬件类型 1Protocol:          layers.EthernetTypeIPv4,  //上层协议类型0x0800HwAddressSize:     6,                        //mac地址长度ProtAddressSize:   4,                        // IP地址长度Operation:         layers.ARPRequest,        //操作类型,1为arp请求SourceHwAddress:   []byte(srcMac),           //本机的mac地址SourceProtAddress: []byte(srcIP),            //本机的IP地址DstHwAddress:      []byte{0, 0, 0, 0, 0, 0}, //目标mac地址,使用任意地址,未知DstProtAddress:    []byte{10, 122, 131, 225},}ethLayer := &layers.Ethernet{EthernetType: layers.EthernetTypeARP,                               //帧类型 0x0806SrcMAC:       srcMac,                                               //本机mac地址DstMAC:       net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, //广播mac地址}buffer := gopacket.NewSerializeBuffer()opts := gopacket.SerializeOptions{FixLengths: true}err := gopacket.SerializeLayers(buffer, opts, ethLayer, arpLayer)if err != nil {log.Fatal(err)}outgoingPacket := buffer.Bytes()handle, err := pcap.OpenLive(device, 1024, true, pcap.BlockForever)if err != nil {log.Fatal(err)}defer handle.Close()//发送 ARP请求包err = handle.WritePacketData(outgoingPacket)fmt.Printf("Outgoing Packet: %x\n", outgoingPacket)if err != nil {log.Fatal(err)}fmt.Println("arp request sent")time.Sleep(3 * time.Second)// 接收并处理响应包packetSource := gopacket.NewPacketSource(handle, handle.LinkType())timeout := time.After(5 * time.Second) // 设置超时时间为5秒// 接收并处理响应包for {select {case packet := <-packetSource.Packets():arpLayer := packet.Layer(layers.LayerTypeARP)if arpLayer != nil {arpPacket, _ := arpLayer.(*layers.ARP)if arpPacket.Operation == layers.ARPReply && bytes.Equal(arpPacket.SourceProtAddress, gw) {fmt.Printf("MAC address of %s is %s\n", gw.String(), arpPacket.SourceHwAddress)return}}case <-timeout:fmt.Println("Timeout: No response received")return}}
}// 获取设备名称
func GetDevByIp(ip net.IP) (devName string, err error) {devices, err := pcap.FindAllDevs()if err != nil {return}for _, d := range devices {for _, address := range d.Addresses {_ip := address.IP.To4()if _ip != nil && _ip.IsGlobalUnicast() && _ip.Equal(ip) {fmt.Println()fmt.Println("找到网络设备:", d.Name)//return d.Name, nil}}return d.Name, nil}return "", errors.New("can not find dev")
}// 通过扫描的目标IP获取发包的网卡信息,返回源IP、源mac、网关IP、设备名称
func GetIpFromRouter(dstIp net.IP) (srcIp net.IP, srcMac net.HardwareAddr, gw net.IP, devName string, err error) {//先验证扫描IP是否同网段srcIp, srcMac = GetIfaceMac(dstIp)if srcIp == nil {//如果不是同网段,则查询路由var r routing.Router    //创建一个 routing.Router 类型的变量,用于查询路由信息r, err = netroute.New() //初始化routing.Routerif err == nil {var iface *net.Interface               //创建变量iface用于保存与路由相关的网络接口信息iface, gw, srcIp, err = r.Route(dstIp) //通过路由查询路由信息,包括目标IP地址 dstIp 对应的路由信息。iface 保存了与该路由信息关联的网络接口,gw 保存了网关IP地址,srcIp 保存了与该路由信息关联的本地IP地址if err == nil {if iface != nil {srcMac = iface.HardwareAddr //如果找到了与目标IP地址匹配的路由信息,即 iface 不为 nil,则设置 srcMac 为该网络接口的MAC地址。否则,继续下一步} else {_, srcMac = GetIfaceMac(srcIp)}}}//如果在之前的步骤中出现错误或者 srcMac 为 nil,它尝试取得第一个默认网关的信息。if err != nil || srcMac == nil {//取第一个默认路由gw, err = gateway.DiscoverGateway() //获取第一个默认网关的IP地址if err == nil {srcIp, srcMac = GetIfaceMac(gw)}}}gw = gw.To4()srcIp = srcIp.To4()devName, err = GetDevByIp(srcIp)if srcIp == nil || err != nil || srcMac == nil {if err == nil {err = fmt.Errorf("err")}return nil, nil, nil, "", fmt.Errorf("no router,%s", err)}return}// 查找与指定IP地址相匹配的本地IP地址和MAC地址,其实就是检测是否同网段
func GetIfaceMac(ifaceAddr net.IP) (src net.IP, mac net.HardwareAddr) {interfaces, _ := net.Interfaces()  //获取本地计算机上的网络接口信息for _, iface := range interfaces { //遍历所有网络接口if addrs, err := iface.Addrs(); err == nil { //获取接口的IP地址列表for _, addr := range addrs { //遍历该接口的IP地址if addr.(*net.IPNet).Contains(ifaceAddr) { //检查每个IP地址是否包含了给定的ifaceAddr(即传参),这里用的contains方法,检查给定IP和接口IP是否同一子网return addr.(*net.IPNet).IP, iface.HardwareAddr //匹配就返回接口IP和mac地址}}}}return nil, nil}

相关文章:

arp报文及使用go实现

一、ARP协议报文格式及ARP表 ARP&#xff08;Address Resolution Protocal&#xff0c;地址解析协议&#xff09;是将IP地址解析为以太网的MAC地址&#xff08;或者称为物理地址&#xff09;的协议。在局域网中&#xff0c;当主机或其他网络设备有数据要发送给另一个主机或设备…...

C++ 文件和流、异常处理、动态内存、预处理器

一、C文件和流&#xff1a; 在C中进行文件处理&#xff0c;需要包含头文件<iostream>和<fstream>。fstream标准库定义的三个新的数据类型&#xff1a; 数据类型 描述 ofstream 该数据类型表示输出文件流&#xff0c;用于创建文件并向文件写入信息。 ifstream …...

夜神模拟器 burp抓包 ADB 微信小程序

夜神模拟器 burp抓包 ADB 微信小程序 初始环境准备应用连接证书转换设置夜神模拟器环境ADB配置测试burp抓包 初始环境准备 既然想了解如何抓包&#xff0c;我想大多数是已经安装好 夜神模拟器 和 Burp 了&#xff0c;这里就不在赘述&#xff0c;直接开始操作。 openssl 的下载…...

WPF实战项目十七(客户端):数据等待加载弹框动画

1、在Common文件夹下新建文件夹Events&#xff0c;新建扩展类UpdateLoadingEvent public class UpdateModel {public bool IsOpen { get; set; }}internal class UpdateLoadingEvent : PubSubEvent<UpdateModel>{} 2、新建一个静态扩展类DialogExtensions来编写注册和推…...

22-Python与设计模式--状态模式

22-Python与设计模式–状态模式 一、电梯控制器 电梯在我们周边随处可见&#xff0c;电梯的控制逻辑中心是由电梯控制器实现的。电梯的控制逻辑&#xff0c;即使简单点设计&#xff0c; 把状态分成开门状态&#xff0c;停止状态和运行状态&#xff0c;操作分成开门、关门、运…...

电脑键盘推荐

一、键盘分类 &#xff08;1&#xff09;键位个数 目前有75&#xff0c;84&#xff0c;87&#xff0c;98&#xff0c;104&#xff0c;108的。 &#xff08;2&#xff09;薄膜键盘和机械键盘 薄膜键盘就是大多数办公室常见的键盘&#xff0c;主要打一个便宜&#xff0c;耐造…...

大数据-之LibrA数据库系统告警处理(ALM-37001 MPPDBServer实例Redo日志缺失)

告警解释 当DN主实例有未同步到DN备实例的xlog日志被删除时&#xff0c;产生该告警。 告警属性 告警ID 告警级别 可自动清除 37001 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务名称 RoleName 产生告警的角色名称 HostName 产生告警的主机名…...

C#关键字、特性基础及扩展合集(持续更新)

一、基础 Ⅰ 关键字 1、record record&#xff08;记录&#xff09;&#xff0c;编译器会在后台创建一个类。支持类似于结构的值定义&#xff0c;但被实现为一个类&#xff0c;方便创建不可变类型&#xff0c;成员在初始化后不能再被改变 &#xff08;C#9新增&#xff09; …...

单例模式-支持并发的C语言实现

代码实现&#xff1a; c #include <stdio.h> #include <stdlib.h> #include <pthread.h>// 定义单例对象结构体 typedef struct {// 单例对象的数据成员int value; } Singleton;// 静态变量&#xff0c;用于保存唯一实例的指针 static Singleton* instance …...

java_基础_数据类型

1.数据类型 java 语言是强类型语言,对于每一种数据都给出了明确的数据类型,不同的数据类型也分配了不同的内存空间,所以他们的数据大小也不一样的. 数据类型关键字内存占用取值范围整数byte1-128~127short2-32768~32767int4-2的31次方到2的31次方-1long8-2的63次方到2的63次方…...

C++入门第九篇---Stack和Queue模拟实现,优先级队列

前言&#xff1a; 我们已经掌握了string vector list三种最基本的数据容器模板&#xff0c;而对于数据结构的内容来说&#xff0c;其余的数据结构容器基本都是这三种容器的延申和扩展&#xff0c;在他们的基础上扩展出更多功能和用法&#xff0c;今天我们便来模拟实现一下C库中…...

计算机组成原理(计算机系统概述)

目录 一. 计算机的发展二. 计算机硬件的基本组成2.1 早期冯诺依曼机2.2 现代计算机的结构 三. 各硬件的工作原理3.1 主存储器的基本组成3.2 运算器的基本组成3.3 控制器的基本组成 四. 计算机的工作过程 \quad 一. 计算机的发展 计算机系统 硬件 软件 #mermaid-svg-gp2AsYELE…...

Qt手写ListView

创建视图&#xff1a; QHBoxLayout* pHLay new QHBoxLayout(this);m_pLeftTree new QTreeView(this);m_pLeftTree->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑m_pLeftTree->setFixedWidth(300);创建模型和模型项&#xff1a; m_pLeftTree…...

【开源】基于Vue.js的城市桥梁道路管理系统的设计和实现

项目编号&#xff1a; S 025 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S025&#xff0c;文末获取源码。} 项目编号&#xff1a;S025&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥…...

2、git进阶操作

2、git进阶操作 2.1.1 分支的创建 命令参数含义git branch (git checkout -b)<new_branch> <old_branch>表示创建分支-d <-D>删除分支 –d如果分支没有合并&#xff0c;git会提醒&#xff0c;-D强制删除-a -v查看分支-m重新命名分支commit id从指定的commi…...

集线器-交换机-路由器

1.集线器(Hub) 集线器就是将网线集中到一起的机器&#xff0c;也就是多台主机和设备的连接器。集线器的主要功能是对接收到的信号进行同步整形放大&#xff0c;以扩大网络的传输距离&#xff0c;是中继器的一种形式&#xff0c;区别在于集线器能够提供多端口服务&#xff0c;也…...

金融众筹模式系统源码 适合创业孵化机构+天使投资机构+投资基金会等 附带完整的搭建教程

随着互联网技术的发展和金融市场的开放&#xff0c;金融众筹模式逐渐成为一种新型的融资方式。这种模式通过互联网平台聚集大量投资者&#xff0c;共同参与到一个项目中&#xff0c;为项目提供资金支持&#xff0c;最终获得投资回报。今天罗峰给大家分享一款金融众筹模式系统源…...

大数据学习(24)-spark on hive和hive on spark的区别

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…...

SQLite3 数据库学习(六):Qt 嵌入式 Web 服务器详解

参考引用 SQLite 权威指南&#xff08;第二版&#xff09;SQLite3 入门 1. Apache 搭建 cgi 环境 1.1 什么是 Apache Apache 是世界使用排名第一的 Web 服务器软件 它可以运行在几乎所有广泛使用的计算机平台上&#xff0c;由于其跨平台和安全性被广泛使用 1.2 具体搭建流程…...

各平台chatGPT使用体验(国内外)

首推&#xff1a;openAI 地址&#xff1a;https://chat.openai.com/ 这个真的很好用&#xff0c;而且回复的结果也基本让让人满意&#xff0c;个人首推&#xff0c;而且对比国内的除了回答更令人满意外&#xff0c;它更连贯&#xff0c;不像国内的gpt一句一问&#xff0c;跟进…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...