• Eureka服务注册与发现


     

    当前项目架构存在的问题

    引出 Eureka

    会员中心,这一块在项目中往往会做成 1 个集群

    为什么需要做成集群呢?

    解决高并发和负载量比较大的问题

    举例:

    会员中心-在 1 台主机上的,假设该主机最多只能接收 1w 请求数据

    如果大量的请求去访问同 1 台服务器(会员中心),

    这样肯定会造成服务器超负荷运行,可能导致各种问题

    如果我们使用集群,也就是开多几个服务器(会员中心)

    那么可以解决如上存在的问题

    服务注册与发现的原理

    深入了解服务注册与服务发现-CSDN博客

    创建单机 Eureka Server-注册中心

    报错解决:Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://localhost:8761/eureka/}-CSDN博客

    验证是否创建模块成功

    在当前父级项目 pom.xml 中查看是否引入了创建的子模块

    查看当前子模块是否在父级模块的内部

    查看当前创建的子模块,是否成功与父级模块建立了依赖关系

    eureka配置

    修改 pom.xml , 加入依赖

    引入后记得刷新,加载依赖后,继续下面的步骤

    1. <!-- 引入 e_commerce_center-common-api -->
    2. <dependency>
    3. <!-- 这里需要创建父模块的groupId-->
    4. <groupId>com.wwf.springcloud</groupId>
    5. <!-- 公共的api项目名-->
    6. <artifactId>e_commerce_center-common-api</artifactId>
    7. <version>${project.version}</version>
    8. </dependency>
    9. <!-- 引入 eureka-server -->
    10. <dependency>
    11. <groupId>org.springframework.cloud</groupId>
    12. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.springframework.boot</groupId>
    16. <artifactId>spring-boot-starter-web</artifactId>
    17. </dependency>
    18. <!-- 监控-生命服务是否健康 -->
    19. <dependency>
    20. <groupId>org.springframework.boot</groupId>
    21. <artifactId>spring-boot-starter-actuator</artifactId>
    22. </dependency>
    23. <dependency>
    24. <groupId>org.projectlombok</groupId>
    25. <artifactId>lombok</artifactId>
    26. <optional>true</optional>
    27. </dependency>
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-test</artifactId>
    31. <scope>test</scope>
    32. </dependency>
    33. <dependency>
    34. <groupId>junit</groupId>
    35. <artifactId>junit</artifactId>
    36. </dependency>

    创建 resources/application.yml

    1. server:
    2. port: 9001
    3. eureka:
    4. instance:
    5. hostname: localhost #eureka 服务端的实例名字
    6. #该注册中心将来也可能是集群
    7. client:
    8. register-with-eureka: false #不向注册中心注册自己
    9. #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    10. fetch-registry: false
    11. service-url:
    12. #设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址
    13. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    创建主启动程序

    1. /**
    2. * @author 卒迹
    3. * @version 1.0
    4. */
    5. //@EnableEurekaServer 表示该程序,作为 Eureka Server
    6. @EnableEurekaServer
    7. // 配置注解扫描路径
    8. @SpringBootApplication(scanBasePackages = {"com.wwf"})
    9. public class EurekaApplication {
    10. public static void main(String[] args) {
    11. SpringApplication.run(EurekaApplication.class, args);
    12. }
    13. }
    http://localhost:9001/

    服务提供者(端口 10000)

    当前服务其他服务所调用

    修改 pom.xml

    引入后记得刷新

    1. <!-- 引入 eureka-client 依赖 -->
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    5. </dependency>

    修改 resources/application.yml

    1. #eureka 客户端配置
    2. eureka:
    3. client:
    4. register-with-eureka: true #将自己注册到 EurekaServer
    5. #是否从从 EurekaServer 抓取注册信息,默认为 true, 单节点无所谓,
    6. #集群必须设置为 true 才能配合 ribbon 使用负载均衡
    7. fetchRegistry: true
    8. service-url:
    9. #表示将自己注册到哪个 eurekaServer
    10. defaultZone: http://localhost:9001/eureka

    修改主启动类

    1. @SpringBootApplication
    2. //@EnableEurekaClient 将该程序标识为 EurekaClient
    3. @EnableEurekaClient
    4. public class MemberApplication {
    5. public static void main(String[] args) {
    6. SpringApplication.run(MemberApplication.class, args);
    7. }
    8. }

    服务消费者(调用方 80 端口)

    服务消费者:当前接口-调用了另外接口的方法

    修改 pom

    1. <!-- 引入 eureka-client 依赖 -->
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    5. </dependency>

    修改 application.yml

    1. server:
    2. port: 80
    3. spring:
    4. application:
    5. name: member-service-consumer #注册的名称
    6. #eureka 客户端配置
    7. eureka:
    8. client:
    9. service-url:
    10. #表示关联哪个 eurekaServer(注册/拉取服务信息)
    11. defaultZone: http://localhost:9001/eureka
    12. #将自己注册到 EurekaServer, 也可以设置 false, 不注册
    13. register-with-eureka: true
    14. #配置从 EurekaServer 抓取其它服务注册信息
    15. fetchRegistry: true

    修改启动类

    配置完记得重启 springBoot 启动类

    Eureka 自我保护模式

    在默认情况下, Eureka 启动了自我保护模式(如图红字, 需要刷新页面, 可以看到)

    服务与注册中心→检测心跳→server

    1. server:
    2. port: 9001
    3. eureka:
    4. instance:
    5. hostname: localhost #eureka 服务端的实例名字
    6. #服务提供者(server)
    7. server:
    8. enable-self-preservation: false #禁用自我保护
    9. eviction-interval-timer-in-ms: 2000 #间隔时间2秒,即2秒收不到心跳就认为超时
    10. #服务消费者(client)
    11. client:
    12. register-with-eureka: false #不向注册中心注册自己
    13. #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    14. fetch-registry: false
    15. service-url:
    16. #设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址
    17. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    修改服务提供者(10000) application.yml

    1. server:
    2. port: 10000 #服务端-端口号
    3. spring:
    4. application:
    5. name: member-service-provider #当前模块的项目名称-访问地址必须加上才能够访问
    6. datasource:
    7. type: com.alibaba.druid.pool.DruidDataSource
    8. # driver-class-name: org.gjt.mm.mysql.Driver
    9. #数据库地址:
    10. #jdbc:mysql://域名:端口/数据库名称?useUnicode=true&characterEncoding=utf-8&useSSL=false
    11. url: jdbc:mysql://localhost:3306/e_commerce_center_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
    12. username: root #数据库名称
    13. password: abc123 #数据库密码
    14. #eureka 客户端配置
    15. eureka:
    16. client:
    17. register-with-eureka: true #将自己注册到 EurekaServer
    18. #是否从从 EurekaServer 抓取注册信息,默认为 true, 单节点无所谓,
    19. #集群必须设置为 true 才能配合 ribbon 使用负载均衡
    20. fetchRegistry: true
    21. service-url:
    22. #表示将自己注册到哪个 eurekaServer
    23. defaultZone: http://localhost:9001/eureka
    24. #心断检与续约时间
    25. #如果你希望保证CP,时间间隔可以短一些,保证服务关闭后注册中心能即使剔除服务 instance
    26. #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    27. lease-renewal-interval-in-seconds: 1
    28. #Eureka服务端在收到最后一次心跳后等待时间上限,单位为种(默认是90秒),超时将剔除服务
    29. lease-expiration-duration-in-seconds: 2
    30. mybatis:
    31. mapperLocations: classpath:mapper/*.xml #后面 mapper 文件的位置
    32. type-aliases-package: com.wwf.entity #指定POJO扫描包来让mybatis自动扫描到自定义的POJO。

    维护机制-注册中心

    搭建 EurekaServer 集群-实现负载均衡&故障容错

    1.新建模块(参考注册 9001)

    2.确保父项目中-子模块被引入了

    3.引入 Pom 依赖(9002-当前)

    如果这里报红-看一下是不是当前父级项目的 groupId 没有引对

    该名为,创建模块时的高级设置里面的父级的 groupId

    1. <!-- 因为是子模块,因此不需要指定 groupId 了,从父工程继承 -->
    2. <!-- 引入 e_commerce_center-common-api -->
    3. <dependency>
    4. <!-- 当前父级项目的groupId-->
    5. <groupId>com.wwf.springcloud</groupId>
    6. <!-- 公共模块-项目名-->
    7. <artifactId>e_commerce_center-common-api</artifactId>
    8. <version>${project.version}</version>
    9. </dependency>
    10. <!-- 引入 eureka-server -->
    11. <dependency>
    12. <groupId>org.springframework.cloud</groupId>
    13. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    14. </dependency>
    15. <dependency>
    16. <groupId>org.springframework.boot</groupId>
    17. <artifactId>spring-boot-starter-web</artifactId>
    18. </dependency>
    19. <dependency>
    20. <groupId>org.springframework.boot</groupId>
    21. <artifactId>spring-boot-starter-actuator</artifactId>
    22. </dependency>
    23. <dependency>
    24. <groupId>org.projectlombok</groupId>
    25. <artifactId>lombok</artifactId>
    26. <optional>true</optional>
    27. </dependency>
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-test</artifactId>
    31. <scope>test</scope>
    32. </dependency>
    33. <dependency>
    34. <groupId>junit</groupId>
    35. <artifactId>junit</artifactId>
    36. </dependency>

    4.创建 resources/application.yml

    这里可以直接参考 9001 端口 的eureka server

    1. server:
    2. port: 9002
    3. eureka:
    4. instance:
    5. hostname: eureka9002.com #eureka 服务端的实例名字
    6. #服务提供者(server)
    7. # server:
    8. # enable-self-preservation: false #禁用自我保护
    9. # eviction-interval-timer-in-ms: 2000 #间隔时间2秒,即2秒收不到心跳就认为超时
    10. #服务消费者(client)
    11. client:
    12. register-with-eureka: false #不向注册中心注册自己
    13. #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    14. fetch-registry: false
    15. service-url:
    16. #设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址
    17. defaultZone: http://eureka9001.com:9001/eureka/ # 相 互 注 册 , 这 里 写eureka9001.com

    5.创建主启动类 EurekaApplication9002.java

    1. package com.wwf.start;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    5. /**
    6. * @author 卒迹
    7. * @version 1.0
    8. */
    9. //@EnableEurekaServer 表示该程序,作为 Eureka Server
    10. @EnableEurekaServer
    11. // 配置注解扫描路径
    12. @SpringBootApplication(scanBasePackages = {"com.wwf"})
    13. public class EurekaApplication9002 {
    14. public static void main(String[] args) {
    15. SpringApplication.run(EurekaApplication9002.class, args);
    16. }
    17. }

    6.修改另外的 eureka 的配置文件

    1. server:
    2. port: 9001
    3. eureka:
    4. instance:
    5. hostname: eureka9001.com #eureka 服务端的实例名字
    6. #服务提供者(server)
    7. # server:
    8. # enable-self-preservation: false #禁用自我保护
    9. # eviction-interval-timer-in-ms: 2000 #间隔时间2秒,即2秒收不到心跳就认为超时
    10. #服务消费者(client)
    11. client:
    12. register-with-eureka: false #不向注册中心注册自己
    13. #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
    14. fetch-registry: false
    15. service-url:
    16. #设置与 eureka server 交互的模块,查询服务和注册服务都需要依赖这个地址
    17. defaultZone: http://eureka9002.com:9002/eureka/

    7. 修改主启动类名为 EurekaApplication9001.java

    8.修改 Host 文件

    1. #eureka 主机名和 ip 映射
    2. 127.0.0.1 eureka9001.com
    3. 127.0.0.1 eureka9002.com

    这里可以直接使用火绒安全软件-工具进行修改

    8.完成测试

    1. 一般实际开发中,不同的服务一般都是搭建在不同的主机服务器上
    2. http://eureka9001.com:9001/eureka
    3. http://eureka9002.com:9002/eureka
    4. 如果上面地址访问不了,
    5. 我这里是在本地进行的搭建,所有访问本地即可
    6. localhost:9001
    7. localhost:9002

    此时 9002 与 9001 端口的注册与服务中心 Eureka Server 相互完成了注册

    将提供服务 10000 端口的模块,

    注册到多个 Eureka 上

    9.完成测试

    10.总结

    80 端口服务只注册了 1 个 Eureka 服务(9001)

    80 端口的服务被同步到了相互注册的 Eureka 服务(9002)上

    访问 9001 和 9002 的 Erueka,我们可以看到 80 端口这个服务被注册到了 Erueka 集群上

    也就是说 Erueka(多个)会把注册的服务,同步到 Erueka 集群上

    11.创建 member-service-provider-10002

    11-1 新建模块

    11-2 引入依赖(10002 端口中的 pom.xml)

    直接将 10000 端口 的 依赖导入即可

    1. <!-- 引入 eureka-client 依赖 -->
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    5. </dependency>
    6. <!-- 引入 e_commerce_center-common-api -->
    7. <dependency>
    8. <groupId>com.wwf.springcloud</groupId>
    9. <artifactId>e_commerce_center-common-api</artifactId>
    10. <version>${project.version}</version>
    11. </dependency>
    12. <!--SpringBoot版本与父项目一致-->
    13. <dependency>
    14. <groupId>org.springframework.boot</groupId>
    15. <artifactId>spring-boot-starter-web</artifactId>
    16. <!-- 如果在子工程/模块指定了 version,则以指定为准 -->
    17. </dependency>
    18. <!-- 老师解读
    19. 1. starter-actuator 是 springboot 程序的监控系统,
    20. 可以实现健康检查,info 信息等
    21. 2. 访问 http://localhost:10000/actuator 可以看到相关链接, 还可以做相关设置. -->
    22. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
    23. -->
    24. <!-- 指定了监控系统版本-->
    25. <dependency>
    26. <groupId>org.springframework.boot</groupId>
    27. <artifactId>spring-boot-starter-actuator</artifactId>
    28. </dependency>
    29. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
    30. -->
    31. <!-- mybatis-->
    32. <dependency>
    33. <groupId>org.mybatis.spring.boot</groupId>
    34. <artifactId>mybatis-spring-boot-starter</artifactId>
    35. </dependency>
    36. <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    37. <!-- springBoot cloud alibaba-->
    38. <dependency>
    39. <groupId>com.alibaba</groupId>
    40. <artifactId>druid-spring-boot-starter</artifactId>
    41. <!-- 这里我们重新指定一下 version -->
    42. <version>1.1.13</version>
    43. </dependency>
    44. <!-- mysql-->
    45. <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    46. <dependency>
    47. <groupId>mysql</groupId>
    48. <artifactId>mysql-connector-java</artifactId>
    49. </dependency>
    50. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc
    51. -->
    52. <!-- jdbc连接池-->
    53. <dependency>
    54. <groupId>org.springframework.boot</groupId>
    55. <artifactId>spring-boot-starter-jdbc</artifactId>
    56. </dependency>
    57. <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    58. <dependency>
    59. <!-- lombok-->
    60. <groupId>org.projectlombok</groupId>
    61. <artifactId>lombok</artifactId>
    62. <optional>true</optional>
    63. </dependency>
    64. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
    65. <dependency>
    66. <groupId>org.springframework.boot</groupId>
    67. <artifactId>spring-boot-starter-test</artifactId>
    68. <scope>test</scope>
    69. </dependency>
    70. <dependency>
    71. <groupId>junit</groupId>
    72. <artifactId>junit</artifactId>
    73. <version>4.12</version>
    74. </dependency>

    引入后记得刷新

    11-3 创建 resources/application.yml

    将 10000 端口的application.yml 拷贝过来即可,仅修改端口号

    1. server:
    2. port: 10002 #服务端-端口号
    3. spring:
    4. application:
    5. name: member-service-provider #当前模块的项目名称-访问地址必须加上才能够访问
    6. datasource:
    7. type: com.alibaba.druid.pool.DruidDataSource
    8. # driver-class-name: org.gjt.mm.mysql.Driver
    9. #数据库地址:
    10. #jdbc:mysql://域名:端口/数据库名称?useUnicode=true&characterEncoding=utf-8&useSSL=false
    11. url: jdbc:mysql://localhost:3306/e_commerce_center_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
    12. username: root #数据库名称
    13. password: abc123 #数据库密码
    14. #eureka 客户端配置
    15. eureka:
    16. client:
    17. register-with-eureka: true #将自己注册到 EurekaServer
    18. #是否从从 EurekaServer 抓取注册信息,默认为 true, 单节点无所谓,
    19. #集群必须设置为 true 才能配合 ribbon 使用负载均衡
    20. fetchRegistry: true
    21. service-url:
    22. #表示将自己注册到哪个 eurekaServer
    23. defaultZone: http://localhost:9001/eureka
    24. #心断检与续约时间
    25. #如果你希望保证CP,时间间隔可以短一些,保证服务关闭后注册中心能即使剔除服务 instance
    26. #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    27. # lease-renewal-interval-in-seconds: 1
    28. #Eureka服务端在收到最后一次心跳后等待时间上限,单位为种(默认是90秒),超时将剔除服务
    29. # lease-expiration-duration-in-seconds: 2
    30. mybatis:
    31. mapperLocations: classpath:mapper/*.xml #后面 mapper 文件的位置
    32. type-aliases-package: com.wwf.entity #指定POJO扫描包来让mybatis自动扫描到自定义的POJO。

    11-4 创建 memberMapper.xml

    直接将 10000 端口的memberMapper.xml 拷贝过来即可

    11-5 将 10000 端口的 java 源代码拷贝到 10002 即可

    11-6 将 10000 与 100002 的启动类-类名进行修改

    11-7 完成测试

    12.配置服务消费端 member-service-consumer-80 使用会员中心服务集群

    修改 MemberConsumerController.java

    这里是为了使用负载均衡动态的调用服务-通过 Eureka-使用服务别名

    修改 CustomizationBean.java

    为了支持负载均衡,还需要加入 1 个注解

    目前我们已经指定了访问的服务别名和为 RestTemplate 实现了负载均衡的能力

    当我们使用服务别名-访问接口的时候-

    会通过负载均衡(默认轮询调用)

    为了看到通过负载均衡调用,当前访问哪个服务端口的效果,

    我们需要修改一下配置

    完成测试

    访问 10000 和 10002 端口-确保当前端口的接口服务能够正常的被调用

    访问 80 端口-确保当前端口的接口服务能够正常的被调用

    默认使用轮询算法(负载均衡)访问

    第 1 次请求访问的是 10000 端口服务

    第 2 次请求访问的是 10002 端口服务

    DiscoveryClient

    1. @GetMapping(value = "/member/consumer/discovery")
    2. public Object discovery() {
    3. List<String> services = discoveryClient.getServices();
    4. for (String element : services) {
    5. System.out.println("======== 服 务 名 " + element +
    6. "=======================");
    7. List<ServiceInstance> instances = discoveryClient.getInstances(element);
    8. for (ServiceInstance instance : instances) {
    9. System.out.println(instance.getServiceId() + "\t" + instance.getHost()
    10. + "\t" + instance.getPort() + "\t" + instance.getUri());
    11. }
    12. }
    13. return this.discoveryClient;
    14. }

  • 相关阅读:
    cvxpy: Python优化库
    Python编程:《外星人入侵》
    多维时序 | MATLAB实现GWO-LSTM灰狼算法优化长短期记忆神经网络的多变量时间序列预测
    2023年,千万别裸辞....
    Java代码中如何计算HashMap对象中元素个数呢?
    leetcode-两数之和
    MySQL之主从复制(双主双从)
    什么是腾讯云图数据可视化?它有哪些特性以及应用场景?
    小程序实现一个 倒计时组件
    北大肖臻老师《区块链技术与应用》系列课程学习笔记[14]以太坊-状态树2
  • 原文地址:https://blog.csdn.net/wang115t/article/details/136278597