Linux文件系统与设备文件
Linux文件系统与设备文件
文章目录
- Linux文件系统与设备文件
- Linux文件操作
- 文件操作系统调用
- C库文件操作
- Linux文件系统
- Linux文件系统目录结构
- Linux文件系统与设备驱动
- file结构体
- inode结构体
- file结构体和inode结构体的区别
- devfs
- udev用户空间设备管理
- sysfs文件系统与Linux设备模型
字符设备和块设备体现了Linux中的一切皆文件的设计思想,驱动通过文件操作相关的系统调用和C库函数(本质也属于系统调用)被访问,其次驱动工程师在设备驱动中不可避免会与设备文件系统打交道,这也引出了我们需要掌握设备文件系统的相关知识。
Linux文件操作
文件操作系统调用
涉及到创建打开关闭等操作
- 创建
int creat(const char *filename, mode_t mode)
其中参数filename指的是文件名,mode指的是文件的权限,它同umask决定了文件的最终权限,umask代表了文件在创建时要去除的一些存取权限
int umask(int newmask)
将umask设置为新的mask,然后返回旧的umask,只影响读写执行的权限
- 打开
int open(const char *pathname, int flags, mode_t mode);
int open(const char *pathname, int flags);
pathname默认的是当前文件夹的下面
文件的打开标志:
标志 | 含义 |
---|---|
O_RDONLY | |
O_WRONLY | |
O_RDWR | rdonly,wronly和rdwr这三个标志只能选取其中一个,不能同时存在 |
O_APPEND | |
O_CREAT | |
O_EXEC | 如果使用了O_CREAT而且文件已经存在,就会发生一个错误 |
O_NOBLOCK | 以非阻塞的方式打开一个文件 |
O_TRUNC | 如果文件已经存在,则删除文件的内容 |
如果使用了mode_t,表示打开时有文件的访问权限:
标志 | 含义 |
---|---|
S_IRUSR | 用户可以读 |
S_IWUSR | |
S_IXUSR | |
S_IRGRP | 组可以读 |
S_IWGRP | |
S_IXGRP | |
S_IROTH | 其他人可以读 |
S_IWOTH | |
S_IXOTH | |
S_IRWXO | 其他人可以读写执行 |
S_ISUID | 设置用户执行ID(set UID) |
S_ISGID | 设置组执行ID |
除了上述宏来表示的产生标志之外,我们自己也可以用数字来表示
文件权限共5位:从左往右数第一位用户ID、第二位组ID、第三位自己的权限、第四位组权限、第五位其他人的权限;
数字表示1(执行权限)、2(写权限)、4(读权限)、0(无权限)
-
例如要创建一个用户可读、可写、可执行、但是组没有权限,其他人可以读、可以执行的文件,并设置用户ID。
open(filename, O_CREAT, 10 705);
open(filename, O_CREAT, S_IRWXU|S_IROTH|S_XOTH|S_ISUID);
如果文件打开成功会返回一个文件描述符,以后对于文件的所有操作都可以通过对这个文件描述符进行操作来实现。
- 读写
int read(int fd, const void *buf, size_t length);
buf为缓冲区名称,length为缓冲区的大小,单位为字节,表示在fd中读取length个字节写入buf中,返回的是实际读取的字节数。
int write(int fd, const void *buf, size_t length);
表示从buf中读取length字节数写入fd中,返回实际写入的字节数
- 定位lseek
int lseek(int fd, offset_t offset, int whence);
lseek将文件的读写指针相对whence移动了offset个字节,返回文件指针相对于文件开发的位置
SEEK_SET | 相对文件开头 |
---|---|
SEEK_CUR | 相对当前位置 |
SEEK_END | 相对文件末尾 |
lseek(fd, 0, SEEK_END)
表示文件的大小
也就是文件指针是从wherece的位置处开始移动,结果移动了0个位置,指针就停在了whence的位置,而函数返回值是文件指针相对于文件开头的位置,因此这个返回值就是文件的长度。
- 关闭
int close(int fd);
例如,编写一个程序,在当前目录下面创建用户可读写文件hello.txt,在其中写入“hello,software weekly”,关闭该文件,再次打开该文件,读取其中的内容输出在屏幕上
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>#define BUFF_SIZE 100int man()
{int ret;char buff[BUFF_SIZE];int fd = open("hello.txt", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);if(fd){ret = write(fd, "hello,software weekly", strlen(hello,software weekly));if(ret < 0)printf("write failed\n");close(fd);
}else{printf("creat failed\n");
}fd = open("hello.txt", O_RDONLY);ret = read(fd, buff, sizeof(buff));if(ret){printf("read failed\n");close(fd);
}buff[ret] = "\0";printf("%s\n", buff);close(fd);
}
C库文件操作
- 创建和打开
FILE *fopen(const char *path, const char *mode);
mode为C库函数打开的标志:
标志 | 含义 |
---|---|
r、rb | 读 |
r+、r+b | 读写 |
w | 写,不存在则创建 |
w+、w+b | 读写,不存在则创建 |
a | 追加,不存在则创建 |
a+、a+b | 读写且追加,不存在则创建 |
b为二进制文件,在window下面是有区分的,但是Linux下面则没有
- 读写
int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int fputs(const char *s, FILE *stream);
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
fread表示从stream流中读取n个字段,每个字段大小为size个字节,将读取到的数据存到ptr中,返回已经读取的字段数。当读取的字段数小于n时,可能是在函数调用时出现了错误,也可能是读到了文件的末尾。因此要通过调用feof()和ferror()来判断。
另外C库还提供了定位函数:
int fseek(FILE *stream, long offset, int whence);
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, const fpos_t *pos);
- 关闭
int fclose(FILE *stream);
例如,编写一个程序,在当前目录下面创建用户可读写文件hello.txt,在其中写入“hello,software weekly”,关闭该文件,再次打开该文件,读取其中的内容输出在屏幕上
#include <stdio.h>#define BUFF_SIZE 100
int main()
{char buff[BUFF_SIZE];FILE *fd = fopen("hello.txt", w+);if (fd){fputs("hello,software weekly", fd);fclose(fd);
}fd = fopen("hello.txt", r+);if(fd){fgets(buff, sizeof(buff), fd);printf("%s\n", buff); //fgets函数会默认在字符串后面补"\0"fclose(fd);
}
}
Linux文件系统
Linux文件系统目录结构
linux文件系统目录结构
Linux文件系统与设备驱动
应用程序与文件系统直接的接口是系统调用,文件系统与设备文件之间的接口是file_operations结构体成员函数。
由于字符设备的上层没有类似于文件系统,所以字符设备的file_operations成员函数就直接由设备驱动提供了
块设备有两种访问方法:
-
一种是不通过文件系统直接访问裸设备,在Linux内核实现了统一的def_blk_fops这一file_operations
类似于”dd if=/dev/sdb1 of=sdb1.img”这一指令是不通过文件系统,直接访问的驱动设备文件
-
第二种是通过文件系统访问块设备,file_operations的实现则位于文件系统内,文件系统会把针对文件的读写转换为针对块设备原始扇区的读写
在设备驱动程序的设计种,一般而言,会关心file和inode这两个结构体
file结构体
系统中每个打开的文件在内核空间都有一个关联的struct file,在内核和驱动源代码中,struct file的指针通常被命名为file或者filep
文件结构体struct file中读写模式mode、标志f_flags都是设备驱动关心得内容,而私有指针private_data在设备驱动中被广泛使用大多数指向设备驱动自定义以**用于描述设备的结构体,**是更高级的文件描述,依赖于低层的struct inode数据结构
inode结构体
VFS inode是Linux管理文件系统的最基本的单位,也是文件系统连接任何子目录,文件的桥梁,只与操作系统相关,用于保存文件或者目录信息。
表示设备文件的inode结构,i_rdev字段包含设备编号。Linux的设备编号分为主设备编号和次设备编号,前者为dev_t的高12位,后者位dev_t的低20位
unsigned int imajor(struct inode *inode);
获取主设备号,主设备号是驱动对应的概念,同一类设备一般使用相同的主设备号,序号一般从0开始
unsigned int imanor(struct inode *inode);
获取次设备号
查看 /proc/devices
可以获知系统中所注册的设备
file结构体和inode结构体的区别
struct inode和struct file的区别在于inode只关心操作系统找出底层文件结构的内容(例如什么设备文件),而不去具体的跟踪文件的当前位置和当前模式。struct file是个基本结构,实际上持有一个struct inode的指针,他代表打开的文件,并且提供一组函数,他们与底层文件结构执行方法有关
也就是说struct inode只代表内核中的文件,而struct file表示实际打开的文件,同一个文件被打开时可能有多个文件描述符,但他们都指向同一个inode。
devfs
devfs(设备文件系统)是由Linux 2.4内核出现的,使得设备驱动程序能够自主地管理自己的设备文件
- 可以在程序初始化的时候在/dev目录下创建设备文件,卸载设备时将它删除
- 设备驱动程序可以指定设备名、所有者和权限位
- 不再需要为设备驱动程序分配主设备号以及处理次设备号,在程序中可以直接给
register_chrdev()
传递0主设备号以获得可用的主设备号,并在devfs_register()
中指定次设备号
udev用户空间设备管理
- udev是在Linux 2.6的时候被引入,与devfs不同的是,就像谈恋爱,udev系统可以使得用户在上层自由选择和谁谈恋爱,而不能在内核空间限制和谁谈恋爱。对于devfs而言,第一个相亲女孩被命名为/dev/girl0,第二个相亲女孩被命名为/dev/girl1。而在用户空间实现的udev则可以,不管你中意的女孩是第几个,只要符合要求,都是/dev/mygirl。
- udev完全工作在用户态,利用设备的热插拔事件来工作,详细的设备信息会由内核通过netlink套接字发送出来,发出的事情叫uevent。
- 那冷插拔事件怎么办呢,设备当主机开机时就已经存在了,Linux内核提供了sysfs下面的一个uevent节点,往该节点写一个”add”,(具体怎么写我也不是很懂)导致内核重新发送netlink,之后udev就可以收到冷插拔的netlink消息了
- 对于devfs,当一个并不存在的/dev节点被访问时,系统会自动加载相对应的设备驱动,而udev却不是这样,是在产生热插拔事件时才会加载相应的驱动,并且创建的对应节点
sysfs文件系统与Linux设备模型
udev和sysfs都是Linux系统的一部分,但它们有不同的功能和用途。sysfs是一个虚拟文件系统,用于从用户空间访问内核对象的属性。它将内核对象的属性表示为文件和目录,使得用户空间的程序能够通过标准的文件系统接口查询和更改内核对象的属性。包括展示设备驱动模型中各组件的层次关系。
在/sys/目录下的顶级目录:
block | 包含所有的块设备 |
---|---|
devices | 包含系统所有的设备 |
bus | 包含所有的总线类型 |
class | 包含系统中的设备类型 |
他们实际上都会被认为是kobject的派生类,一个kobject对应sysfs中的一个目录。
在/sys/bus/pci的目录下又会出现devices和drivers,而这个devices目录下的文件是对/sys/devices下的文件的符号链接
与此不同,udev是一个设备管理器,它管理/dev目录下的设备节点。当内核检测到新设备时,它将发送一个uevent,udev将接收到这个事件并对其进行处理。这可能包括加载设备驱动,创建或删除设备节点,甚至更改设备的权限和所有权。udev的工作依赖于sysfs,因为它使用sysfs提供的信息来确定如何处理设备。
总的来说,sysfs是一个提供有关内核对象的信息的接口,而udev则使用这些信息来管理设备。就好比udev是做饭的方法,而sys是菜和米饭
-
在Linux内核中,分别使用bus_type、device_driver和device来描述总线、驱动和设备,这三个结构体定义在include/linux/device.h中
- device_driver和device分别代表驱动和设备,他们都会挂载在总线上面,因此结构体中也都包含struct bus_type指针
- 驱动和设备注册的时候不需要都存在,注册设备时不需要对应的驱动被注册,注册驱动时不需要对应的设备被注册,而都注册之后,又如何连接起来呢
- 通过bus_type结构体的match()成员将两者捆绑在一起,一旦捆绑成功bus_driver的probe()就被执行
- 驱动、设备、总线的attribute都会落实为sys中的一个文件,会伴随着show()和store()这两个函数进行读写操作
- sysfs中的目录来源于device、device_driver、bus_type,而目录中的文件就来源于attribute
- 定义了一些快捷方式以方便attribute的创建工作
#define DRIVER_ATTR(_name, _mode, _show, _store) \struct driver_attribute driver_attr_##_name = __ATTR(_name, _ mode, _show, _store) #define DRIVER_ATTR_RW(_name) \struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) #define DRIVER_ATTR_RO(_name) \struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) #define DRIVER_ATTR_WO(_name) \struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)#define BUS_ATTR(_name, _mode, _show, _store) \struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _ store) #define BUS_ATTR_RW(_name) \struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) #define BUS_ATTR_RO(_name) \struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)#define DEVICE_ATTR(_name, _mode, _show, _store) \struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) #define DEVICE_ATTR_RW(_name) \struct device_attribute dev_attr_##_name = __ATTR_RW(_name) #define DEVICE_ATTR_RO(_name) \struct device_attribute dev_attr_##_name = __ATTR_RO(_name) #define DEVICE_ATTR_WO(_name) \struct device_attribute dev_attr_##_name = __ATTR_WO(_name) #define DEVICE_ULONG_ATTR(_name, _mode, _var) \struct dev_ext_attribute dev_attr_##_name = \{ __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } #define DEVICE_INT_ATTR(_name, _mode, _var) \struct dev_ext_attribute dev_attr_##_name = \{ __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) } #define DEVICE_BOOL_ATTR(_name, _mode, _var) \struct dev_ext_attribute dev_attr_##_name = \{ __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) } #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \struct device_attribute dev_attr_##_name = \__ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
撰写不易,留下您的关注和点赞,我们一起进步!
相关文章:

Linux文件系统与设备文件
Linux文件系统与设备文件 文章目录 Linux文件系统与设备文件Linux文件操作文件操作系统调用C库文件操作 Linux文件系统Linux文件系统目录结构Linux文件系统与设备驱动file结构体inode结构体file结构体和inode结构体的区别 devfsudev用户空间设备管理sysfs文件系统与Linux设备模…...

QT的绘图系统QPainterDevice与文件系统QIODevice
QT的绘图系统(QPainterDevice)与文件系统(QIODevice) 文章目录 1、Qt 的绘图系统1、QPainter的使用2、QPen(画笔)及QBursh(画刷)3、手动更新窗口4、绘图设备1、四种绘图设备的 区别2、 QBitmap3…...

Spark流式读取文件数据
流式读取文件数据 from pyspark.sql import SparkSession ss SparkSession.builder.getOrCreate() # todo 注意1:流式读取目录下的文件 --》一定一定要是目录,不是具体的文件,# 目录下产生新文件会进行读取# todo 注意点2࿱…...

Leetcode 3011. Find if Array Can Be Sorted
Leetcode 3011. Find if Array Can Be Sorted 1. 解题思路2. 代码实现 题目链接:3011. Find if Array Can Be Sorted 1. 解题思路 这一题挺简单的,就是一个分组进行排序考察,我们将相邻且bit set相同的元素划归到同一组,然后进…...

Databend 开源周报第 129 期
Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展,遇到更贴近你心意的 Databend 。 支持标准流 标…...

python 正则表达式学习(1)
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 1. 特殊符号 1.1 符号含义 模式描述^匹配字符串的开头$匹配字符串的末尾.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包…...

安全防御-基础认知
目录 安全风险能见度不足: 常见的网络安全术语 : 常见安全风险 网络的基本攻击模式: 病毒分类: 病毒的特征: 常见病毒: 信息安全的五要素: 信息安全的五要素案例 网络空间:…...

各省税收收入、个人和企业所得税数据,Shp、excel格式,2000-2021年
基本信息. 数据名称: 各省税收收入、个人和企业所得税数据 数据格式: Shp、excel 数据时间: 2000-2021年 数据几何类型: 面 数据坐标系: WGS84 数据来源:网络公开数据 数据字段: 序号字段名称字段说明1sssr_2021税收收入(亿元&am…...

Vue记录
vue2、vue3记录,参考地址:尚硅谷Vue项目实战硅谷甄选,vue3项目TypeScript前端项目一套通关_哔哩哔哩_bilibili vue2记录 经典vue2结构 index.vue: <template><div>...</div> </template><script>…...

【JavaEE进阶】 Spring Boot⽇志
文章目录 🎋关于日志🚩为什么要学习⽇志🚩⽇志的⽤途🚩日志的简单使用 🎄打印⽇志🚩程序中得到⽇志对象🚩使⽤⽇志对象打印⽇志 🎍⽇志格式的说明🚩⽇志级别的作用&#…...

《GitHub Copilot 操作指南》课程介绍
第1节:GitHub Copilot 概述 一、什么是 GitHub Copilot 什么是 GitHub Copilot GitHub Copilot是GitHub与OpenAI合作开发的编程助手工具,利用机器学习模型生成代码建议。它集成在开发者的集成开发环境(IDE)中,可以根…...

结构体(C语言)
结构体 1.结构体基础知识: //结构是一些值的集合,这些值称为成员变量. // 结构的每个成员可以是不同类型的变量. 2.结构的定义 struct peo { char name[10];//姓名 char tele[12];//电话 char gender[5];//性别 int high;//身高 }; struct stu { struct…...

HNU-数据挖掘-实验1-实验平台及环境安装
数据挖掘课程实验实验1 实验平台及环境安装 计科210X 甘晴void 202108010XXX 文章目录 数据挖掘课程实验<br>实验1 实验平台及环境安装实验背景实验目标实验步骤1.安装虚拟机和Linux平台,熟悉Ubuntu环境。2.在Linux平台上搭建Python平台,并安装…...

JavaEE中的监听器的作用和工作原理
在JavaEE(Java Platform, Enterprise Edition)中,监听器(Listener)是一种重要的组件,用于监听和响应Web应用程序中的事件。监听器的作用是在特定的事件发生时执行一些自定义的逻辑。常见的监听器包括Servle…...

Webpack5入门到原理1:前言
为什么需要打包工具? 开发时,我们会使用框架(React、Vue),ES6 模块化语法,Less/Sass 等 css 预处理器等语法进行开发。 这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、Css 等语法…...

#vue3 实现前端下载excel文件模板功能
一、需求: 前端无需通过后端接口,即可实现模板下载功能。 通过构造一个 JSON 对象,使用前端常用的第三方库 xlsx,可以直接将该 JSON 对象转换成 Excel 文件,让用户下载模板 二、效果: 三、源码如下&…...

《WebKit 技术内幕》之五(3): HTML解释器和DOM 模型
3 DOM的事件机制 基于 WebKit 的浏览器事件处理过程:首先检测事件发生处的元素有无监听者,如果网页的相关节点注册了事件的监听者则浏览器会将事件派发给 WebKit 内核来处理。另外浏览器可能也需要处理这样的事件(浏览器对于有些事件必须响应…...

136基于matlab的自适应滤波算法的通信系统中微弱信号检测程序
基于matlab的自适应滤波算法的通信系统中微弱信号检测程序,周期信号加入随机噪声,进行滤波,输出滤波信号,程序已调通,可直接运行。 136 matlab自适应滤波算法LMS (xiaohongshu.com)...

【Linux】权限 !
Linux 权限 Liunx Linux 权限1 什么是权限1.1 Linux用户1.2 切换用户 2 权限管理2.1 文件访问者的分类2.2 文件类型和访问权限2.3 文件权限的设置方法chmod 命令chown 命令chgrp 命令umask 命令file 指令 2.4 目录权限粘滞位 3 权限总结 1 什么是权限 关于Linux的权限问题&…...

axios原理
文章目录 axios基本概念axios多种方式调用工具函数axios的拦截器如何实现?用的设计模式是哪种?axios如何实现取消请求,和cancelToken如何使用 axios基本概念 axios是目前比较流行的一个js库,是一个基于promise的网络数据请求库&am…...

epoll
常用函数 //创建 /** * param size 告诉内核监听的数目 * * returns 返回一个epoll句柄(即一个文件描述符) */ int epoll_create(int size);//控制 /** * param epfd 用epoll_create所创建的epoll句柄 * param op 表示对epoll监控描述符控制的动作 * * …...

AEB滤镜再破碎,安全焦虑「解不开」?
不久前,理想L7重大交通事故,再次引发了公众对AEB的热议。 根据理想汽车公布的事故视频显示,碰撞发生前3秒,车速在178km/h时驾驶员采取了制动措施,但车速大幅超出AEB(自动紧急刹车系统)的工作范…...

深度学习和机器学习中针对非时间序列的回归任务,有哪些改进角度?
深度学习和机器学习中针对非时间序列的回归任务,有哪些改进角度? 目录 深度学习和机器学习中针对非时间序列的回归任务,有哪些改进角度?引言1 数据预处理2 数据集增强3 特征选择4 模型选择5 模型正则化与泛化6 优化器7 学习率8 超…...

无限商机、拓全国、赢未来!2024上海国际轴承展重磅来袭!
中国设备管理协会主办的“2024上海国际轴承及其专用装备展览会”将于2024年7月24日至26日在“国家会展中心(虹桥)”举办。展会预计展出面积55000平方米,汇聚来自世界各地的近1000家企业与60000多人次的国内外观众齐聚一堂。为期三天的展览会是…...

PPT 编辑模式滚动页面不居中
PPT 编辑模式滚动页面不居中 目标:编辑模式下适应窗口大小、切换页面居中显示 调整视图大小,编辑模式通过Ctrl 鼠标滚轮 或 在视图菜单中点击适应窗口大小。 2. 翻页异常,调整视图大小后,PPT翻页但内容不居中或滚动,…...

笨蛋学设计模式结构型模式-享元模式【13】
结构型模式-享元模式 7.7享元模式7.7.1概念7.7.2场景7.7.3优势 / 劣势7.7.4享元模式可分为7.7.5享元模式7.7.6实战7.7.6.1题目描述7.7.6.2输入描述7.7.6.3输出描述7.7.6.4代码 8.1.7总结享元模式 7.7享元模式 7.7.1概念 享元模式是通过共享对象减少内存使用,来…...

磁盘的分区与文件系统的认识
磁盘的认识 了解磁盘的结构: 1、盘片 硬盘首先会有多个盘片构成,类似很多个独立的光盘合并在一起,每个盘片都有2个面,每个盘片都有一个对应的磁头,我们的磁头横移和盘面的旋转就可以读写到盘面的每一个位置,…...

韩国访问学者如何申请?
作为访问学者,前往韩国学术机构进行研究是一项令人期待的经历。首先,申请者需要查找目标学术机构的官方网站,下面知识人网小编带大家了解其访问学者计划的具体要求和申请流程。 通常,申请程序包括填写在线申请表格,提交…...

MybatisPlus框架入门级理解
MybatisPlus 快速入门入门案例常见注解常用配置 核心功能条件构造器自定义SQLService接口 快速入门 入门案例 使用MybatisPlus的基本步骤: 1.引入MybatisPlus的起步依赖 MybatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能&#…...

ELK 分离式日志(1)
目录 一.ELK组件 ElasticSearch: Kiabana: Logstash: 可以添加的其它组件: ELK 的工作原理: 二.部署ELK 节点都设置Java环境: 每台都可以部署 Elasticsearch 软件: 修改elasticsearch主配置文件&…...