Eureka注册中心

Eureka注册中心

回想我们的第一个SpringCloud项目,我们会发现,我们虽然在里面实现了微服务的思想,但是我们服务与服务之间的耦合度还是非常高的,具体如何体现呢?也就是我们的模块还是会去直接调用不同的模块,这样的耦合度,在之前的开发中我根本就不在乎,但是在spring-cloud任何一个稍微的耦合都是不可容忍的,因此我们在此处提出一种服务关联管理组件,将我们的组件之间的关系进行优质的管理,减少服务之间的耦合,那就是Eureka注册中心,中文名称尤里卡

image-20240507212113071

注册中心是依赖于SpringCloud上下文进行操作理解的!话不多说,我们直接进行应用操作

  • 导入Spring-Cloud依赖(注意,位于MavenManagement中进行操作)
  <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.1</version>
                <type>pom</type>
    		   <scope>import</scope>
</dependency>

注意此处的依赖导入版本操作,是非常标准化的

Springboot与SpringCloud的版本是完全一一对应的

image-20240507214414419

  • 构建注册中心模块

image-20240507211448316

  • 每个服务进行注册中心服务端依赖注入
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency>
  • 配置主类信息
package com.example;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
//开启注册服务标记
@EnableEurekaServer
public class EurekaApplication {
    public static void main(String[] args) {
        //启动相关的Eureka
        SpringApplication.run(EurekaApplication.class, args);
    }
}

  • 配置尤里卡注册中心
server:
	port: 8080
eureka:
  client:
    #关闭服务端获取
    fetch-registry: false
    #不需要将自己注册到尤里卡中心中
    register-with-eureka: false
    #服务URL:进行相关的默认网页请求路径(注册空间路径)
    service-url:
      defaultZone: http://localhost:8080/eureka
  • 配置服务的尤里卡空间路径
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: FBCD
    url: jdbc:mysql://localhost:3306/spring_cloud
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka
  • 注册中心画面

image-20240507212446880

  • 如果存在任何服务下线的情况会直接进行显示

image-20240507212523976

关于不同服务中注册中心中的Name-Speace理解

如果对应的服务没有设置AppLicationName 那么注册中心中会显示Unknown名称

image-20240507213145735

  • 设置Name-Speacing(容器思想不能丢)
spring: 
  application:
    name: readerService

心跳机制

我们将服务注册到对应的注册中心的时候,我们的Eureka会定时的向我们服务发送续约心跳包,用于检测我们的服务是否存活,我们的服务也会对注册中心发送定期心跳来表明自己是存活状态

  • 定期心跳:服务向注册中心发送的心跳
  • 续约心跳:注册中心向服务发送的心跳

image-20240507214040438

基于注册中心的多服务调用操作

  • 远程调用操作
package com.example.service.impl;

import com.example.entities.Books;
import com.example.entities.Readers;
import com.example.entity.BookRelation;
import com.example.entity.BookRelationDetails;
import com.example.mapper.BookRelationMapper;
import com.example.service.BookRelationService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
@Service
public class BookRelationServiceImpl implements BookRelationService {

    @Resource
    BookRelationMapper bookRelationMapper;

    @Resource
    RestTemplate template;

    @Override
    public BookRelationDetails getTheBookRelationDetails(Integer rid) {
        List<BookRelation> theReads = bookRelationMapper.getTheReads(rid);
        Readers readers=template.getForObject("http://localhost:8102/user/"+rid, Readers.class);
        List<Books> booksList= theReads.stream()
                .map(b -> template.getForObject("http://localhost:8100/book/"+b.getBid(), Books.class)).toList();
        return new BookRelationDetails(readers,booksList);
    }

}

我们在之前的调用过程中,我们的不同服务还是以一种URI的形式进行调用操作的,但是这种操作有一种弊端,那就是当我们的服务更换端口或者主机的时候,我们还是需要到对应位置进行更换,这种形式肯定还是不符合低耦合高扩展的理解操作的,那么如何解决这样的操作呢?

利用注册中心,将不同服务以一种ID形式进行标记,如果我们需要进行服务调用,那么我们直接调用Name即可,这是一种命名空间的思想,也是SQL以及spring带给我的思路!

  1. 独立远程调用接口类(实现负载均衡)
package com.example.configuration;


import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class BeanConfig {

    @Bean
    //用于发现服务,将对应的NameSpeacing空间转换为具体的地址,用于实现负载均衡
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

  1. 实现地址解析然后进行相关的操作
   @Override
    public BookRelationDetails getTheBookRelationDetails(Integer rid) {
        List<BookRelation> theReads = bookRelationMapper.getTheReads(rid);
        Readers readers=template.getForObject("http://readerService/user/"+rid, Readers.class);
        List<Books> booksList= theReads.stream()
                .map(b -> template.getForObject("http://bookService/book/"+b.getBid(), Books.class)).toList();
        return new BookRelationDetails(readers,booksList);
    }

注册中心实现多实例负载均衡

我们中心能够实现低耦合操作,但是我们的软件系统仅仅实现低耦合,如果我们的不同服务宕机了怎么办,宕机了我们也没办法进行相关操作了,于是这种情况为我们提出来一个服务的高可用问题,服务如果Down了,到底该怎么办?

解决方法:创建多个实例,如果一个实例DOWN了,我们还有其他的实例进行操作,这样我们就可以实现高可用的方案了

image-20240507221211706

  • 我们的实例主要设置就是通过我们的环境变量,将我们的实例放在不同的端口上进行服务操作,如果我们某个服务Down了我们还有其他端口的服务进行

image-20240507221707570

image-20240507221736609

多实例负载均衡

还记得我们之前对我们远程调用标记的@LoadedBlanced注解吗,这个注解除了解析地址,还有一个作用就是负载均衡,这点子多实例的时候能够尤为体现

  • 我们对读者控制器进行标记
package com.example.controller;


import com.example.entities.Readers;
import com.example.service.ReaderService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;


//浏览器仅仅只返回相关数据进行操作理解
@RestController
public class ReadersController {

    @Resource
    ReaderService readerService;

    //获取所有读者信息的控制器
    @GetMapping("/user/{userId}")
    public Readers getReaders(@PathVariable("userId") Integer userId) {
        System.out.println("服务被调用了");
        return readerService.getReaderService(userId);
    }
}

当我们的服务每次被调用之后,我们的终端都能够显示调用信息,下面我们就从不同的服务中获取相关信息吧

image-20240507222125739

image-20240507222133374

两个实例,分别进行了调用,说明我们的注册中心进行了负载均衡操作

负载均衡:防止一个服务/端口多次调用而形成忙等的情况,分散调用请求,处理了高并发调用情况的瓶颈效应

多实例注册中心

我们上面做了多实例服务的操作以及负载均衡相关的理解操作,我们解决了服务的高可用问题与服务发现问题,那么我们整体的架构是否还存在一些问题呢?当然存在,那就是注册中心的高可用问题,如果我们的注册中心Down了,那我们的所有服务不就没有逻辑链接,甚至是物理链接了吗,那么我们如何解决注册中心的高可用问题呢?

解决方案:多实例注册中心操作,创建多个注册中心进行高可用方案,如果一个注册中心Down了,那么注册中心的服务自动转换到另外的注册中心中,合理!

  • 构建l两个配置文件

eureka:
  client:
    #关闭服务端获取
    fetch-registry: false
#    #不需要将自己注册到尤里卡中心中,此处不需要进行注册中心的操作,删去配置,直接将我们的服务进行对应的注册
#    register-with-eureka: false
    #服务URL:进行相关的默认网页请求路径
    service-url:
      defaultZone: http://eureka01:8080/eureka
  instance:
    hostname: eureka01
server:
  port: 8080
spring:
  application:
    name: eurekaServer1

image-20240507224004366

  • 配置文件2
server:
  port: 8081
spring:
  application:
    name: eurekaServer2
eureka:
#实例化主机名称
  instance:
    hostname: eureka02
  client:
    fetch-registry: false
    service-url:
      defaultZone: http://eureka02:8081/eureka

关于主机路径的配置

Windows-Host设置:C:\Windows\System32\drivers\etc\hosts

image-20240507223510612

  • 将主机配置到对应文件即可
  • 配置环境变量

image-20240507224030341

千万注意此处环境变量激活的位置,而不是有效的配置文件的地方,千万不能混为一谈了,之前就是混为一谈进而浪费多少时光啊!

  • 设置完毕之后我们就能启动我们的最终项目了

image-20240507224540163

  • 不同的注册中心注册不同的服务

image-20240507224610491

image-20240507224624969

  • 一旦有一个服务宕机,另外的服务自动具备宕机的注册中心的服务

image-20240507224716910

这其实就是一种非常优质的负载均衡操作,注册中心是实现了负载均衡操作的!

总结:Eureka注册中心操作,其实是给予了一个非常中心化的服务管理者角色,他能够分派不同的服务进行链接操作,但是中心化必然还是会存在一些问题,多个实例解决,但是总体来说还是没多少效率的,因此我们的Cloud框架已经将此组件进行过时处理了!但是值得我们去学习其中的思维,后续会理解新的组件,任重道远啊同志!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值