Nacos入门

Nacos:以“服务”为中心的现代应用架构的服务基础设施

1、Nacos功能

Nacos主要功能在微服务中主要体现:配置中心、注册中心

1.1、Nacos优点

简单易用、特性丰富、超高性能、超大容量、高可用(这里几个特点下面会提到)

有些友友肯定对于配置中心和注册中心是有点分不清的,下面会一步步让你分清这两个的区别

1.2、安装并启动

(1)Nacos安装和运行需要依赖JDK环境,因此在安装之前,需要先在服务器安装JDK1.8+的环境

(2)安装并启动

这里直接编译压缩包进行安装(下面是linux上进行安装的)

下载压缩包:直接来github上下载就行 Releases · alibaba/nacos (github.com)

 解压压缩包:unzip nacos-server-版本.zip 或者 tar -xvf nacos-server-版本.tar.zip

进入Nacos运行目录:cd nacos/bin;

启动Nacos服务:

Linux:sh startup.sh -m standalone 启动 Nacos 单击模式

windows:startup.cmd -m standalone 启动Nacos单击模式

下面展示一下:windows上得启动方式(方便演示)

 下载好的,直接解压一份出来就可以了,我解压后改了个名字叫nacos文件夹

注:这里在你没有配置端口的时候,默认是8848端口

1.3、开启控制台授权登录

建议使用VS Code打开,快捷查找ctrl + F  

nacos.core.auth.enabled=true

nacos.core.auth.server.identity.key=nacos

nacos.core.auth.server.identity.value=nacos

nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789

 配置好以后,重启一下服务 访问之后会出现这个,点击确定就行

2、配置中心

2.1、创建配置服务

注:配置内容就是我们统一配置管理的信息 

2.2、Spring Boot项目使用配置中心

(1)添加nacos-config依赖

(2)在项目配置文件设置nacos相关信息

(3)使用@Value注解

除了以上的依赖还需要一个spring web依赖,方便我们进行演示操作

不用东西可以直接删除,以下是不需要的东西

application.properties文件的配置

# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html
# Nacos认证信息
#登录 nacos 用户名
spring.cloud.nacos.config.username=nacos
#登录密码 nacos
spring.cloud.nacos.config.password=nacos
#访问路径  不变的
spring.cloud.nacos.config.contextPath=/nacos
# 设置配置中心服务端地址
spring.cloud.nacos.config.server-addr=localhost:8848
# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
# spring.cloud.nacos.config.namespace=
#第一个nacos 表示的协议 : 配置名称
spring.config.import=nacos:nacos-config-example

注:这里的配置是不存在mysize的,mysize配置参数是写在nacos的配置中心的

2.3、特点

下面写一个类,访问,拿到nacos中配置参数

@RestController
@RequestMapping("/test")
public class TestController {

    @Value("${mysize}")
    private String mysize;

    @RequestMapping("/get")
    public String get(){
        return "nacos-config : "+ mysize;
    }
}

启动项目之后,按照路径进行访问

 特点1:集中管理配置信息: 配置中心将不同服务的配置信息集中放在一起进行管理,实现了配置信息的集中存储,java代码也就不用写那么多了(这里拿到的就是配置中心存放的进行统一管理信息)

特点2:动态更新配置:配置中心的配置信息可以通过操作界面或者API进行动态更新,无需重启服务就可以应用最新的配置信息

如果这里我们修改配置信息,会进行热更新吗?就以现在代码,当然是不行的

这里需要加入一个注解,能意识到Nacos配置中心在更改

在原有代码的基础上添加一个注解@RefreshScope

@RestController
@RefreshScope
@RequestMapping("/test")
public class TestController {

    @Value("${mysize}")
    private String mysize;

    @RequestMapping("/get")
    public String get(){
        return "nacos-config : "+ mysize;
    }
}

就会进行实时更新,记得重启

注:修改内容后发布会有一个比对,这里绿色表示新添加的内容,红色表示删除内容,此时直接刷新就可以看见访问内容改变

特点3:配置信息共享:将配置集中在配置中心中,不同的服务实例可以共享一套配置信息,在上面配置文件的时候,这里有一个分组和Data ID,多个服务都可以使用同一个Data ID来实现配置共享

特点4:配置信息安全:配置中心可以配对信息,提供安全管理,权限控制等管理功能

特点5:信息追溯:支持配置版本管理、历史记录等管理功能

下面演示特点5,我们前面在Nacos中修改过一次配置信息,Nacos里面是记录了历史版本的

注:配置列表本身是存在在nacos自己给的一个存储文件中 嵌入式数据库Derby,一旦删除配置数据就会丢失,下面解释

3、Nacos注册中心 

3.1、配置数据源

Nacos单击模式启动默认使用的是内置的嵌入式数据库Derby作为数据存储的,但是Derby不适合承载生产环境大规模部署,因为它有以下限制:

(1)数据存储容量最大只有2GB

(2)不支持集群模式下数据的高可用复制

(3)性能和并发能力有限

在生产环境中使用单击模式时,可以使用外置数据库作为数据存储,这里展示的是MySQL

数据源切换为MySQL

Nacos 0.7版本增加支持MySQL数据源能力:

(1)安装数据库,版本要求:5.6.5+;

(2)初始化MySQL数据库,数据库初始化文件:

注:下载好的Nacos包中是自带mysql的sql语句的 

直接打开MySQL创建一个叫做nacos的数据库,把这个sql文件内容插入到前面创建的nacos数据库中(我这里使用的workbench进行操作),当前已经创建好了nacos数据库并导入表信息

 (3)修改Nacos安装目录中中conf/application.properties文件,增加支持MySQL数据库配置,添加MySQL数据源的URL、用户名和密码,配置如下(将以下配置的注释去掉,并进行修改):

spring.datasource.platform=mysql

db.num=1

db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC

db.user.0=root

db.password.0=226688

datasource:表示数据源使用的是MySQL

num:表示数据库个数(这里我只有一个数据库所以就写了1)

url:数据库访问路径记住着连接的是我们刚刚导入那个nacos数据库,名字处理好

user.0:就是第一个数据库用户名(我的数据库用户名是root,请输入你的用户名)

password.0:就是第一个数据库密码(我的数据库密码是226688,请输入你的用户名)

3.2、注册中心

注册中心的交互过程:

服务提供者(生产者):对外提供服务的微服务应用,它会把自身的服务地址注册到注册中心,以供消费者发现者和调用

服务调用者(消费者):调用其他微服务的应用程序,它会向注册中心订阅自己需要的服务,并基于服务提供者注册的信息发起远程调用

3.2.1、生产者实现

(1)添加nacos-discovery依赖

(2)配置nacos服务器端信息

(3)编写调用接口

这里我从新创建一个项目来针对注册中心解释的

注:删除父类的src

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider</name>
    <description>provider</description>
    <!--标签 配置 父类-->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>nacos-discovery-csdn</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <!--因为我们这里继承父类 配置就可以省去了 这里的就可以删除了-->
<!--    <properties>-->
<!--        <java.version>17</java.version>-->
<!--        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
<!--        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>-->
<!--        <spring-boot.version>3.0.2</spring-boot.version>-->
<!--    </properties>-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!--这里的依赖配置管理 父类已经配置过了,所以这里的就可以删除了-->
<!--    <dependencyManagement>-->
<!--        <dependencies>-->
<!--            <dependency>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-dependencies</artifactId>-->
<!--                <version>${spring-boot.version}</version>-->
<!--                <type>pom</type>-->
<!--                <scope>import</scope>-->
<!--            </dependency>-->
<!--        </dependencies>-->
<!--    </dependencyManagement>-->

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.provider.ProviderApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

 提供者的配置:

spring:
  application:
    name: provider    #服务名称 一会在Nacos注册中心会看见的
  cloud:
    nacos:            #nacos 服务
      discovery:      #进行注册配置
        server-addr: localhost:8848      #配置nacos的访问地址
        username: nacos                  #配置登录用户
        password: nacos                  #配置用户密码
server:
  port: 0  #端口随机分配 提供者 不需要具体的端口

提供者写一个代码: 在provider项目中创建一个controller层同时在该层建立一个UserController类

@RestController
@RequestMapping("/user")
public class UserController {
    
    //为了获取端口号 注入webServer相关注解
    @Autowired
    private WebServerApplicationContext serverApplicationContext;
    
    @RequestMapping("/getname")
    public String getName(@RequestParam("id") Integer id){
        return "provider  : "+id+" | port "+serverApplicationContext.getWebServer().getPort();
    }
}

3.2.2、消费者实现

消费者,需要调用生产者的HTTP接口,需要引入OpenFeign进行HTTP调用,其次为了实现负载均衡,所以开始添加了LoadBalancer

(1)添加依赖(注册中心,OpenFeign、LoadBalancer)

(2)配置nacos服务信息

(3)在项目中开启OPenFeign

(4)编写OPenFeign调用代码

(5)编写代码通过OpenFeign调用生产者

这里我们们直接使用父工程的,父工程已经导入了,我这里就直接创建项目依赖父工程管理就行

注:大体和提供者一样,配置父工程,删除自己的相关配置和依赖管理

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumer</name>
    <description>consumer</description>
    <!--首先继承父工程-->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>nacos-discovery-csdn</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <!--删除自己配置 直接使用父工程的配置-->
<!--    <properties>-->
<!--        <java.version>17</java.version>-->
<!--        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
<!--        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>-->
<!--        <spring-boot.version>3.0.2</spring-boot.version>-->
<!--    </properties>-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!--删除自己的依赖管理 父工程提我们管理了-->
<!--    <dependencyManagement>-->
<!--        <dependencies>-->
<!--            <dependency>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-dependencies</artifactId>-->
<!--                <version>${spring-boot.version}</version>-->
<!--                <type>pom</type>-->
<!--                <scope>import</scope>-->
<!--            </dependency>-->
<!--        </dependencies>-->
<!--    </dependencyManagement>-->

下面我们来写下配置文件:

spring:
  application:
    name: provider    #服务名称 一会在Nacos注册中心会看见的
  cloud:
    nacos:            #nacos 服务
      discovery:      #进行注册配置
        server-addr: localhost:8848      #配置nacos的访问地址
        username: nacos                  #配置登录用户
        password: nacos                  #配置用户密码
        register-enabled: false  #表示注册显示 消费者 不需要显示
server:
  port: 8080

 注:下面开始编写消费者代码的时候,需要涉及远程调用所以consumer的启动类上需要添加一个@EnableFeignClients

 启动提供者和消费者(注意:确保nacos服务是启动的)

 3.3、注册中心参数

分组:注册服务所在的组名,默认是DEFAULT——GROUP,例如:研发小组,测试小组等

这里演示一下该操作;提供者的服务进行一下克隆,这里只需要在已经启动的提供者服务右击选择cope configuration ( 点击modify options选择 program arguments配置以下内容)

 服务路由类型:常见有以下两种:

none:默认路由,基于权重的轮询负载均衡路由策略

label:标签路由,相同标签的实例会被聚合为一个集群,不同标签则实现流量隔离(不常用)

临时实例-永久实例

永久实例(Persistent Instance):是指注册到Nacos的服务实例,其注册信息会一直保留在Nacos服务器上,知道主动注销或者被删除。这意味即使服务实例下线或不可用,它的注册信息仍然会保留在Nacos上,直到显示取消注册。永久实例适用于需要长期存在服务

临时实例(Ephemeral Instance):是指注册到Nacos的服务实例,其注册信息在实例下线或不可用时会自动被删除。如果服务实例下线,、断开连接或者主动注销,Nacos会自动从注册表中删除这些实例的信息。临时实例适用于临时性的服务实例

以上两种实例主要针对健康检测机制有不同显示

健康检查机制应用

Nacos中提供两种健康检测的机制:

客户端主动上报(健康状态的)机制:客户端有问题了,及时向服务器求救

服务器端反向探测(健康状态的)机制:服务器定期扫描检测服务是否健康

临时实例(非持久化实例):对应的是客户端主动上报机制

临时实例每隔5秒级会主动上报一次自己的健康状况,发送的数据包叫做心跳包,发送心跳包的机制叫做心跳机制,如果心跳包的间隔时间超过了15秒,那么Nacos服务器端就会将此服务实例标记为非健康实例,如果心跳包超过了30s,那么Nacos服务端将会把此服务实例从服务列表删除

永久实例(持久化实例):对应的是服务端反向探测机制

服务端会定期检测,永久实例是否还存活这,如果不健康了,就会发出警告

演示:(这里只需要给provider服务 配置文件进行一个参数配置 ephemeral: false

注:以为2.0以后nacos实例下线的提示给去掉了,所以这里就是在演示实例下线后的提醒,如果有兴趣的友友,可以下载1.4.1版本的nacos去看看

spring:
  application:
    name: provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        ephemeral: false
server:
  port: 0

保护阀值:健康节点要求的最小百分比。用于在服务出现不健康实例时,阻止流量过度向少量健康实例集中,保护服务的整体可用性,保护阀值应设置为一个0到1之间浮点数,默认值为0。当集群中的健康实例占比小于设置的保护阀值时,就会触发阀值保护功能,触发保护阀值后,Nacos会将全部实例返回给调用者,虽然可能会损失一部分流量,但是保证集群中的剩余的健康实例能正常工作(临时实例是演示不了阀值的,永久实例才能体现保护阀值,永久实例下线后不会丢失,可以计算占比)

那永久实例怎么删除呢,有点麻烦,永久实例存在这个文件里,直接把protocol文件删除就行

 4、底层原理

Nacos执行流程图:

4.1、配置自动刷新原理

Nacos配置中心是支持配置项目自动刷新的,实现原理是通过长轮询+事件驱动方式来实现的

(1)客户端向Nacos服务器发送一个带有监听器(Listener)的请求,以获取某个特定配置的值

(2)Nacos服务器接收请求后,会检查该配置是否发生变化,如果没有变化,该请求将阻塞,知道超时或者配置发生变化

(3)当配置发生变化时,Nacos服务器会立即响应,并将新的配置值返回给客户端

(4)客户端接收到新的配置值后,可以根据需要更新自身的配置

以上叙述性其实就是长轮询

长轮询:客户端--(发送监听请求)->Nacos服务接收---(数据变化或者超时)-->数据返回客户端---->客户端收到消息,立马再发一个带有监听的请求(重复以上流程)

4.2、注册中心的底层实现

Nacos注册中心的底层实现主要依赖于两个关键组件:服务注册(Service Register)和服务发现(Service Discovery)

依仗这四个点:服务注册、心跳机制、服务发现、负载均衡

服务注册:当服务启动时,它会向Nacos服务器发送一个注册请求,包含自己的元数据信息。Nacos服务器接收到注册请求后,在内存中维护一个注册表,将服务实例的元数据保护起来,用户后续的服务发现

心跳机制:注册成功后,服务会定期发送心跳请求,以检测自己的健康状况和可以性,Nacos服务器就可以及时监控到服务实例的状态

服务发现:当服务消费者需要访问某个服务时,它会向Nacos服务器发送一个服务请求,包含所需服务的名称,Nacos服务器根服务名称查找注册表,返回服务的实例列表给消费者

负载均衡:Nacos提供了负载均衡的支持。消费者可以选择合适的负载均衡策略选择其中一个或者多个服务实例进行调用

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

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

相关文章

C语言每日一题(33)随机链表的复制

力扣138 随机链表的复制 题目描述 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都…

Java 11及更高版本的Oracle JDK版本

2021 年 9 月 14 日&#xff0c;Oracle 发布了可以长期支持的 JDK17 版本&#xff0c;那么从 JDK11 到 JDK17&#xff0c;到底带来了哪些特性呢&#xff1f;亚毫秒级的 ZGC 效果到底怎么样呢&#xff1f;值得我们升级吗&#xff1f;而且升级过程会遇到哪些问题呢&#xff1f;带…

PyTorch微调权威指南3:使用数据增强

如果你曾经参与过 PyTorch 模型的微调&#xff0c;可能会遇到 PyTorch 的内置变换函数&#xff0c;这使得数据增强变得轻而易举。 即使你之前没有使用过这些功能&#xff0c;也不必担心。 在本文中&#xff0c;我们将深入研究 PyTorch 变换换函数的世界。 我们将探索你可以使用…

Ubuntu20.04 安装微信 【deepin-wine方式极简安装】推荐,两行命令就解决了。

参考git仓库地址: GitHub - zq1997/deepin-wine: 【deepin源移植】Debian/Ubuntu上最快的QQ/微信安装方式【deepin源移植】Debian/Ubuntu上最快的QQ/微信安装方式. Contribute to zq1997/deepin-wine development by creating an account on GitHub.https://github.com/zq199…

指针与多维数组练习

例题一&#xff1a; 矩阵相乘 首先&#xff0c;如果你没学过线代的话&#xff0c;这边建议你去B站把宋浩的矩阵运算学了再来看题 如果有个矩阵A和一个矩阵B&#xff0c;当A的列数和B的行数相同时&#xff0c;生成一个新矩阵C&#xff0c;且C是通过矩阵乘法得来的 A[3][2]{3…

Schrodinger Shape Screen 工具使用方法

schrodinger的shape screen方法是一种基于ligand的筛选方法。需要提供一个参考分子&#xff0c;和需要筛选的分子库。shape screen可以根据原子类型、药效团对分子的形状相似度进行打分。 shape screen面板 shape screen面板如下&#xff1a; 1. 参考分子来源&#xff0c;可以…

【Linux】C文件系统详解(三)——如何理解缓冲区以及自主封装一个文件接口

文章目录 如何理解缓冲区现象概念:文件缓冲区为什么要有缓冲区缓冲区在哪里 自己封装一个简单的文件接口自主封装目标 代码关于缓冲区强制刷新内核 关于字符串格式化函数printf和scanf函数 如何理解缓冲区 以前写过一个进度条, 有一个输出缓冲区->这个缓冲区在哪里,为什么要…

十三、Linux文件目录指令

pwd 指令 基本语法&#xff1a;pwd &#xff08;功能描述&#xff1a;显示当前工作目录的绝对路径&#xff09; 应用实例&#xff1a;案例&#xff1a;显示当前工作目录的绝对路径 ls 指令 基本语法&#xff1a;ls 【选项】【目录或是文件】 常用选项 -a &#xff1a;显示当…

卡片排列-第15届蓝桥第二次STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第159讲。 第15届蓝桥杯第2次STEMA测评已于2023年10月29日落下帷幕&#xff0c;编程题一共有6题&#xff0c;分别如下&…

最强人工智能ChatGPT引领AIGC发展

从公众号转载&#xff0c;关注微信公众号掌握更多技术动态 --------------------------------------------------------------- ——AI不会淘汰所有人&#xff0c;但会淘汰不懂AI的人 一、最强人工智能GPT-4 Turbo 在前不久的OpenAI开发者大会&#xff0c;正值Chatgpt3.5发布一…

UDS 14229-1定义的请求的响应行为

UDS服务响应规则 重要提示服务器一般响应行为包含子功能的请求响应行为物理寻址请求功能寻址请求 没有子功能参数的服务响应行为物理寻址客户端请求功能寻址客户端请求 伪代码示例 重要提示 服务应当支持物理寻址方式请求&#xff0c;部分服务也支持功能寻址方式请求。在功能寻…

Java集合大总结——List的简单使用

List简单介绍 鉴于Java中数组用来存储数据的局限性&#xff0c;我们通常使用java.util.List替代数组List集合类中元素有序、且可重复&#xff0c;集合中的每个元素都有其对应的顺序索引。JDK API中List接口的实现类常用的有&#xff1a;ArrayList、LinkedList和Vector。 List…

五、Linux目录结构

1.基本介绍 1.Linux的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录"r/"&#xff0c;然后在此目录下再创建其他的目录。 2.深刻理解linux树状文件目录是非常重要的 3.记住一句经典的话&#xff1a;在Linux世界里&#xff0c;一切皆文件…

asp.net智能考试系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 asp.net 智能考试系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 系统运行视频 https://www.bilibili.com/video/BV1gz4y1A7Qp/ 二、功能介绍 本系统使用Microsoft Visual Studio 201…

4.6每日一题(多元函数的隐函数求导)

三元方程确定的二元函数类型的隐函数 方法一&#xff1a;两边对x求偏导&#xff0c;把y看成常数 注&#xff1a;z可以把x和y同时代入求出答案 方法二&#xff1a;带公式

Linux tc 使用

tc模拟延时丢包等网络故障依赖的内核驱动 /lib/modules/5.15.0-52-generic/kernel/net/sched/sch_netem.ko有些系统并不是默认就安装上该驱动的&#xff0c;如果没有安装该驱动&#xff0c;构造网络故障时会报错。 root:curtis# tc qdisc change dev enp4s0 root netem delay…

油猴脚本(JavaScript)-练手-简单的随机音乐播放器

浅浅的写个简单的随机音乐播放脚本(可移动)&#xff0c;注释很详细&#xff0c;直接上源码 效果&#xff1a; // UserScript // name 播放音乐脚本 // namespace 代码对我眨眼睛 // version 1.2 // description 在API上请求音乐链接并随机自动连续播放音乐&…

斯坦福机器学习 Lecture1

https://www.bilibili.com/video/BV1JE411w7Ub?p1&vd_source7a1a0bc74158c6993c7355c5490fc600 笔记如下 机器学习的定义&#xff1a;不需要明确编程就能让计算机去学习做某件事情 另一个定义 TODO:here

【网络】OSI模型 与 TCP/IP模型 对比

一、OSI模型 OSI模型包含7个层次&#xff0c;从下到上分别是&#xff1a; 1. 物理层&#xff08;Physical Layer&#xff09; - 功能&#xff1a;处理与电子设备物理接口相关的细节&#xff08;如电压、引脚布局、同步&#xff0c;等等&#xff09;。 - 协议&#xff1a;以…