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 容易很多,而且理解的更深刻。

分析上述我们上一篇内容补充 当中项目架构问题分析

在这里插入图片描述

当前项目问题分析:

  1. 在企业项目中,服务消费访问请求会存在高并发
  2. 如果只有一个会议中心-提供服务,可用性就比较差了
  3. 所以,会议中心提供服务往往是一个集群,也就是说会有多个会议中心-提供服务微服务模块
  4. 那么这个时候,就存在一个问题就是服务消费方,怎么去发现可以使用的服务(哪些服务又不可以使用)
  5. 当服务消费方,发现了可以使用的服务后(可能是多个,又存在一个问题就是到底调用 A服务,
    还是调用B服务,这就引出了服务注册和负载均衡的问题)
  6. Eureka 就可以解决上述问题

引入 Eureka 项目架构,一图胜千言

在这里插入图片描述

上图 Eureka 项目架构图解析:

  1. 会员中心——> 提供服务的,在项目中,会做成集群 ,提供高可用
  2. Eureka Server 有必要的话,也可以做成集群
  3. Eureka 包含两个组件: Eureka ServerEureka Client
  4. Eureka Server 提供注册服务,各个微服务节点童工配置启动后,会在 EurekaServer 中进行注册,
    这样Eureka Server 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
  5. 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 以及 完成配置

  1. 创建 e-commerce-eureka-server-9001 微服务模块[作为注册中心]

在这里插入图片描述

在这里插入图片描述

父工程的 pom.xml-会做相应变化,管理 e-commerce-eureka-server-9001 微服务子模块

在这里插入图片描述

  1. 修改 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>
  1. 创建 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 服务角色 ,所以自然,我们需要将其配置为 服务角色。

在这里插入图片描述

  1. 创建主启动类 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);}
}
  1. 完成测试:

在这里插入图片描述

补充说明: 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 文件当进行一个配置。如下图所示:

  1. 配置 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

在这里插入图片描述

  1. 同时我们也需要将该 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);}
}

测试:

  1. 启动 e-commerce-eureka-server-9001
  2. 启动 member-service-provider-10000
  3. 浏览器: 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
说明:

  1. 微服务 RPC 远程服务调用最核心的是实习高可用
  2. 如果注册中心只有1个,它出故障,会导致整个服务环境不可用
  3. 解决办法: 搭建 Eureka 注册中心集群,实习 负载均衡 + 故障容错

5.2 需求分析/图解

在这里插入图片描述

5.3 搭建 Eureka Server 集群

1. 创建 e-commerce-eureka-server-9002 微服务模块[作为注册中心]

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 修改 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>
  1. 创建 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/
  1. 创建主启动类 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);}
}
  1. 修改 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 文件,修改保存完后,再拷贝回原来路径位置,进行一个替换。

运行测试:

  1. 启动 e-commerce-eureka-server-9001
  2. 启动 e-commerce-eureka-server-9002
  3. 浏览器: http://eureka9001.com:9001 浏览器: http://eureka9002.com:9002

在这里插入图片描述

在这里插入图片描述

将 member-service-consumer-80 注册到 EurekaServer 集群(目前 2 台)

修改 member-service-consumer-80 模块当中的:resources/application.yml

在这里插入图片描述

在这里插入图片描述

  1. 启动 e-commerce-eureka-server-9001 和 e-commerce-eureka-server-9002
  2. 启动 member-service-consumer-80
  3. 观察 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服务说明:

  1. 注解@LoadBalanced(在RestTemplate 配置类的@Bean方法上加上该 @LoadBalanced注解的)
    底层是 Ribbon 支持算法

在这里插入图片描述

  1. 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;}
}
  1. 这里修改所在模块 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 后续说明

  1. Eureka 停更说明: https://github.com/Netflix/eureka/wiki

在这里插入图片描述

  1. 对于一些早期使用 Eureka 项目,掌握老师讲解技术基本可以应付了(这也是老师为什么还要讲Eureka的原因)

  2. 目前替代Eureka做服务注册和发现均衡负载的最佳组件是Nacos , 后面会重点讲解
    Spring Cloud Alibaba

  3. 虽然 Eureka 停更,目前用的不多,但是它的服务注册和发现均衡负载的思想是优先
    的,有了Eureka的基础,我们学习Spring Cloud Alibaba Nacos会轻松很多

8. 总结:

  1. Spring Cloud Eureka 服务注册于发现
  2. Eureka 自我保护模式
  • 默认情况下EurekaClient 定时向 EurekaServer 端发送 心跳包

  • 如果 Eureka 在 server 端一定时间内(默认90秒) 没有收到 EurekaClient 发送心跳包,便会
    直接从服务注册表中剔除该服务

  • 如果Eureka 开启了**“自我保护机制/模式”** ,那么在短时间(90秒中)内丢失了大量的服务实例心跳。
    这时候Eureka Server 会开启自我保护机制,不会剔除该服务(该现象可能出现在如果网络不通或者
    阻塞)因为客户端还能正常发送心跳,只是网络延迟问题,而保护机制是为了解决此问题而产生的。

  • 自我保护是属于CAP里面的AP分支 ,保证高可用和分区容错性

  • 自我保护模式是一种应对网络异常的安全保护措施,它的架构哲学是宁可同时保留所有微服务(健康
    的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务
    。使用自我保护模式,
    可以让 Eureka 集群更加的健壮,稳定,参考:
    https://blog.csdn.net/wangliangluang/article/details/120626014

在生产环境中,一般不会禁用自我保护模式

  1. Eureka 集群-实现负载均衡,故障容错

为什么需要集群 Eureka Server
说明:

  1. 微服务 RPC 远程服务调用最核心的是实习高可用
  2. 如果注册中心只有1个,它出故障,会导致整个服务环境不可用
  3. 解决办法: 搭建 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 直接调用服务而不用再关心地址和端口号,且该服务还有负载功能

  1. 定义本地的域名机制:

设置本地的域名映射,需要找到本地电脑当中的 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 文件,修改保存完后,再拷贝回原来路径位置,进行一个替换。

  1. 获取 Eureka Server 服务注册信息 - DiscoveryClient;在引入 DiscoveryClient 时,不要引入错误的包,正确的包: import org.springframework.cloud.client.discovery.DiscoveryClient;

9. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024年11月第2个交易周收盘总结

计划自己的交易&#xff0c;交易自己的计划! 跟随市场而情绪波动&#xff0c;最终一定会导向失败&#xff01;连续、平稳、冷静地惯彻交易计划&#xff0c;比什么都重要&#xff01; 交易本身是极其简单和清楚的&#xff0c;让事情变复杂的原因不是行情走势和交易本身&#x…

一种时间戳对齐的方法(离线)

这段代码的主要功能是: 读取指定目录下的 pcd 文件和 jpg 文件。对于每个 pcd 文件,在 jpg 目录中找到时间戳最接近的 jpg 文件。将找到的 jpg 文件复制到对应的输出目录,实现时间戳对齐。 这种时间戳对齐的操作在多传感器数据融合中非常常见,它确保了不同传感器采集的数据在时…

【数据分享】全国农产品成本收益资料汇编(1953-2024)

数据介绍 一、《全国农产品成本收益资料汇编 2024》收录了我国2023年主要农产品生产成本和收益资料及 2018年以来六年的成本收益简明数据。其中全国性数据均未包括香港、澳门特别行政区和台湾省数据。 二、本汇编共分七个部分,即:第一部分,综合;第二部分,各地区粮食、油料;第…

SQL 处理数列

在关系模型的数据结构中&#xff0c;并没有“顺序”这一概念。因此&#xff0c;基于它实现的关系数据库中的表和视图的行和列也必然没有顺序。 1 处理数列 1.1 实践 1.1.1 生成连续编号 图 t_num 数据库源与目标视图v_seq 需求&#xff1a;根据0~9 这10个数&#xff0c;生成…

【云原生系列--Longhorn的部署】

Longhorn部署手册 1.部署longhorn longhorn架构图&#xff1a; 1.1部署环境要求 kubernetes版本要大于v1.21 每个节点都必须装open-iscsi &#xff0c;Longhorn依赖于 iscsiadm主机为 Kubernetes 提供持久卷。 apt-get install -y open-iscsiRWX 支持要求每个节点都安装 N…

编写情绪K线指标(附带源码下载)

编写需求&#xff1a; 很多交易者抱怨&#xff0c;传统的跟踪类指标常常存在滞后的问题&#xff0c;而预测类指标又常常不够可靠。那么&#xff0c;是否存在一种指标&#xff0c;能够精准地反映当前K线的强弱变化&#xff0c;并且具备高度的时效性呢&#xff1f; 效果展示&am…

16、pxe自动装机

pxe自动装机的组成 pxe&#xff1a;自动安装系统必要的运行环境 无人值守&#xff1a;为系统定制化的安装需要的软件 pxe的优点 规模化&#xff1a;同时装配多台服务器&#xff08;20-30&#xff09; 自动化&#xff1a;系统安装和服务配置不需要人工干预 远程实现&#x…

H.265流媒体播放器EasyPlayer.js网页直播/点播播放器WebGL: CONTEXT_LOST_WEBGL错误引发的原因

EasyPlayer无插件直播流媒体音视频播放器属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 EasyPlayer.js能够同时支持HTTP、HTTP-FLV、HLS&a…

Javaweb开发核⼼心之玩转Servlet4(笔记)

javaweb开发核⼼心之玩转Servlet4.0 简介&#xff1a;什么是Servlet-开发你的第⼀一个动态⽹网站 什么是Servlet 简介&#xff1a;是JavaServlet的简称&#xff0c;⽤用Java编写的运⾏行行在Web服务器器或应⽤用服务器器上的程序,具有独⽴立于平台和协议的特性, 主要功能在于交…

VUE实现通话:边录边转发送语言消息、 播放pcm 音频

文章目录 引言I 音频协议音频格式:音频协议:II 实现协议创建ws对象初始化边录边转发送语言消息 setupPCM按下通话按钮时开始讲话,松开后停止讲话播放pcm 音频III 第三库recorderplayer调试引言 需求:电台通讯网(电台远程遥控软件-超短波)该系统通过网络、超短波终端等无线…

无人机遥控器基础讲解——CKESC电调小课堂08

无人机遥控器是控制无人机飞行的重要设备&#xff0c;以下是对其的详细介绍&#xff1a; CKESC-专业级电调研发生产供应商http://www.ckesc.com 一、外观与布局 1. 通常由两个摇杆、多个功能按钮、一个显示屏和天线组成。 2. 摇杆一般位于遥控器的中央位置&#xff0c;用于控…

谷歌新作:Unbounded开放世界RPG,AI定义无限游戏新纪元

在开放世界和角色扮演游戏的领域里&#xff0c;玩家们总是渴望着那种无拘无束的自由体验。他们梦想着一个没有空气墙阻隔&#xff0c;没有剧情杀限制&#xff0c;没有任何交互限制的游戏世界。现在&#xff0c;这个梦想可能即将成真。谷歌联合北卡罗来纳大学教堂山分校推出的Un…

Qt文件目录操作

文件目录操作相关类 Qt 为文件和目录操作提供了一些类&#xff0c;利用这些类可以方便地实现一些操作。Qt 提供的与文件和目录操作相关的类包括以下几个&#xff1a; QCoreApplication&#xff1a;用于提取应用程序路径&#xff0c;程序名等文件信息&#xff1b;QFile&#x…

网页web无插件播放器EasyPlayer.js H.265流媒体播放器的decoder.js报Unexpected token ‘<‘错误

EasyPlayer.js H.265流媒体播放器属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff1b;支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#xff…

渗透测试之信息收集 DNS主机发现探测方式NetBIOS 协议发现主机 以及相关PorCheck scanline工具的使用哟

目录 主机发现 利用NetBIOS 协议发现主机 利用TCP/UDP发现主机 PorCheck scanline 利用DNS协议发现主机 主机发现 信息收集中的一项重要工作是发现内网中的主机、数据库、IP段网络设备、安全设备等资产&#xff0c;以便于更快地获取更多权限和密码&#xff0c;更加接近红…

Nginx SSL+tomcat,使用request.getScheme() 取到https协议

架构上使用了 Nginx tomcat 集群, 且nginx下配置了SSL,tomcat no SSL,项目使用https和http协议。 发现 request.getScheme() //总是 http&#xff0c;而不是实际的http或https request.isSecure() //总是false&#xff08;因为总是http&#xff09; request.getRemoteAddr(…

[Redis] Redis服务集群

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

期权懂|上证50ETF期权的交易时间是什么时候?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 上证50ETF期权的交易时间是什么时候&#xff1f; 一、开盘集合竞价时间‌&#xff1a; 上午9:15至9:25。在这段时间内&#xff0c;投资者可以提交或撤销委托&#xff0c;但不会立…

FPGA 第7讲 简单组合逻辑译码器

时间&#xff1a;2024.11.15 一、学习内容 1.译码器 译码是编码的逆过程&#xff0c;在编码时&#xff0c;每一种二进制代码&#xff0c;都赋予了特定的含义&#xff0c;即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码&#xff0c;实现译码操…

jmeter常用配置元件介绍总结之断言

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之断言 9.断言9.1.响应断言9.2.JSON断言9.3.大小断言9.4.JSON JMESPath Assertion9.5.断言持续时间9.6.MD5Hex断言9.7.XPath断言9.8.XPath2 Assertion 9.断言 检查测试中得到的响应数据结果是否符合预期 9.1.响应断言 功…