3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)
3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)
文章目录
- 3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)
- 前言
- 1. Spring Cloud Eureka 的概述
- 1.1 服务治理概述
- 1.2 服务注册与发现
- 2. 实践:创建单机 Eureka Server 注册中心
- 2.1 需求说明 + 图解
- 2.3 具体实现步骤
- 2.3.1 创建相关的 Moduel 以及 完成配置
- 2.3.2 配置 member-service-consumer-80 作为 EurekaClient 可 以 拉 取/获取 e-commerce-eureka-server-9001 提供的服务信息
- 2.3.3 架构示意图
- 2.3.4 将 member-service-provider-10000 作为 EurekaClient 注册到 e-commerce-eureka-server-9001 成为服务提供者
- 2.3.5 架构示意图
- 3. Service Consumer 、Service Provider 、EurekaServer 的维护机制
- 4. Eureka 自我保护模式
- 4.1 自我保护模式理论
- 4.2 禁用自我保护模式(生产环境中, 一般不禁用)
- 5. 搭建 EurekaServer 集群- 实现负载均衡故障容错
- 5.1 为什么需要集群 Eureka Server
- 5.2 需求分析/图解
- 5.3 搭建 Eureka Server 集群
- 6. 补充:定义本地的域名机制
- 5.4 搭建会员中心服务提供方-集群
- 5.5 配置服务消费端 member-service-consumer-80 使用会员中心服务集群
- 5.6 获取 Eureka Server 服务注册信息 - DiscoveryClient
- 5.5.1 具体操作步骤:
- 5.5.1.1 注意事项和细节说明
- 7. Eureka 后续说明
- 8. 总结:
- 9. 最后:
前言
- 对应上一篇学习内容:🌟🌟🌟2. Spring Cloud 微服务基础环境搭建_搭建cloud微服务-CSDN博客
- 对应下一篇学习内容:🌟🌟🌟 4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明-CSDN博客
1. Spring Cloud Eureka 的概述
从上个学习内容上我们可以知道 补充, 当中的 、Spring Cloud 组件选型- 图
从上图可以看出,目前主流的服务注册/发现的组件是 Nacos,但是Eureka 作为一个老牌经典的服务
注册/发现技术还是有必要回顾一下:
原因:
- 一些早期的分布式 微服务项目使用的是 Eureka ,大家工作中,完全有可能遇到这种情况。
- 后期的服务注册/发现组件/技术,都参考了 Eureka 的设计和理念,学习了 Eureka 后,我们上手
Nacos 容易很多,而且理解的更深刻。
分析上述我们上一篇内容补充 当中项目架构问题分析
当前项目问题分析:
- 在企业项目中,服务消费访问请求会存在高并发
- 如果只有一个会议中心-提供服务,可用性就比较差了
- 所以,会议中心提供服务往往是一个集群,也就是说会有多个会议中心-提供服务微服务模块
- 那么这个时候,就存在一个问题就是服务消费方,怎么去发现可以使用的服务(哪些服务又不可以使用)
- 当服务消费方,发现了可以使用的服务后(可能是多个,又存在一个问题就是到底调用 A服务,
还是调用B服务,这就引出了服务注册和负载均衡的问题) - Eureka 就可以解决上述问题
引入 Eureka 项目架构,一图胜千言
上图 Eureka 项目架构图解析:
- 会员中心——> 提供服务的,在项目中,会做成集群 ,提供高可用
- Eureka Server 有必要的话,也可以做成集群 。
- Eureka 包含两个组件: Eureka Server 和 Eureka Client
- Eureka Server 提供注册服务,各个微服务节点童工配置启动后,会在 EurekaServer 中进行注册,
这样Eureka Server 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。 - Eureka Client 通过注册中心进行访问,是一个Java客户端,用于简化 Eureka Server 的交互,
客户端同时也具备一个内置的,使用轮询(round-robin) 负载算法的负载均衡器。在应用启动后,
将会向 Eureka Server 发送心跳(默认周期为 30秒)。如果 Eureka Server 在多个心跳周期
内没有接收到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认90秒)
1.1 服务治理概述
Eureka 实现服务治理
在传统的 rpc 远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理困难,所以 需要治理服务之间依赖关系
服务治理实现服务调用、负载均衡、容错等,实现服务发现与注册。
二说分布式开发: https://jingyan.baidu.com/article/46650658def479f549e5f83e.html
1.2 服务注册与发现
-
Eureka 采用了CS[client-server-java] 基础我们讲过一个多人聊天项目。的设计架构,
Eureka Server 作为服务注册的服务器,它是服务注册中心 -
系统中的其它微服务,使用Eureka 的客户端连接到 Eureka Server 并维持心跳连接,
通过 Eureka Server 来监控系统中各个微服务是否正常运行 -
在服务注册与发现中,有一个注册中心,当服务启动的时候,会把当前自己服务器的信息,比如服务地址通讯地址等以别名方式注册到注册中心上。
-
服务消费者或者服务提供者,以服务别名的方式去注册中心上获取到实际的服务提供
者通讯地址,然后,通过 RPC 调用服务
2. 实践:创建单机 Eureka Server 注册中心
2.1 需求说明 + 图解
2.3 具体实现步骤
2.3.1 创建相关的 Moduel 以及 完成配置
- 创建 e-commerce-eureka-server-9001 微服务模块[作为注册中心]
父工程的 pom.xml-会做相应变化,管理 e-commerce-eureka-server-9001 微服务子模块
- 修改 e-commerce-eureka-server-9001 的 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"><parent><artifactId>e-commerce-center</artifactId><groupId>com.rainbowsea</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>e-commerce-eureka-server-9001</artifactId><dependencies><!-- 引入web-starter 说明:这里我们使用版本仲裁(从父项目继承了版本)--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--1. starter-actuator 是sprng boot 程序的监控系统,可以实现健康检查,info 信息等2. 访问http://localhost:10000/actuator 可以看到相关链接,还可以做相关配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 引入 eureka-server 场景启动器 starter: 使用版本仲裁注意:不要搞错了,有一个 starter 的--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- lombok 引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><!-- 不进行转递依赖--><optional>true</optional></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><!-- 引入 test-starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 引入我们自己对 bean 封装成 api 的模块内容--><dependency><groupId>com.rainbowsea</groupId><artifactId>e_commerce_center-common-api</artifactId><version>${project.version}</version></dependency></dependencies></project>
- 创建 resources/application.yml
server:port: 9001
# 配置 eureka-server
eureka:instance:hostname: localhost # 服务实例名或者别名client:# 配置不向注册中心注册自己,默认是 trueregister-with-eureka: false# 表示自己就是注册中心,作用就是维护注册服务实例,不需要去检索服务,默认是 truefetch-registry: falseservice-url:#设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址# defaultZone: http://localhost:9001/eureka/ ,也可以使用别名,在同一个文件当中可以引用defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
特别说明:注意:这里从架构图上可以知道的是,这里的这个
e-commerce-eureka-server-9001
充当为Eureka Server
服务角色 ,所以自然,我们需要将其配置为 服务角色。
- 创建主启动类 com/rainbwosea/springcloud/EurekaApplication.java
package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer // @EnableEurekaServer 表示该项目/该模块/该程序作为 Eureka Server 角色进行运行
@SpringBootApplication
public class EurekaApplication9001 {public static void main(String[] args) {SpringApplication.run(EurekaApplication9001.class, args);}
}
- 完成测试:
补充说明: Spring Eureka 完整的可视化页面展示
2.3.2 配置 member-service-consumer-80 作为 EurekaClient 可 以 拉 取/获取 e-commerce-eureka-server-9001 提供的服务信息
2.3.3 架构示意图
配置 member-serivce-consumer-10000 作为 EurekaClient 注册发现到 commerce-eureka-server-9001 服务当中,我们需要在 resource目录下的 application.yaml
文件当进行一个配置。如下图所示:
- 配置 member-serivce-consumer-80 作为 EurekaClient 注册发现到 commerce-eureka-server-9001 服务当中,我们需要在 resource目录下的
application.yaml
文件当进行一个配置。如下图所示:
server:port: 80 # 浏览器默认就是 80 端口spring:application:name: member-service-consumer-80 # 该项目/模块名称eureka:client:register-with-eureka: true # 表示将自己注册到 Eureka-Server 当中fetch-registry: true # 表示将信息发送到 Eureka-Server 当中service-url:# 表示将自己注册到那个 eureka-serverdefaultZone: http://localhost:9001/eureka
- 同时我们也需要将该
member-service-consumer-80
项目,配置指明为是 Eureka Client 角色,在该项目的场景启动器上添加 注解即可 。
package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;// 如果错误: 加入排除 DataSourceAutoConfiguration 自动配置
//@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient //表示将项目/模块/程序 标注作为 Eureka Client
@SpringBootApplication
public class MemberConsumerApplication80 {public static void main(String[] args) {SpringApplication.run(MemberConsumerApplication80.class, args);}
}
运行测试:
注意:测试的时候,我们尽量先将 EukekatServer (也就是我们这里的
e-commerce-eureka-server-9001
) 注册中心启动,然后再将 Eukekat Client(也就是我们这里的member-service-consumer-80
) 启动。然后,打开浏览器输入:http://localhost:9001/ 查看结果。
2.3.4 将 member-service-provider-10000 作为 EurekaClient 注册到 e-commerce-eureka-server-9001 成为服务提供者
上述操作我们是已经将 定义为了一个 Eureka Server 服务器,那么我们就需要将 服务提供者
注册到我们的 Eureka Server 当中。注册到 Eureka Server 当中,换句话说:就是将我们 Eureka Client 告诉 Eureka Server 我还没有宕机,还活着,我还可以继续提供服务下去。
2.3.5 架构示意图
配置 member-service-provider-10000 作为 EurekaClient 注册发现到 commerce-eureka-server-9001 服务当中,我们需要在 resource目录下的 application.yaml
文件当进行一个配置。如下图所示:
server:port: 10000
spring:application:name: member-service-provider-10000 # 配置应用的名称datasource:type: com.alibaba.druid.pool.DruidDataSource # 配置 alibaba 的数据库连接池password: MySQL123username: rooturl: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8
mybatis:mapper-locations: classpath:mapper/*.xml # 指定 mapper.xml 文件位置 classpath 表示 resources 目录下type-aliases-package: com.rainbowsea.springcloud.entity # 实例 bean 类所在的包,这样可以通过类名的方式# 配置 eureka-client
eureka:client:register-with-eureka: true # 表示将自己注册到 Eureka-Server# 表示从 Eureka-Server 抓取注册信息# 如果是单节点,是可以配置的,但是如果是一个集群,则必须配置true# 才能配合 Ribbon 使用负载均衡fetch-registry: trueservice-url:# 表示将自己注册到那个 eureka-serverdefaultZone: http://localhost:9001/eureka
同时我们也需要将该 member-service-provider-10000
项目,配置指明为是 Eureka Client 角色,在该项目的场景启动器上添加 注解即可 。
package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient 表示将该程序/项目/模块 标识为 eureka-client 端
@EnableEurekaClient
@SpringBootApplication
public class MemberApplication10000 {public static void main(String[] args) {SpringApplication.run(MemberApplication10000.class, args);}
}
测试:
- 启动 e-commerce-eureka-server-9001
- 启动 member-service-provider-10000
- 浏览器: http://localhost:9001
3. Service Consumer 、Service Provider 、EurekaServer 的维护机制
示图:
4. Eureka 自我保护模式
4.1 自我保护模式理论
在默认情况下, Eureka 启动了自我保护模式(如图红字, 需要刷新页面, 可以看到)
-
默认情况下EurekaClient 定时向 EurekaServer 端发送 心跳包
-
如果 Eureka 在 server 端一定时间内(默认90秒) 没有收到 EurekaClient 发送心跳包,便会
直接从服务注册表中剔除该服务 -
如果Eureka 开启了**“自我保护机制/模式”** ,那么在短时间(90秒中)内丢失了大量的服务实例心跳。
这时候Eureka Server 会开启自我保护机制,不会剔除该服务(该现象可能出现在如果网络不通或者
阻塞)因为客户端还能正常发送心跳,只是网络延迟问题,而保护机制是为了解决此问题而产生的。 -
自我保护是属于CAP里面的AP分支 ,保证高可用和分区容错性
-
自我保护模式是一种应对网络异常的安全保护措施,它的架构哲学是宁可同时保留所有微服务(健康
的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。使用自我保护模式,
可以让 Eureka 集群更加的健壮,稳定,参考:
https://blog.csdn.net/wangliangluang/article/details/120626014
- 一致性: 所有节点在同一时间的数据完全一致
- 可用性:服务在正常时间内一直可用
- 分区容错性:系统在遇到节点或者网络分区故障的时候,仍然能够对外满足可用性或一致性的服务
测试:
启动member-service-provider-10000 和 e-commerce-eureka-server-9001
让member-service-provider-10000 正确的注册
然后关闭member-service-provider-10000
观察注册的 member-service-provider-10000 服务是否还在.
4.2 禁用自我保护模式(生产环境中, 一般不禁用)
演示禁用自我保护模式:
修改 e-commerce-eureka-server-9001 的 application.yml
修改 member-service-provider-10000 的 application.yml
启 动 e-commerce-eureka-server-9001 和 member-service-provider-10000
在 member-service-provider-10000 注册成功后,再关闭, 看看 eureka server 服务注册信息的变化
提醒:测试完毕后,别忘了恢复原状,启用自我保护
5. 搭建 EurekaServer 集群- 实现负载均衡故障容错
5.1 为什么需要集群 Eureka Server
示意图(上图)
为什么需要集群 Eureka Server
说明:
- 微服务 RPC 远程服务调用最核心的是实习高可用
- 如果注册中心只有1个,它出故障,会导致整个服务环境不可用
- 解决办法: 搭建 Eureka 注册中心集群,实习 负载均衡 + 故障容错
5.2 需求分析/图解
5.3 搭建 Eureka Server 集群
1. 创建 e-commerce-eureka-server-9002 微服务模块[作为注册中心]
- 修改 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"><parent><artifactId>e-commerce-center</artifactId><groupId>com.rainbowsea</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>e-commerce-eureka-server-9002</artifactId><dependencies><!-- 引入web-starter 说明:这里我们使用版本仲裁(从父项目继承了版本)--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--1. starter-actuator 是spring boot 程序的监控系统,可以实现健康检查,info 信息等2. 访问http://localhost:9002/actuator 可以看到相关链接,还可以做相关配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 引入 eureka-server 场景启动器 starter: 使用版本仲裁注意:不要搞错了,有一个 starter 的--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- lombok 引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><!-- 不进行转递依赖--><optional>true</optional></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><!-- 引入 test-starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 引入我们自己对 bean 封装成 api 的模块内容--><dependency><groupId>com.rainbowsea</groupId><artifactId>e_commerce_center-common-api</artifactId><version>${project.version}</version></dependency></dependencies></project>
- 创建 resources/application.yml
server:port: 9002
# 配置 eureka server
eureka:instance:hostname: eureka9002.com # 服务实例名/或者叫别名client:# 配置不向注册中心注册自己(因为自己就是注册中心),默认是 trueregister-with-eureka: falsefetch-registry: falseservice-url:#设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址# defaultZone: http://localhost:9001/eureka/ ,也可以使用别名,在同一个文件当中可以引用# 相互注册,这里应用注册到 eureka server 9001 上defaultZone: http://eureka9001.com:9001/eureka/
- 创建主启动类 EurekaApplication9002.java
package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer //该注解标注,当前的项目/模块/程序作为 Eureka Server 角色
public class EurekaApplication9002 {public static void main(String[] args) {SpringApplication.run(EurekaApplication9002.class, args);}
}
- 修改 e-commerce-eureka-server-9001 微服务模块,修改其中的内容 resources/application.yml
让: e-commerce-eureka-server-9001 微服务模块 与 e-commerce-eureka-server-9002 相互注册 。
server:port: 9001
# 配置 eureka-server
eureka:instance:hostname: eureka9001.com # 服务实例名或者别名client:# 配置不向注册中心注册自己,默认是 trueregister-with-eureka: false# 表示自己就是注册中心,作用就是维护注册服务实例,不需要去检索服务,默认是 truefetch-registry: falseservice-url:#设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址# defaultZone: http://localhost:9001/eureka/ ,也可以使用别名,在同一个文件当中可以引用# 相互注册,这里应用注册到 eureka server 9002 上defaultZone: http://eureka9002.com:9002/eureka/
6. 补充:定义本地的域名机制
如下图所示:
无论是 9001 还是 9002 ,我们都定义了别名,如果想要,让定义的别名生效的话,我们需要在本地,设置域名映射。
设置本地的域名映射,需要找到本地电脑当中的 host
文件,在该 host
文件当中编写添加相应的域名映射。
host文件路径: C:\Windows\System32\drivers\etc\host
# 配置 eureka 主机 和 ip 的映射 127.0.0.1 eureka9001.com 127.0.0.1 eureka9002.com
# Copyright (c) 1993-2009 Microsoft Corp. # # This is a sample HOSTS file used by Microsoft TCP/IP for Windows. # # This file contains the mappings of IP addresses to host names. Each # entry should be kept on an individual line. The IP address should # be placed in the first column followed by the corresponding host name. # The IP address and the host name should be separated by at least one # space. # # Additionally, comments (such as these) may be inserted on individual # lines or following the machine name denoted by a '#' symbol. # # For example: # # 102.54.94.97 rhino.acme.com # source server # 38.25.63.10 x.acme.com # x client host# localhost name resolution is handled within DNS itself. # 127.0.0.1 localhost # ::1 localhost127.0.0.1 account.wondershare.com # 配置 eureka 主机 和 ip 的映射 127.0.0.1 eureka9001.com 127.0.0.1 eureka9002.com
特别提醒:如果发现文件修改后无法保存,那么可以将文件复制到桌面上,然后,修改复制到桌面上的那份复制过来的 host 文件,修改保存完后,再拷贝回原来路径位置,进行一个替换。
运行测试:
- 启动 e-commerce-eureka-server-9001
- 启动 e-commerce-eureka-server-9002
- 浏览器: http://eureka9001.com:9001 浏览器: http://eureka9002.com:9002
将 member-service-consumer-80 注册到 EurekaServer 集群(目前 2 台)
修改 member-service-consumer-80 模块当中的:resources/application.yml
- 启动 e-commerce-eureka-server-9001 和 e-commerce-eureka-server-9002
- 启动 member-service-consumer-80
- 观察 member-service-consumer-80 是否注册到 Eureka 集群(目前 2 台)
浏览器输入: http://eureka9001.com:9001/
5.4 搭建会员中心服务提供方-集群
创建 member-service-provider-10002
参考 member-service-provider-10000 来创建 member-service-provider-10002 即可
创 建 好 后 , 使 用 member-service-provider-10000 的 源 码 和 配 置 替 换 member-service-provider-10002 生成的代码
(不要到磁盘整体拷贝,会出现关联到 member-service-provider-10000 的问题,很麻烦, 可以创建好新项目的包,然后再拷贝对应包下的文件,就不会出问题)
提醒,拷贝时不要忘记拷贝 resources/mapper/MemberMapper.xml
这些 xxx.xml
文 件。
创建 resources/application.yml
创建好 application.yml
从 member-service-provider-10000 拷贝 application.yml 的内容
修改端口号即可
server:port: 10002
spring:application:name: member-service-provider # 配置应用的名称datasource:type: com.alibaba.druid.pool.DruidDataSource # 配置 alibaba 的数据库连接池password: MySQL123username: rooturl: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8
mybatis:mapper-locations: classpath:mapper/*.xml # 指定 mapper.xml 文件位置 classpath 表示 resources 目录下type-aliases-package: com.rainbowsea.springcloud.entity # 实例 bean 类所在的包,这样可以通过类名的方式# 配置 eureka-client
eureka:client:register-with-eureka: true # 示将自己注册到 Eureka-Server,因为自己是作为 eureka-client客户端的角色的# 表示从 Eureka-Server 抓取注册信息# 如果是单节点,是可以配置的,但是如果是一个集群,则必须配置true# 才能配合 Ribbon 使用负载均衡fetch-registry: trueservice-url:# 表示将自己注册到那个 eureka-server# 将本微服务注册到多个 eureka - server 当中,使用逗号间隔即可defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/
创建主启动类名(场景启动器)
启动 eureka server 集群(目前 2 台)
启动 member-service-provider-10000
启动 member-service-provider-10002
浏览器输入: http://eureka9001.com:9001/
浏览器输入: http://eureka9002.com:9002/
5.5 配置服务消费端 member-service-consumer-80 使用会员中心服务集群
因为 member-service-provider-10000 和 member-service-provider-10002 作为一个集 群提供服务, 因此需要将 spring.application.name 进行统一,方便用于负载均衡
这样消费方通过统一的别名进行负载均衡调用。
示意图:
修改 member-service-consumer-80 模块下的,MemberConsumerController.java
package com.rainbowsea.springcloud.controller;import com.rainbowsea.springcloud.entity.Member;
import com.rainbowsea.springcloud.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.util.List;@RestController
@Slf4j
public class MemberConsumerController {// 定义 MEMBER_SERVICE_PROVIDER_URL 这是一个基础 url地址// 使用 shift+ctrl+u 进行字母大小写的切换//private static final String MEMBER_SERVICE_PROVIDER_URL = "http://localhost:10000";// 负载均衡统一别名,修改为提供服务模块的注册别名: 不需要配置指明端口号,因为是一个负载集群了。不是特指某个了Service 服务来处理了/*server:port: 10000
spring:application:name: member-service-provider # 配置应用的名称*//*说明:1. MEMBER-SERVICE-PROVIDER 就是服务提供方【集群】,注册到Eureka Server 的名称2. 也就是服务提供方【集群】对外暴露的名称为 MEMBER-SERVICE-PROVIDER3. MEMBER-SERVICE-PROVIDER 目前有两个 Availability Zones UP (2) - localhost:member-service-provider:10000 , localhost:member-service-provider:10002还有一个 member-service-provider:10002需要增加一个注解 @LoadBalanced 赋予 RestTemplate 才能有负载均衡的能力,也就是会根据你的负载均衡来选择某个服务去访问,默认是“轮询算法”,当然我们也可以自己配置负载均衡算法4. 在对应的 RestTemplate 配置类上的,@Bean注解下面加上 @LoadBalanced 注解。*/private static final String MEMBER_SERVICE_PROVIDER_URL = "http://MEMBER-SERVICE-PROVIDER";// 装配 RestTemplate bean/对象@Resourceprivate RestTemplate restTemplate;@PostMapping("/member/consumer/save")public Result<Member> save(Member member) {// 1.第1个参数: 就是请求的完整的url:MEMBER_SERVICE_PROVIDER_URL + "/member/save" => http://localhost:10000/member/save// 表示你向将该请求,发送给那个微服务处理,注意无论是返回值,还是参数, @PostMapping() 请求方式都要一一对应上对应处理的微服务上的内容//2. 第2个参数: member : 就是通过 restTemplate 发出的 post 请求携带数据或者对象//3. 第3个参数: Result.class ,微服务当中的对应处理的方法的,返回值,也就是返回对象类型// 注意:坑点// 这里通过 restTemplate 调用服务模块的接口,就是一个远程调用//log.info("member-service-consumer-80 save member={}", member);return restTemplate.postForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/save", member, Result.class);}/*1.与@PostMapping("/member/save")public Result save(Member member) {int affected = memberService.save(member);if (affected > 0) { // 说明添加成功return Result.success("添加会员成功", affected);} else {return Result.error("401", "添加会员失败");}}*//*** 方法/接口,调用服务接口,返回 member 对象信息** @param id* @return*/@GetMapping("/member/consumer/get/{id}")public Result<Member> getMemberById(@PathVariable("id") Long id) {// 这里就用两个参数// 第一个参数,因为是查询,所以这里我们直接字符串拼接上去// 这里通过return restTemplate.getForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/get/" + id, Result.class);}/*保持一致:* 提交方式* 返回类型* 参数* 路径映射要对应上@GetMapping("/member/get/{id}")public Result getMemberById(@PathVariable("id") Long id) {Member member = memberService.queryMemberById(id);// 使用 Result 把查询到的结果返回if (member != null) {return Result.success("查询会员成功", member);} else {return Result.error("402", "ID" + id + "不存在");}}*/// 注意:有两个是这个包下的 : org.springframework.cloud.client.discovery.DiscoveryClient@Resource // 装配到 Spring ioc 容器当中private DiscoveryClient discoveryClient;// 注意:想要获取到服务端信息,还需要在SpringBoot 启动场景上加上:@EnableDiscoveryClient // 启用服务发现 注解才行@GetMapping("/member/consumer/discovery")public Object discovery(){List<String> services = discoveryClient.getServices();// 遍历 servicesfor (String service : services) {log.info("服务名==={}",service);// 再根据服务名获取更加详细的信息List<ServiceInstance> instances = discoveryClient.getInstances(service);for (ServiceInstance instance : instances) {log.info("id={},host={},uri={}",instance.getServiceId(),instance.getHost(),instance.getUri());}}return this.discoveryClient;}
}
为了看到测试效果,修改服务提供方
在两个服务提供方的查询和添加返回结果处增加自己服务名称信息,如图, 其它位置可参考加入
/*** 这里我们使用 url占位符 + @PathVariable** @param id* @return*/@GetMapping("/member/get/{id}")public Result getMemberById(@PathVariable("id") Long id) {Member member = memberService.queryMemberById(id);// 使用 Result 把查询到的结果返回if (member != null) {return Result.success("查询会员成功 member-service-provider-10000 ", member);} else {return Result.error("402", "ID" + id + "不存在 member-service-provider-10000 ");}}
/*** 这里我们使用 url占位符 + @PathVariable** @param id* @return*/@GetMapping("/member/get/{id}")public Result getMemberById(@PathVariable("id") Long id) {Member member = memberService.queryMemberById(id);// 使用 Result 把查询到的结果返回if (member != null) {return Result.success("查询会员成功 member-service-provider-10002 ", member);} else {return Result.error("402", "ID" + id + "不存在 member-service-provider-10002 ");}}
特别说明: 我们想要能够实现 member 交替访问的话,需要在 RestTemplate 配置类上@Bean方法上加上该 @LoadBalanced注解的)才行。
底层是 Ribbon 支持算法 交替访问 member服务说明:
- 注解@LoadBalanced(在RestTemplate 配置类的@Bean方法上加上该 @LoadBalanced注解的)
底层是 Ribbon 支持算法
- Ribbon 和 Eureka 整合后 consumer 直接调用服务而不用再关心地址和端口号,且该服务还有负载功能
运行测试:
启动 member-service-consumer-80
浏览器访问:http://eureka9001.com:9001/
浏览器访问: http://localhost/member/consumer/get/1 这个是通过客户端 Eureka Client 发送的请求路径映射:
5.6 获取 Eureka Server 服务注册信息 - DiscoveryClient
先看需求分析示意图:
这里我们以服务消费方 去获取 Eureka Server 的服务注册信息为例讲解
当然也可以在服务提供方获取 Eureka Server 的服务注册信息。
5.5.1 具体操作步骤:
所在模块 member-service-consumer-80,修改:com.rainbowsea.springcloud.controller.MemberConsumerController
包当中的
增加如下代码:
@Resource // 装配到 Spring ioc 容器当中private DiscoveryClient discoveryClient;// 注意:想要获取到服务端信息,还需要在SpringBoot 启动场景上加上:@EnableDiscoveryClient // 启用服务发现 注解才行@GetMapping("/member/consumer/discovery")public Object discovery(){List<String> services = discoveryClient.getServices();// 遍历 servicesfor (String service : services) {log.info("服务名==={}",service);// 再根据服务名获取更加详细的信息List<ServiceInstance> instances = discoveryClient.getInstances(service);for (ServiceInstance instance : instances) {log.info("id={},host={},uri={}",instance.getServiceId(),instance.getHost(),instance.getUri());}}return this.discoveryClient;}
package com.rainbowsea.springcloud.controller;import com.rainbowsea.springcloud.entity.Member;
import com.rainbowsea.springcloud.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.util.List;@RestController
@Slf4j
public class MemberConsumerController {// 定义 MEMBER_SERVICE_PROVIDER_URL 这是一个基础 url地址// 使用 shift+ctrl+u 进行字母大小写的切换//private static final String MEMBER_SERVICE_PROVIDER_URL = "http://localhost:10000";// 负载均衡统一别名,修改为提供服务模块的注册别名: 不需要配置指明端口号,因为是一个负载集群了。不是特指某个了Service 服务来处理了/*server:port: 10000
spring:application:name: member-service-provider # 配置应用的名称*//*说明:1. MEMBER-SERVICE-PROVIDER 就是服务提供方【集群】,注册到Eureka Server 的名称2. 也就是服务提供方【集群】对外暴露的名称为 MEMBER-SERVICE-PROVIDER3. MEMBER-SERVICE-PROVIDER 目前有两个 Availability Zones UP (2) - localhost:member-service-provider:10000 , localhost:member-service-provider:10002还有一个 member-service-provider:10002需要增加一个注解 @LoadBalanced 赋予 RestTemplate 才能有负载均衡的能力,也就是会根据你的负载均衡来选择某个服务去访问,默认是“轮询算法”,当然我们也可以自己配置负载均衡算法4. 在对应的 RestTemplate 配置类上的,@Bean注解下面加上 @LoadBalanced 注解。*/private static final String MEMBER_SERVICE_PROVIDER_URL = "http://MEMBER-SERVICE-PROVIDER";// 装配 RestTemplate bean/对象@Resourceprivate RestTemplate restTemplate;@PostMapping("/member/consumer/save")public Result<Member> save(Member member) {// 1.第1个参数: 就是请求的完整的url:MEMBER_SERVICE_PROVIDER_URL + "/member/save" => http://localhost:10000/member/save// 表示你向将该请求,发送给那个微服务处理,注意无论是返回值,还是参数, @PostMapping() 请求方式都要一一对应上对应处理的微服务上的内容//2. 第2个参数: member : 就是通过 restTemplate 发出的 post 请求携带数据或者对象//3. 第3个参数: Result.class ,微服务当中的对应处理的方法的,返回值,也就是返回对象类型// 注意:坑点// 这里通过 restTemplate 调用服务模块的接口,就是一个远程调用//log.info("member-service-consumer-80 save member={}", member);return restTemplate.postForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/save", member, Result.class);}/*1.与@PostMapping("/member/save")public Result save(Member member) {int affected = memberService.save(member);if (affected > 0) { // 说明添加成功return Result.success("添加会员成功", affected);} else {return Result.error("401", "添加会员失败");}}*//*** 方法/接口,调用服务接口,返回 member 对象信息** @param id* @return*/@GetMapping("/member/consumer/get/{id}")public Result<Member> getMemberById(@PathVariable("id") Long id) {// 这里就用两个参数// 第一个参数,因为是查询,所以这里我们直接字符串拼接上去// 这里通过return restTemplate.getForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/get/" + id, Result.class);}/*保持一致:* 提交方式* 返回类型* 参数* 路径映射要对应上@GetMapping("/member/get/{id}")public Result getMemberById(@PathVariable("id") Long id) {Member member = memberService.queryMemberById(id);// 使用 Result 把查询到的结果返回if (member != null) {return Result.success("查询会员成功", member);} else {return Result.error("402", "ID" + id + "不存在");}}*/// 注意:有两个是这个包下的 : org.springframework.cloud.client.discovery.DiscoveryClient@Resource // 装配到 Spring ioc 容器当中private DiscoveryClient discoveryClient;// 注意:想要获取到服务端信息,还需要在SpringBoot 启动场景上加上:@EnableDiscoveryClient // 启用服务发现 注解才行@GetMapping("/member/consumer/discovery")public Object discovery(){List<String> services = discoveryClient.getServices();// 遍历 servicesfor (String service : services) {log.info("服务名==={}",service);// 再根据服务名获取更加详细的信息List<ServiceInstance> instances = discoveryClient.getInstances(service);for (ServiceInstance instance : instances) {log.info("id={},host={},uri={}",instance.getServiceId(),instance.getHost(),instance.getUri());}}return this.discoveryClient;}
}
- 这里修改所在模块 member-service-consumer-80当中的主启动类(场景启动类)
com.rainbowsea.springcloud.MemberConsumerApplication80
package com.rainbowsea.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;// 如果错误: 加入排除 DataSourceAutoConfiguration 自动配置
//@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
//@EnableEurekaClient 表示将项目/模块/程序 标注作为 Eureka Client
@EnableEurekaClient
@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现
public class MemberConsumerApplication80 {public static void main(String[] args) {SpringApplication.run(MemberConsumerApplication80.class, args);}
}
重启 member-service-consumer-80
浏览器输出 http://localhost/member/consumer/discovery
5.5.1.1 注意事项和细节说明
在引入 DiscoveryClient 时,不要引入错误的包
正确的包: import org.springframework.cloud.client.discovery.DiscoveryClient;
错误的包: import com.netflix.discovery.DiscoveryClient;
演示的是在服务消费方使用 DiscoveryClient 来完成服务发现,同样,在服务提供 方/模块也 OK
7. Eureka 后续说明
- Eureka 停更说明: https://github.com/Netflix/eureka/wiki
-
对于一些早期使用 Eureka 项目,掌握老师讲解技术基本可以应付了(这也是老师为什么还要讲Eureka的原因)
-
目前替代Eureka做服务注册和发现均衡负载的最佳组件是Nacos , 后面会重点讲解
Spring Cloud Alibaba -
虽然 Eureka 停更,目前用的不多,但是它的服务注册和发现均衡负载的思想是优先
的,有了Eureka的基础,我们学习Spring Cloud Alibaba Nacos会轻松很多
8. 总结:
- Spring Cloud Eureka 服务注册于发现
- Eureka 自我保护模式
默认情况下EurekaClient 定时向 EurekaServer 端发送 心跳包
如果 Eureka 在 server 端一定时间内(默认90秒) 没有收到 EurekaClient 发送心跳包,便会
直接从服务注册表中剔除该服务如果Eureka 开启了**“自我保护机制/模式”** ,那么在短时间(90秒中)内丢失了大量的服务实例心跳。
这时候Eureka Server 会开启自我保护机制,不会剔除该服务(该现象可能出现在如果网络不通或者
阻塞)因为客户端还能正常发送心跳,只是网络延迟问题,而保护机制是为了解决此问题而产生的。自我保护是属于CAP里面的AP分支 ,保证高可用和分区容错性
自我保护模式是一种应对网络异常的安全保护措施,它的架构哲学是宁可同时保留所有微服务(健康
的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。使用自我保护模式,
可以让 Eureka 集群更加的健壮,稳定,参考:
https://blog.csdn.net/wangliangluang/article/details/120626014
在生产环境中,一般不会禁用自我保护模式 。
- Eureka 集群-实现负载均衡,故障容错
为什么需要集群 Eureka Server
说明:
- 微服务 RPC 远程服务调用最核心的是实习高可用
- 如果注册中心只有1个,它出故障,会导致整个服务环境不可用
- 解决办法: 搭建 Eureka 注册中心集群,实习 负载均衡 + 故障容错
因为 member-service-provider-10000 和 member-service-provider-10002 作为一个集 群提供服务, 因此需要将 spring.application.name 进行统一,方便用于负载均衡
这样消费方通过统一的别名进行负载均衡调用。
特别说明: 我们想要能够实现 member 交替访问的话,需要在 RestTemplate 配置类上@Bean方法上加上该 @LoadBalanced注解的)才行。 底层是 Ribbon 支持算法 交替访问 member服务说明:
注解@LoadBalanced(在RestTemplate 配置类的@Bean方法上加上该 @LoadBalanced注解的) 底层是 Ribbon 支持算法
Ribbon 和 Eureka 整合后 consumer 直接调用服务而不用再关心地址和端口号,且该服务还有负载功能
- 定义本地的域名机制:
设置本地的域名映射,需要找到本地电脑当中的 host
文件,在该 host
文件当中编写添加相应的域名映射。
host文件路径: C:\Windows\System32\drivers\etc\host
127.0.0.1 account.wondershare.com
# 配置 eureka 主机 和 ip 的映射
127.0.0.1 eureka9001.com
127.0.0.1 eureka9002.com
特别提醒:如果发现文件修改后无法保存,那么可以将文件复制到桌面上,然后,修改复制到桌面上的那份复制过来的 host 文件,修改保存完后,再拷贝回原来路径位置,进行一个替换。
- 获取 Eureka Server 服务注册信息 - DiscoveryClient;在引入 DiscoveryClient 时,不要引入错误的包,正确的包: import org.springframework.cloud.client.discovery.DiscoveryClient;
9. 最后:
“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”
相关文章:

3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)
3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用) 文章目录 3. Spring Cloud Eureka 服务注册与发现(超详细说明及使用)前言1. Spring Cloud Eureka 的概述1.1 服务治理概述1.2 服务注册与发现 2. 实践:创建单机 Eureka Server 注册中心2.1 需求说明 图解…...

品牌如何利用大数据工具,进行消费者洞察分析?
存量竞争的时代, 消费者聆听是品牌持续增长的关键,借助大数据的消费者数据洞察,可以帮助品牌分析消费者的所思所想及行为特征,获取消费者对产品的需求痛点、使用感受,对品牌的评价口碑等,从而帮助品牌更好地…...

鸿蒙实现 web 传值
前言:安卓和 IOS 加载 H5 的时候,都有传值给到 H5 或者接收 H5 值,鸿蒙也可传值和接收 H5 的内容,以下是鸿蒙传值给 H5 端的具体操作 一: 定义好 H5 和鸿蒙传值的方法名,两端必须保持方法名一致 // xxx.ets import …...

uniapp vuex的使用
实现组件全局(数据)管理的一种机制,可以方便的实现组件之间共享数据,不同于上述三种传递值的方式。 可以把vuex当成一个store仓库,可以集中管理共享的数据,并且存储在vuex中的数据都是响应式的,…...

RabbitMQ实战启程:从原理到部署的全方位探索(上)
文章目录 一、RabbitMQ简介1.1、概述1.2、特性 二、RabbitMQ原理架构三、RabbitMQ应用场景3.1 简单模式3.2 工作模式3.3 发布订阅3.4 路由模式3.5 主题订阅模式 四、同类中间件对比五、RabbitMQ部署5.1 单机部署5.1.1 安装erlang5.1.2 安装rabbitmq 5.2 集群部署(镜…...

【论文复现】轻松利用自适应特征融合实现去雾
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 智慧医疗 介绍创新点网络结构特征提取阶段自适应融合阶段图像重建阶段上下文增强模块CEM特征融合模块AFM 结果分析 提示 论文题目࿱…...

【大数据学习 | HBASE高级】hbase-phoenix 与二次索引应用
1. hbase-phoenix的应用 1.1 概述: 上面我们学会了hbase的操作和原理,以及外部集成的mr的计算方式,但是我们在使用hbase的时候,有的时候我们要直接操作hbase做部分数据的查询和插入,这种原生的方式操作在工作过程中还…...

高级java每日一道面试题-2024年11月09日-缓存中间件篇-Redis和Memecache有什么区别?
如果有遗漏,评论区告诉我进行补充 面试官: Redis和Memecache有什么区别? 我回答: 一、基础特性 数据类型支持 Redis: 支持多种数据类型,包括字符串(String)、哈希(Hash)、列表(List)、集合…...

vscode 关闭绑定元素 隐式具有“any”类型这类错误
在vue的项目里面,经常看到any类型的报错,真的很烦的 在tsconfig.json中配置以下参数 “noImplicitAny”: false 就可以了 出现类型“never”上不存在属性“userName”。ts-plugin(2339) 配置该参数 modeuleResolution : node "compilerOptions&qu…...

手机ip地址异常怎么解决
在现代社会中,手机已成为我们日常生活中不可或缺的一部分,无论是工作、学习还是娱乐,都离不开网络的支持。然而,有时我们会遇到手机IP地址异常的问题,这不仅会影响我们的网络体验,还可能带来安全隐患。本文…...

【售前方案】工业园区整体解决方案,智慧园区方案,智慧城市方案,智慧各类信息化方案(ppt原件)
基于云计算、物联网、移动通信计算的智慧园区集中运营管理平台是一个高度集成化、智能化的管理系统,它利用先进的技术手段对园区进行全方位的监控和管理。 软件资料清单列表部分文档清单:工作安排任务书,可行性分析报告,立项申请审…...

37.超级简易的计算器 C语言
超级简单,简单到甚至这个计算器输入都比较反人类 但是足够简单 有输入功能有Switch语句支持四种运算还能检查除数是不是0还能打印出完整的式子 #define _CRT_SECURE_NO_WARNINGS// 禁用安全警告 #include <stdio.h>int main() {double num1, num2;// 声明两…...

防火墙----iptables
防火墙是位于内部网和外部网之间的屏障,他按照系统管理员预先定义好的规则来控制数据包的进出 一、iptables简介 防火墙会从以上至下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止&…...

若点集A=B则A必能恒等变换地变为B=A这一几何常识推翻直线(平面)公理
黄小宁 关键词:“更无理”复数 复平面z各点z的对应点z1的全体是z1面。z面平移变为z1面就使x轴⊂z面沿本身平移变为ux1轴。R可几何化为R轴,R轴可沿本身平移变为R′轴,R′轴可沿本身平移变为R″轴,...。直线公理和平面公理使几百年…...

网络安全之WINDOWS端口及病毒编写
目录 一、常见端口和服务 二、Windows病毒编写 声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 声明:本文主要用作技术分享,所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判…...

Flink 开发工程应加载哪些依赖
在我们要开发Flink程序时,就会涉及到应该加载哪些Flink jar的问题。本章内容就是向你展示如何配置你的项目,添加必要的依赖。 每个应用程序都会依赖一些 Flink libraries,比如至少依赖 Flink APIs库,如果使用了connector,则还需要依赖connector相关的库,比如kafka、jdbc…...

wordpress建外贸独立站常用的多语言插件
WordPress是一个功能强大的内容管理系统,对于外贸独立站来说,多语言支持是非常重要的功能。以下是一些常用的WordPress多语言插件: 1. WPML (WordPress Multilingual) 这是最流行且功能最全面的多语言插件之一。它支持翻译整个网站…...

[SpB]如何开始使用 Spring Boot?
如何开始使用 Spring Boot? Spring Boot 简化了 Java 项目开发,你只需要专注于业务逻辑,底层的很多配置和功能由 Spring Boot 自动帮你处理。下面是你如何快速上手 Spring Boot 的步骤,以及如何通过 IDEA 了解 Spring Boot 的功能…...

蓝桥杯模拟
【问题描述】 如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只…...

数字化转型企业架构设计手册(交付版),企业数字化转型建设思路、本质、数字化架构、数字化规划蓝图(PPT原件获取)
1、企业架构现状分析 2、企业架构内容框架 3、企业架构设计方法 3.1 、业务架构设计方法 3.2 、数据架构设计方法 3.3 、应用架构设计方法 3.4 、技术架构设计方法 软件全套资料部分文档清单: 工作安排任务书,可行性分析报告,立项申请审批表&…...

2. langgraph中的react agent使用 (在react agent添加历史消息)
1. 导入必要的库 首先,我们需要导入所需的库。这里我们使用 langchain_openai 来与 智谱AI 模型进行交互,并使用 langchain_core.tools 来定义自定义工具。 from langchain_openai import ChatOpenAI from typing import Literal from langchain_core.…...

MySQL社区版的启动与连接
1.启动: 注意:MySQL是默认开机自启的 方式一: 1.WinR 的命令行中直接输入services.msc 2.在服务中找到数据库名称,然后鼠标右键点击启动 方式二: 1.在开始选项中搜索“cmd”命令提示符,使用管理员身份运行 …...

【图像压缩感知】论文阅读:Content-Aware Scalable Deep Compressed Sensing
tips: 本文为个人阅读论文的笔记,仅作为学习记录所用。本文参考另一篇论文阅读笔记 Title: Content-Aware Scalable Deep Compressed Sensing Journal: TIP 2022 代码链接: https://github.com/Guaishou74851/CASNet…...

物理hack
声明 声明 文章只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 ✍🏻作者简介:致力于网络安全领域,目前作为一名学习者,很荣…...

Linux——环境基础开发工具使用2(正在更新中...)
1.自动化构建-make/Makefile 1.1 认识make和Makefile make是一个命令; Makefile是一个文件。 1.2 理解 其中在第一个图片中,第一行的 mytest:test.c 叫做依赖关系;第二行的 gcc test.c -o mytest 叫做依赖方法。 依赖关系和依赖方法共同…...

STM32传感器模块编程实践(十二) micro SD卡模块简介及驱动源码
文章目录 一.概要二.Micro SD卡模块主要特性三.Micro SD卡模块接线说明四.Micro SD卡模块参考原理图五.通讯协议介绍六.FATFS文件系统介绍七.STM32F030C8T6单片机与SD卡模块实现数据读写实验1.硬件准备2.软件工程3.软件主要代码4.实验效果 八.源代码工程下载九.小结 一.概要 M…...

Linux debian系统安装ClamTk开源图形用户界面(GUI)杀毒软件
一、ClamTk简介 ClamTk 是一个基于 ClamAV 的开源图形用户界面(GUI)杀毒软件。它使用 GTK2-Perl 脚本构建而成,支持32位与64位操作系统。ClamTk 提供了一个直观的用户界面,使得用户无需深入了解命令行即可完成大部分操作。它具备…...

RapidIO介绍
传统串行总线(如 UART, SPI, I2C 等) 特点: 接口简单:传统的串行总线设计相对简单,通常使用少量的引脚,因此硬件设计较为简洁。协议简单:这些协议设计简单,容易实现,因…...

用魔方做存储器
用魔方模拟存储器是一种形象化的方式,特别适合教学演示或帮助理解存储器结构。以下是如何将魔方作为存储器的设计思路和可能的实现: 基本思路 魔方的结构: 魔方有 (6) 个面,每面 (3 \times 3 9) 个方块,总共 (6 \time…...

动力商城-03 Idea集成apifox Mybatis-Plus字段策略
1.Idea下载apifox插件 2.新建令牌放入Idea 3.右键上传到对应接口 4.设置前置url 插件能够自动识别swagger注解 Mybatis-Plus字段策略 1、FieldStrategy作用 Mybatis-Plus字段策略FieldStrategy的作用主要是在进行新增、更新时,根据配置的策略判断是否对实体对…...