04.搭建EurekaServer集群-实现负载均衡&故障容错
为什么需要集群Eureka server
示意图
解读
引入Eureka server 集群项目架构剖析
示意图
搭建Eureka server 集群
创建e-eommerce-eureka-server-9002 微服务模块[作为注册中心]
- 创建步骤参考e-eommerce-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.hspedu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>e-eommerce-eureka-server-9002</artifactId>
<!-- 引入相关的依赖-->
<dependencies>
<!-- 引入eureka-server 场景启动器starter:使用版本仲裁-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引入web-starter 我们指定版本仲裁(从父项目继承了版本)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 说明:starter-actuator 是springboot程序的监控系统,可以实现系统的监控检测
可以通过http://localhost:9002/actuator 看到相关的连接,和信息
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- starter-test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 引入e_commerce_center-common-api-->
<dependency>
<groupId>com.hspedu.springcloud</groupId>
<artifactId>e_commerce_center-common-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
- 创建resources/application.yml
server:
port: 9002
# 配置eureka-server
eureka:
instance:
hostname: eureka9002.com # 服务实例名
client:
# 配置不向注册中心注册自己
register-with-eureka: false
# 表示自己就是注册中心,作用就是维护注册服务实例,不需要去检索服务
fetch-registry: false
service-url:
#这里注册到eureka9001 server
defaultZone: http://eureka9001.com:9001/eureka/
# server:
# # 禁用自我保护模式
# enable-self-preservation: false
# # 设置超时时间2秒,在2秒钟收不到心跳包,就认为是超时
# eviction-interval-timer-in-ms: 2000
- 创建主启动类EurekaApplication9002.java
package com.hspedu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class eurekaApplication9002 {
public static void main(String[] args) {
SpringApplication.run(eurekaApplication9002.class,args);
}
}
修改e-eommerce-eureka-server-9001 微服务模块
- 修改resources/application.yml
eureka:
instance:
hostname: eureka9001.com # 服务实例名
- 修改主启动类名为EurekaApplication9001
修改hosts文件
-
修改文件:C:\Windows\System32\drivers\etc\hosts
-
添加
-
配置eureka 主机和ip的映射
-
127.0.0.1 eureka9001.com
127.0.0.1 eureka9002.com
-
完成测试
启动EurekaApplication9001
启动eurekaApplication9002
浏览器:http://eureka9001.com:9001/
浏览器:http://eureka9002.com:9002/
将member-service-provider-10000注册到Eureka server 集群(目前两台)
#配置eureka-client
eureka:
client:
register-with-eureka: true # 将自己注册到 Eureka-server
# 表示从 Eureka-server 抓取注册信息
# 如果是单节点,是可以不配置的,但是如果是一个集群,则必须配置true
# 才能配合Ribbon使用负载均衡
fetch-registry: true
service-url:
# defaultZone: http://localhost:9001/eureka/
# 表示将自己注册到哪个eureka-server
# 将本微服务注册到多个eureka-server,只有逗号间隔即可
defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/
将member-service-consumer-80注册到EurekaServer集群(目前两台)
#配置eureka-client
eureka:
client:
register-with-eureka: true # 将自己注册到 Eureka-server
# 表示从 Eureka-server 抓取注册信息
# 如果是单节点,是可以不配置的,但是如果是一个集群,则必须配置true
# 才能配合Ribbon使用负载均衡
fetch-registry: true
service-url:
# defaultZone: http://localhost:9001/eureka/
# 表示将自己注册到哪个eureka-server
# 将本微服务注册到多个eureka-server,只有逗号间隔即可
defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/
搭建会员中心服务提供方-集群
示意图
创建member-service-provider-10002
- 目录文件拷贝member-service-provider-10000
创建resources/application.yml
server:
port: 10002
spring:
application:
name: member-service-provider-10002 #配置应用的名称
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml #指定mapper.xml文件位置
type-aliases-package: com.hspedu.springcloud.entity #实体类所在的包,这样通过类名可以引用
#配置eureka-client
eureka:
client:
register-with-eureka: true # 将自己注册到 Eureka-server
# 表示从 Eureka-server 抓取注册信息
# 如果是单节点,是可以不配置的,但是如果是一个集群,则必须配置true
# 才能配合Ribbon使用负载均衡
fetch-registry: true
service-url:
# 表示将自己注册到哪个eureka-server
# 将本微服务注册到多个eureka-server,只有逗号间隔即可
# defaultZone: http://localhost:9001/eureka/
defaultZone: http://eureka9001.com:9001/eureka/,http://eureka9002.com:9002/eureka/
# instance:
# # 客户端向服务器发送心跳的间隔 1s(默认30s)
# lease-renewal-interval-in-seconds: 1
# # 服务端收到最后一次心跳后等待的时间上线
# # 时间单位(秒),默认是90秒,超时将删除服务
# lease-expiration-duration-in-seconds: 2
修改主启动类名
修改member-service-provider-10000 的主启动类名:MemberApplication10000
修改member-service-provider-10002的主启动类名:MemberApplication10002
完成测试
启动 MemberApplication10000
启动 MemberApplication10002
浏览器:http://eureka9001.com:9001/
浏览器:http://eureka9002.com:9002/
注意事项和细节
- 修改member-service-provider-10000 的yml文件
spring:
application:
name: member-service-provider #配置应用的名称
- 修改member-service-provider-10002 的yml文件
spring:
application:
name: member-service-provider #配置应用的名称
-
完成测试
-
启动 MemberApplication10000
-
启动 MemberApplication10002
-
浏览器:http://eureka9001.com:9001/
-
浏览器:http://eureka9002.com:9002/
-
配置服务消费端member-service-consumer-80 使用会员中心服务集群
示意图
修改MemberConsumerController
// 定义member_service_provider_url 这是一个基础url地址
/**
* 1.MEMBER-SERVICE-PROVIDER 就是服务提供方[集群],注册到Eureka Server 的名称
* 2.也就是服务提供方[集群]对外暴露的名称为 MEMBER-SERVICE-PROVIDER
* 3.MEMBER-SERVICE-PROVIDER 目前有两个 Availability Zones
* member-service-provider-10000 还有一个 member-service-provider-10002
* 需要增加一个注解@LoadBalanced 赋予 RestTemplate 负载均衡的能力,也就是根据
* 你的负载均衡算法来选择某个服务访问,默认是轮询算法,当然我们也可以自己配置负载均衡算法
*/
public static final String MEMBER_SERVICE_PROVIDER_URL =
"http://MEMBER-SERVICE-PROVIDER"; //后面这里地方会修改成提供服务模块的注册别名
修改CustomizationBean
// 配置注入RestTemplate bean/对象
// 这里的@LoadBalanced 就是赋予RestTemplate 负载均衡的能力
// 默认是使用轮询算法来访问远程调用接口
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
为了看到测试效果,修改服务提供方
- 修改member-service-provider-10000 的查询接口
// 查询接口
@GetMapping("member/get/{id}")
public Result getMemberById(@PathVariable Long id) {
Member member = memberService.queryMemberById(id);
if (member != null) {
return Result.success("查询会员成功 member-service-provider-10000", member);
} else {
return Result.error("402", "ID=" + id + "不存在");
}
}
- 修改member-service-provider-10002 的查询接口
// 查询接口
@GetMapping("member/get/{id}")
public Result getMemberById(@PathVariable Long id) {
Member member = memberService.queryMemberById(id);
if (member != null) {
return Result.success("查询会员成功 member-service-provider-10002", member);
} else {
return Result.error("402", "ID=" + id + "不存在");
}
}
完成测试
http://localhost:81/member/consumer/get/2
交替访问member服务说明
- 注解@LoadBanlanced 底层是Ribbon支持算法
- Ribbon和Eureka整合后consumer直接调用服务而不用再关心地址和端口号,且该服务还有负载功能
获取Eureka Server 服务注册信息-DiscoveryClient
需求分析示意图
代码实现
添加代码 MemberConsumerController
// 装配DisoveryClient
@Resource
private DiscoveryClient discoveryClient;
@GetMapping("member/consumer/discovery")
public Object discovery(){
List<String> services = discoveryClient.getServices();
for (String service : services) {
log.info("服务名={}",service);
List<ServiceInstance> instances = discoveryClient.getInstances(service);
for (ServiceInstance instance : instances) {
log.info("id{},host={},port={},uri={}",instance.getServiceId(),instance.getHost(),instance.getPort(),instance.getUri());
}
}
return discoveryClient;
}
MemberConsumerApplication 添加注解
@EnableDiscoveryClient // 启用服务发现
@EnableEurekaClient
@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现
public class MemberConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(MemberConsumerApplication.class,args);
}
}
测试
http://localhost:81/member/consumer/discovery