Spring Cloud Eureka 服务注册与发现

Spring Cloud Eureka 服务注册与发现

  • 一、Eureka基础知识概述
    • 1.Eureka两个核心组件
    • 2.Eureka 服务注册与发现
  • 二、Eureka单机搭建
  • 三、Eureka集群搭建
  • 四、心跳续约
  • 五、Eureka自我保护机制


在这里插入图片描述

一、Eureka基础知识概述

1.Eureka两个核心组件

  • Eureka Server :服务注册中心,主要用于提供服务注册功能。
    当微服务启动时,会将自己的服务注册 到 Eureka Server。Eureka Server 维护了一个可用服务列表,存储了所有注册到 Eureka Server 的可用服务的信息,这些可用服务可以在 Eureka Server 的管理界面中直观看到
  • Eureka Client :客户端,通常指的是微服务系统中各个微服务,主要用于和 Eureka Server 进行交互。
    在微服务应用启动后,Eureka Client 会向 Eureka Server 发送心跳(默认周期为 30 秒)。若 Eureka Server 在多个心跳周期内没有接收到某个 Eureka Client 的心跳,Eureka Server 将它从可用服务列表中移除(默认 90 秒)

Eureka的心跳机制主要用于确保客户端(服务提供者)与服务器(服务注册中心)之间的连接活性。客户端启动后,会定期向服务器发送心跳数据,以告知服务器自己仍然处于活动状态


2.Eureka 服务注册与发现

在这里插入图片描述

  • 服务注册中心(Register Service): 它是一个 Eureka Server,用于提供服务注册和发现功能。
  • 服务提供者(Provider Service): 它是一个 Eureka Client,用于提供服务。它将自己提供的服务注册到服务注册中心,以供服务消费者发现。
  • 服务消费者(Consumer Service): 它是一个 Eureka Client,用于消费服务。它可以从服务注册中心获取服务列表,调用所需的服务。

Eureka 实现服务注册与发现的流程

  1. 搭建一个Eureka Server作为服务注册中心
  2. 服务提供者Eureka Client启动时,会把当前服务器的信息以服务名(spring.application.name)的方式注册到服务注册中心
  3. 服务消费者Eureka Client启动时,也会向服务注册中心注册
  4. 服务消费者还会获取一份可用路由服务列表,该列表中包含了所有注册到服务注册中心的服务信息(包括服务提供者和自身的信息)
  5. 在获得了可用服务列表后,服务消费者通过 HTTP 或消息中间件远程调用服务提供者提供的服务。
  6. 服务注册中心(Eureka Server)所扮演的角色十分重要,它是服务提供者和服务消费者之间的桥梁。服务提供者只有将自己的服务注册到服务注册中心才可能被服务消费者调用,而服务消费者也只有通过服务注册中心获取可用服务列表后,才能调用所需的服务。

二、Eureka单机搭建

1.构建父模块和三个子模块 分别为注册中心 eureka-service 仓储模块stock-service 订单模块 order-service
在这里插入图片描述


2.父模块pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>cloud-02-Eureka-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>cloud-eureka-service</module>
        <module>cloud-stock-service</module>
        <module>cloud-order-service</module>
    </modules>

    <!-- 统一管理jar包版本 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.18.22</lombok.version>
        <mysql.version>8.0.24</mysql.version>
        <druid.version>1.2.8</druid.version>
        <mybatis-plus.version>3.0.7.1</mybatis-plus.version>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
            <optional>true</optional>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-generator</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version  -->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3.对cloud-eureka-service注册中心操作
3.1 pom.xml文件

	<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

3.2 主启动类

// 添加数据库和 druid 却未配置
// 则添加 exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class}
// 则启动报错
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableEurekaServer//告诉服务器我是一个注册中心
public class EurekaServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication.class,args);
    }
}

3.3 application.yml

server:
  port: 8001
eureka:
  instance:
    hostname: 127.0.0.1  #eureka服务端的实例名字127.0.0.1 或 localhost
  client:
    #表识不向注册中心注册自己
    register-with-eureka: false
    #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
      #服务注册位置 http://127.0.0.1:8001/eureka/
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4.对仓储模块cloud-stock-service操作
4.1 pom.xml

	<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

4.2 主启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableEurekaClient//需要使用Eureka注册中心添加此注解
public class StockServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(StockServiceApplication.class,args);
    }
}

4.3 application.yml

server:
  port: 9001
spring:
  application:
    name: cloud-stock-service
eureka:
  client:
    # 向服务端注册
    register-with-eureka: true
    # 需要检索
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:8001/eureka

4.4 StockController

@RestController
@RequestMapping("/stock")
public class StockController {
    @GetMapping("/subStock")
    public String subStock(){
        System.out.println("库存减1");
        return "库存减1";
    }
}

5.对订单模块cloud-order-service操作
5.1 pom.xml文件

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

5.2 主启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableEurekaClient
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}

5.3 application.yml

server:
  port: 7001
spring:
  application:
    name: cloud-order-servce
eureka:
  client:
    # 向服务端注册
    register-with-eureka: true
    # 需要检索
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:8001/eureka/

5.4 OrderController

@RestController
@RequestMapping("/order")
public class OrderController {
	//这里特别提醒 `http://` 千万别忘加 本人因为这个错误找了很长时间 。。。。
	//CLOUD-STOCK-SERVICE 这里是eureka注册中心的名称
    private static final String HOST = "http://CLOUD-STOCK-SERVICE";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/addOrder")
    public String addOrder(){
        System.out.println("订单已完成");
        return restTemplate.getForObject(HOST + "/stock/subStock",String.class);
    }
}

5.5 RestTemplate配置类

@Configuration
public class ApplicationConfig {
    @Bean
    @LoadBalanced//负载均衡器
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

6.启动设置

我用的是idea 2021 ,多应用启动设置在如下位置
在这里插入图片描述
7.启动
7.1 先启动服务注册中心cloud-eureka-service 访问localhost:8001

在这里插入图片描述

7.2 在以端口号为9001和 9002 分别启动 cloud-stock-service
在yml文件 server.port更改 启动完成9001 更改端口号为9002 在启动一次 再次访问localhost:8001

在这里插入图片描述
7.3 在以端口号为7001和 7002 分别启动 cloud-order-service ,和 7.2更改方式一样 访问 localhost:8001

在这里插入图片描述
8. **测试 **
8.1 访问 localhost:7001/order/addOrder
在这里插入图片描述
8.2 观察控制台,当我们多少刷新访问 localhost:7001/order/addOrder 则会出现9001和9002交替处理请求(轮循),缓解服务器压力,选择服务规则和 @LoadBalanced 负载均衡器有关
在这里插入图片描述

试着访问localhost:7002,结果相同


三、Eureka集群搭建

在微服务架构中,一个系统往往由十几甚至几十个服务组成,若将这些服务全部注册到同一个 Eureka Server 中,就极有可能导致 Eureka Server 因不堪重负而崩溃,最终导致整个系统瘫痪。解决这个问题最直接的办法就是部署 Eureka Server 集群。

1.新建cloud-eureka-server-2和cloud-eureka-server-3
在这里插入图片描述
2.修改映射配置

打开 C:\Windows\System32\drivers\etc 目录下的hosts文件 修改映射配置添加进hosts文件
在这里插入图片描述
3.更改yml文件
3.1 cloud-eureka-service-2的yml文件

server:
  port: 8002
eureka:
  instance:
    hostname: eureka8002.com  #eureka服务端的实例名字
  client:
    #表识不向注册中心注册自己
    register-with-eureka: false
    #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://eureka8003.com:8003/eureka/

3.2 cloud-eureka-service-2的yml文件

server:
  port: 8003
eureka:
  instance:
    hostname: eureka8003.com  #eureka服务端的实例名字
  client:
    #表识不向注册中心注册自己
    register-with-eureka: false
    #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    fetch-registry: false
    service-url:
      #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
      defaultZone: http://eureka8002.com:8002/eureka/

3.3 cloud-order-service的yml文件

server:
  port: 7001
spring:
  application:
    name: cloud-order-servce
eureka:
  client:
    # 向服务端注册
    register-with-eureka: true
    # 需要检索
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:8002/eureka,http://localhost:8003/eureka

3.3 cloud-stock-service的yml文件

server:
  port: 9001
spring:
  application:
    name: cloud-stock-service
eureka:
  client:
    # 向服务端注册
    register-with-eureka: true
    # 需要检索
    fetchRegistry: true
    service-url:
      defaultZone: http://localhost:8002/eureka,http://localhost:8003/eureka


4.分别为cloud-eureka-service-2和cloud-eureka-service-3添加启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableEurekaServer//告诉服务器我是一个注册中心
public class EurekaServiceApplication2 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication2.class,args);
    }
}
-----------------------------------------------------------------------------------------------------------------

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableEurekaServer//告诉服务器我是一个注册中心
public class EurekaServiceApplication3 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication3.class,args);
    }
}

5.启动
5.1 启动cloud-eureka-service-2和cloud-eureka-service-3
5.1.1 访问localhost:8002
在这里插入图片描述
5.1.2 访问localhost:8003
在这里插入图片描述


5.2 启动cloud-order-service和 端口号为9001和9002的cloud-stock-service集群服

5.2.1 访问localhost:8002
在这里插入图片描述

5.2.2 访问localhost:8003
在这里插入图片描述


6.测试 多次访问localhost:7001 观察控制台
在这里插入图片描述


以上方式可以形成一组互相注册的 Eureka Server 集群,当服务提供者发送注册请求到 Eureka Server 时,Eureka Server 会将请求转发给集群中所有与之相连的 Eureka Server 上,以实现 Eureka Server 之间的服务同步。

在这里插入图片描述

通过服务同步,服务消费者可以在集群中的任意一台 Eureka Server 上获取服务提供者提供的服务。这样,即使集群中的某个服务注册中心发生故障,服务消费者仍然可以从集群中的其他 Eureka Server 中获取服务信息并调用,而不会导致系统的整体瘫痪,这就是 Eureka Server 集群的高可用性。


四、心跳续约

“心跳”指的是一段定时发送的自定义信息,让对方知道自己“存活”,以确保连接的有效性。大部分 CS 架构的应用程序都采用了心跳机制,服务端和客户端都可以发心跳。通常情况下是客户端向服务器端发送心跳包,服务端用于判断客户端是否在线

心跳续约是指服务实例(Eureka客户端)定期向Eureka服务器发送心跳包,以证明其仍然在线并愿意继续提供服务。Eureka服务器会根据这些心跳包来更新服务实例的活跃状态,并维护一个可用的服务实例列表。

在这里插入图片描述
功能介绍

Spring Cloud A 和 Spring Cloud B可以看作两个服务的提供者
Spring Cloud C 相当于 服务的消费者 定时(默认30秒)获取服务列表
registry服务注册列表 里面存储的是 各个注册服务的 名称 ip 端口号
readWriteCacheMap 会实时同步registry注册列表中的数据
readOnlyCacheMap 默认每30秒去同步一次readWriterCacheMap对象中的数据


详细流程

  • A和B 服务 向Eureka Service 服务注册列表中注册服务 将自己的服务名称 ip + 端口号注册到 registry服务注册列表。
  • A和B每隔30秒 (默认30秒) 发送 一次心跳任务告诉Eureka 我还活着, registry服务注册列表 同步数据到readWriteCacheMap
  • C 服务 通过readOnlyCacheMap 每30秒拉去一次注册表数据,这个数据不是同步的而是30秒(默认30秒)更新一次,这也是有时我们会在UI界面上看到服务注册成功,调用时却出现错误的原因。同理,服务下线也存在同样的问题,服务已经下线了,但是还是有客户端在调用已经下线的服务,这时就会出现连接拒绝的错误。
  • 我们在Eureka UI页面上看到的注册信息,实际上并没有走readOnlyCacheMap,而是直接通过registry服务注册列表获取,所以我们能够在Eureka UI页面实时的看到注册的新服务。
  • 服务续约默认是30秒 ,定时请理60秒清理一次超过90秒未续约的服务,也就是说在连续3次丢失心跳后会被Eureka Server的evict线程清理,最极端的情况,服务下线后,可能需要延迟180s之后,Eureka Server中的registry对象才会被更新。

综上分析,在非手动清除的情况下,缓存需要180秒才能感知下线的服务,这种情况在生产环境中非常严重。


上述问题中,我们可以更改默认值,来解决感知下线服务时间过长问题

Eureka注册中心

eureka:
  server:
    #清理无效服务间隔 (默认60秒)
    eviction-interval-timer-in-ms: 1000
    #同步readWrite到readOnly间隔(默认30秒)
    response-cache-update-interval-ms: 10000
    #Client直接从readWriteCacheMap更新服
    #use-read-only-response-cache: false

服务提供者

eureka:
  instance:
    # Eureka注册中心(服务端)在收到客户端心跳之后,
    #等待下一次心跳的超时时间,如果在这个时间内没有收到下次心跳,则移除该客户端。(默认90秒)
    lease-expiration-duration-in-seconds: 5
    # 客户端向注册中心发送心跳的时间间隔(默认30秒)
    lease-renewal-interval-in-seconds: 2

五、Eureka自我保护机制

Eureka的自我保护机制是一种应对网络异常的安全保护措施,宁可同时保留所有微服务(健康的服务和不健康的服务都会保留)也不盲目移除任何健康的服务。

当我们在本地调试基于 Eureka 的程序时,Eureka 服务注册中心很有可能会出现红色警告。
在这里插入图片描述

  • 实际上,这个警告是触发了 Eureka 的自我保护机制而出现的。默认情况下,如果 Eureka Server 在一段时间内没有接收到某个服务提供者的心跳,就会将这个服务提供者提供的服务从服务注册表中移除。 这样服务消费者就再也无法从服务注册中心中获取到这个服务了,更无法调用该服务。

  • 但在实际的分布式微服务系统中,健康的服务也有可能会由于网络故障(例如网络延迟、卡顿等原因)而无法与 Eureka Server正常通讯。若此时 Eureka Server因为没有接收心跳而误将健康的服务从服务列表中移除,这显然是不合理的。而 Eureka 的自我保护机制就是来解决此问题的。

  • 所谓 “Eureka 的自我保护机制”,其中心思想就是“好死不如赖活着”。如果 Eureka Server 在一段时间内没有接收到 Eureka Client 的心跳,那么 Eureka Server 就会开启自我保护模式,将所有的 Eureka Client 的注册信息保护起来,而不是直接从服务注册表中移除。一旦网络恢复,这些 Eureka Client 提供的服务还可以继续被服务消费者消费。


默认情况下,Eureka 的自我保护机制是开启的,如果想要关闭,则需要在配置文件中添加以下配置

eureka:
  server:
  	# false 关闭 Eureka 的自我保护机制,默认是开启
    enable-self-preservation: false 

需要注意的是:

Eureka 的自我保护机制也存在弊端。如果在 Eureka 自我保护机制触发期间,服务提供者提供的服务出现问题,那么服务消费者就很容易获取到已经不存在的服务进而出现调用失败的情况。此时,我们可以通过客户端的容错机制来解决此问题

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

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

相关文章

告别系统限制,一键关闭Windows Defender

作为一款专业级系统优化工具&#xff0c;Defender Remover 为追求完全系统控制权的高级用户提供了全方位的安全组件管理解决方案。这款强大的实用工具不仅完美支持从 Windows 8.x 到最新的 Windows 11 全系列操作系统&#xff0c;更提供了精细化的安全组件调整选项。 本工具最…

GitLab 如何降级?

本分分享 GitLab 降级的流程和注意事项。极狐GitLab 为 GitLab 的中文发行版&#xff0c;本文以私有化部署的极狐GitLab 为例来演示整个过程。 【极狐GitLab 推出 GitLab 老旧版本的专业升级服务【https://dl.gitlab.cn/cm33bsfv】&#xff0c;可以让 12.x、13.x、14.x、15.x …

微软日志丢失事件敲响安全警钟

NEWS | 事件回顾 最近&#xff0c;全球最大的软件公司之一——微软&#xff0c;遭遇了一场罕见的日志丢失危机。据报告&#xff0c;从9月2日至9月19日&#xff0c;持续长达两周的时间里&#xff0c;微软的多项核心云服务&#xff0c;包括身份验证平台Microsoft Entra、安全信息…

leetcode268 丢失的数字

class Solution { public:int missingNumber(vector<int>& nums) {sort(nums.begin(),nums.end());int i0;for(;i<nums.size();i){if(i!nums[i]) break;}return i;} }; sort(nums.begin(), nums.end()); 对数组进行排序。虽然排序是一个可行的方法&#xff0c;但是…

HBuilder(uniapp) 配置android模拟器

HBuilder&#xff08;uniapp&#xff09; 配置android模拟器 选择完成之后&#xff0c;点击ok&#xff0c;再次点击Configure—》AVD Manager

Redis高可用-主从复制

这里写目录标题 Redis主从复制主从复制过程环境搭建从节点配置常见问题主从模式缺点 Redis主从复制 虽然 Redis 可以实现单机的数据持久化&#xff0c;但无论是 RDB 也好或者 AOF 也好&#xff0c;都解决不了单点宕机问题&#xff0c;即一旦 redis 服务器本身出现系统故障、硬…

Vue3 -- 项目配置之husky【企业级项目配置保姆级教程4】

引言&#xff1a; eslint&#xff1a;代码规范校验prettier&#xff1a;代码格式化stylelint&#xff1a;CSS代码校验 上述三篇文章集成配置完成代码校验工具&#xff0c;当时需要每次手动的去执行命令才会格式化我们的代码。。如果有人没有格式化就提交了远程仓库&#xff0…

PaddlePaddle 开源产业级文档印章识别PaddleX-Pipeline “seal_recognition”模型 开箱即用篇(一)

AI时代到来&#xff0c;各行各业都在追求细分领域垂直类深度学习模型&#xff0c;今天给大家介绍一个PaddlePaddle旗下&#xff0c;基于PaddleX Pipeline 来完成印章识别的模型“seal_recognition”。 官方地址&#xff1a;https://github.com/PaddlePaddle/PaddleX/blob/relea…

06.VSCODE:备战大项目,CMake专项配置

娇小灵活的简捷配置不过是年轻人谈情说爱的玩具&#xff0c;帝国大厦的构建&#xff0c;终归要交给CMake去母仪天下。一个没有使用 CMake 的 C 项目&#xff0c;就像未来世界里的一台相声表演&#xff0c;有了德纲却无谦&#xff0c;观众笑着遗憾。—— 语出《双城记》作者&…

新高考志愿录取方式变革,如何应对挑战?答案在这里

在教育改革的浪潮中&#xff0c;新高考的实施带来了重大变革&#xff0c;其中志愿录取方式的变化尤为关键。它不仅关系着每一位考生的未来发展&#xff0c;更是对整个教育体系产生着深远影响。今天&#xff0c;我们就来深入探讨新高考的两大志愿录取方式&#xff0c;分析其特点…

Unity网络通信(part7.分包和黏包)

目录 前言 概念 解决方案 具体代码 总结 分包黏包概念 分包 黏包 解决方案概述 前言 在探讨Unity网络通信的深入内容时&#xff0c;分包和黏包问题无疑是其中的关键环节。以下是对Unity网络通信中分包和黏包问题前言部分的详细解读。 概念 在网络通信中&#xff0c;…

64位PE壳编写指南

文章目录 前记x64壳后记reference 文章首发于微信公众号《渗透测试安全攻防》 前记 开源的关于PE压缩和加密壳几乎都是32位&#xff0c;于是学习写一个64位的壳供参考&#xff0c;其原理差别不大学写PE壳是熟悉PE结构很好的方式项目已开源&#xff0c;求个stars嘻嘻嘻 https:…

3D意识(3D Awareness)浅析

一、简介 3D意识&#xff08;3D Awareness&#xff09;主要是指视觉基础模型&#xff08;visual foundation models&#xff09;对于3D结构的意识或感知能力&#xff0c;即这些模型在处理2D图像时是否能够理解和表示出图像中物体或场景的3D结构&#xff0c;其具体体现在编码场景…

Web安全之SQL注入---基础

文章目录 SQL注入简介SQL注入基础SQL注入分类SQL注入流程 SQL注入简介 什么是SQL注入&#xff1f; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理…

黄仁勋对话孙正义:日本的AI新饼、Arm的AI野心与英伟达的东亚新机会

2020 年的软银世界大会上&#xff0c;孙正义与黄仁勋围绕「What’s Next for AI」展开了一次围炉对谈。黄仁勋穿着标志性的皮夹克坐在火堆旁&#xff0c;畅谈了将 Arm 纳入麾下的重要价值&#xff0c;孙正义也毫不吝啬赞美之词&#xff0c;称老黄在未来 10 年会达到史蒂夫 乔布…

【案例】Excel使用宏来批量插入图片

一、场景介绍 我有一个excel文件&#xff0c;需要通过一列的文件名称&#xff0c;按照规则给批量上传图片附件。 原始文件&#xff1a; 成功后文件&#xff1a; 二、实现方法 1. 使用【wps】工具打开Excel文件&#xff0c;将其保存为启用宏的文件。 2.找到编辑宏的【VB编辑器…

Kubernetes-ArgoCD篇-01-简介

1、什么是Argo CD Argo CD 是针对 Kubernetes 的声明式 GitOps 持续交付工具。 Argo CD官方文档地址&#xff1a;https://argo-cd.readthedocs.io Argo CD源码地址&#xff1a;https://github.com/argoproj/argo-cd 1.1 关于Argo Argo是一个开源的项目&#xff0c;主要是扩…

odoo17 前端 在头像下拉 dropdown 自定义菜单

odoo17 前端 在头像下拉 dropdown 自定义菜单 其实很简单, 我们先找到原来已经创建好的, 找到代码位置 使用 我的资料 为例 odoo-17.0\addons\hr\static\src\user_menu\my_profile.js /** odoo-module **/import { _t } from "web/core/l10n/translation"; import …

时序预测 | Python基于CNN-transformer时间序列预测

时序预测 | Python基于CNN-transformer时间序列预测 目录 时序预测 | Python基于CNN-transformer时间序列预测预测效果基本介绍参考资料 预测效果 基本介绍 时序预测 | Python基于CNN-transformer时间序列预测 Cnn-transformer-自适应稀疏自注意力ASSA-对比归一化contranorm预…

(干货)Jenkins使用kubernetes插件连接k8s的认证方式

#Kubernetes插件简介 Kubernetes 插件的目的是能够使用 Kubernetes 配合&#xff0c;实现动态配置 Jenkins 代理&#xff08;使用 Kubernetes 调度机制来优化负载&#xff09;&#xff0c;在执行 Jenkins Job 构建时&#xff0c;Jenkins Master 会在 kubernetes 中创建一个 Sla…