SpringCloud之Eureka注册中心与Robbin负载均衡(二)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
网络型负载均衡 NLB,每月750个小时 15LCU
简介: SpringCloud之Eureka注册中心与Robbin负载均衡(二)

编写服务(客户端)


编写班级服务 服务提供方(9010)


步骤一:编写项目(服务),cloud-classes-service-1007微信图片_20220526124947.png

步骤二:修改pom.xml文件,添加 eureka client依赖

<dependencies>
    <!--web起步依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Eureka客户端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--spring boot监控(可选)-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

步骤三:创建yml文件,确定eureka注册中心的位置

server:
  port: 9010
spring:
  application:
    name: classes-service
eureka:
  client:
    service-url: #注册中心位置
      defaultZone: http://localhost:10086/eureka/
  instance: #web页面显示效果和访问路径
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true

步骤四:编写启动类,添加注解

微信图片_20220526124957.png

package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ClassesApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClassesApplication.class,args);
    }
}

步骤五:启动项目,并测试微信图片_20220526125005.png

步骤六:提供查询所有班级

package com.czxy.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/classes")
public class ClassesController {
    @GetMapping
    public List<String> findAll(){
        List<String> list = new ArrayList<>();
        list.add("Java12班");
        list.add("Java34班");
        return list;
    }
}

微信图片_20220526125011.png

编写学生服务 服务调用方(9020)


步骤一:编写项目(服务),cloud-student-service-1007微信图片_20220526125018.png


步骤二:修改pom.xml文件, (和eureka_service一样)

<dependencies>
    <!--web起步依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Eureka客户端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--spring boot监控(可选)-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

步骤三:创建yml文件

server:
  port: 9020
spring:
  application:
    name: student-service
eureka:
  client:
    service-url: #注册中心位置
      defaultZone: http://localhost:10086/eureka/
  instance: #web页面显示效果和访问路径
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true

步骤四:编写启动类

微信图片_20220526125027.png

package com.czxy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class StudentApplication {
    public static void main(String[] args) {
        SpringApplication.run(StudentApplication.class,args);
    }
}

步骤五:启动,并测试微信图片_20220526125036.png


功能:学生服务调用班级服务


步骤一:编写HttpConfig,用于配置RestTemplate微信图片_20220526125048.png

package com.czxy.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class HttpConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

步骤二:编写ClassesDao,完成远程调用微信图片_20220526125103.png

package com.czxy.dao;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@Repository
public class ClassesDao {
    @Resource
    private RestTemplate restTemplate;
    @GetMapping
    public List<String> findAll(){
        ResponseEntity<List> entity = restTemplate.getForEntity("http://localhost:8082/classes", List.class);
        List<String> list = entity.getBody();
        return list;
    }
}

步骤三:编写StudentService,调用ClassesDao微信图片_20220526125110.png

package com.czxy.service;
import com.czxy.dao.ClassesDao;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class StudentService {
    @Resource
    private ClassesDao classesDao;
    public List<String> findAll() {
        return classesDao.findAll();
    }
}

步骤四:编写StudentController,调用StudentService直接显示数据

微信图片_20220526125949.png

package com.czxy.controller;
import com.czxy.service.StudentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/student")
public class StudentController {
    @Resource
    private StudentService studentService;
    @GetMapping
    public List<String> findAll(){
        return studentService.findAll();
    }
}

步骤五:测试微信图片_20220526130134.png

优化:服务调用


修改HttpConfig类,使RestTemplate支持通过服务名调用微信图片_20220526130227.png

修改Dao,使用服务名调用微信图片_20220526130234.png

@GetMapping
public List<String> findAll(){
    ResponseEntity<List> entity = restTemplate.getForEntity("http://classes-service/classes", List.class);
    List<String> list = entity.getBody();
    return list;
}

Eureka高级


优化集群:高可用的Eureka Server


Eureka Server即服务的注册中心,在刚才的案例中,我们只有一个Eureka Server,事实上Eureka Server也可以是一个集群,形成高可用的Eureka中心。


服务同步

多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。


动手搭建高可用的EurekaServer微信图片_20220526130242.png


我们假设要搭建两条EurekaServer的集群,端口分别为:10086和10087

步骤一:分别为两个端口配置yml文件

微信图片_20220526130248.png

application-10086.yml 配置

# 端口号
server:
  port: 10086
# 服务名称
spring:
  application:
    name: cloud-eureka-1007
# eureka的配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10087/eureka/  # 注册中心的地址
    register-with-eureka: true       # 是否注册自己的信息到注册中心,默认是true
    fetch-registry: true             # 是否拉取其它服务的信息,默认是true

application-10087.yml 配置

# 端口号
server:
  port: 10087
# 服务名称
spring:
  application:
    name: cloud-eureka-1007
# eureka的配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka/  # 注册中心的地址
    register-with-eureka: true       # 是否注册自己的信息到注册中心,默认是true
    fetch-registry: true             # 是否拉取其它服务的信息,默认是true

所谓的高可用注册中心,其实就是把EurekaServer自己也作为一个服务进行注册,这样多个EurekaServer之间就能互相发现对方,从而形成集群。因此我们做了以下修改:


  • 删除了register-with-eureka=false和fetch-registry=false两个配置。因为默认值是true,这样就会吧自己注册到注册中心了。
  • 把service-url的值改成了另外一台EurekaServer的地址,而不是自己

步骤二:配置启动器

-Dspring.profiles.active=10086

微信图片_20220526130257.png微信图片_20220526130851.png

步骤三:测试

注意:10086端口启动后,将一直报错,再等待10087端口,10087启动后错误消失

微信图片_20220526130305.png

微信图片_20220526130953.png

步骤四:将“classes-service”注册到10086,将自动同步到10087微信图片_20220526130959.png

步骤七:手动将服务注册到Eureka集群

因为EurekaServer不止一个,可以通过service-url设置多个注册地址

eureka:
  client:
    service-url: #注册中心位置,多个地址以','隔开
      defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka

微信图片_20220526131302.png

优化:服务提供者配置


服务提供者要向EurekaServer注册服务,并且完成服务续约等工作。


服务注册

服务提供者在启动时,会检测配置属性中的:eureka.client.register-with-erueka=true参数是否正确,事实上默认就是true。如果值确实为true,则会向EurekaServer发起一个Rest请求,并携带自己的元数据信息,完成注册操作。


服务续约

在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起Rest请求),告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew);


有两个重要参数可以修改服务续约的行为:

eureka:
  client:
    lease-renewal-interval-in-seconds: 5   #服务续约(renew)的间隔,默认值90秒
    lease-expiration-duration-in-seconds: 10  #服务失效时间,默认为30秒
  • lease-expiration-duration-in-seconds:服务失效时间,默认值90秒
  • lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒

也就是说,默认情况下每个30秒服务会向注册中心发送一次心跳,证明自己还活着。如果超过90秒没有发送心跳,EurekaServer就会认为该服务宕机,会从服务列表中移除,这两个值在生产环境不要修改,默认即可。/


但是在开发时,这个值有点太长了,经常我们关掉一个服务,会发现Eureka依然认为服务在活着。所以我们在开发阶段可以适当调小。

server:
  port: 8080
spring:
  application:
    name: service
eureka:
  client:
    service-url: #注册中心位置
      defaultZone: http://localhost:10086/eureka/
  instance: #web页面显示效果和访问路径
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 5  #5秒一次心跳
    lease-expiration-duration-in-seconds: 10  #10秒及过期

微信图片_20220526131522.png

优化:服务消费者配置


获取服务列表

当服务消费者启动是,会检测eureka.client.fetch-registry=true参数的值,如果为true,则会从Eureka Server服务的列表只读备份,然后缓存在本地。并且每隔30秒会重新获取并更新数据。我们可以通过下面的参数来修改:

eureka:
  client:
    registry-fetch-interval-seconds: 5
server:
  port: 9090
spring:
  application:
    name: client
eureka:
  client:
    service-url: #注册中心位置
      defaultZone: http://localhost:10087/eureka/
    registry-fetch-interval-seconds: 5 #从注册中心,获得列表的间隔时间
  instance: #web页面显示效果和访问路径
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true

微信图片_20220526131645.png生产环境中,我们不需要修改这个值。


但是为了开发环境下,能够快速得到服务的最新状态,我们可以将其设置小一点。


注册中心优化:失效剔除和自我保护


服务端配置


eureka.server.enable-self-preservation ,是否开启自我保护模式,默认为true。


eureka.server.eviction-interval-timer-in-ms, 清理无效节点的时间间隔,默认60000毫秒

# eureka的配置
eureka:
  server:
    enable-self-preservation: true #是否开启自我保护模式
    eviction-interval-timer-in-ms: 4000 # 清理无效节点的时间间隔

微信图片_20220526131806.png

失效剔除

有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。


可以通过eureka.server.eviction-interval-timer-in-ms参数对其进行修改,单位是毫秒,生成环境不要修改。


这个会对我们开发带来极大的不变,你对服务重启,隔了60秒Eureka才反应过来。开发阶段可以适当调整,比如10S

# eureka的配置
eureka:
  server:
  eviction-interval-timer-in-ms: 4000 # 清理无效节点的时间间隔(缺省为60*1000ms)

自我保护


我们关停一个服务,就会在Eureka面板看到一条警告:


这是触发了Eureka的自我保护机制。当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例是否超过了85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。


但是这给我们的开发带来了麻烦, 因此开发阶段我们都会关闭自我保护模式:

# eureka的配置
eureka:
  server:
    enable-self-preservation: true #是否开启自我保护模式(缺省为true)

优化总结微信图片_20220526132007.png

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
负载均衡 算法 Java
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
|
4月前
|
NoSQL Java Nacos
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
SpringCloud集成Seata并使用Nacos做注册中心与配置中心
128 3
|
2天前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
13 5
|
2月前
|
负载均衡 Java 对象存储
负载均衡策略:Spring Cloud与Netflix OSS的最佳实践
负载均衡策略:Spring Cloud与Netflix OSS的最佳实践
46 2
|
1月前
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
55 0
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
3月前
|
负载均衡 监控 Java
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
|
4月前
|
负载均衡 Java Spring
Spring cloud gateway 如何在路由时进行负载均衡
Spring cloud gateway 如何在路由时进行负载均衡
474 15
|
3月前
|
缓存 Java Maven
SpringCloud基于Eureka的服务治理架构搭建与测试:从服务提供者到消费者的完整流程
Spring Cloud微服务框架中的Eureka是一个用于服务发现和注册的基础组件,它基于RESTful风格,为微服务架构提供了关键的服务注册与发现功能。以下是对Eureka的详细解析和搭建举例。
|
4月前
|
负载均衡 Java 微服务
深入理解Spring Cloud中的服务发现与注册
深入理解Spring Cloud中的服务发现与注册