Eureka注册中心
回想我们的第一个SpringCloud项目,我们会发现,我们虽然在里面实现了微服务的思想,但是我们服务与服务之间的耦合度还是非常高的,具体如何体现呢?也就是我们的模块还是会去直接调用不同的模块,这样的耦合度,在之前的开发中我根本就不在乎,但是在spring-cloud任何一个稍微的耦合都是不可容忍的,因此我们在此处提出一种服务关联管理组件,将我们的组件之间的关系进行优质的管理,减少服务之间的耦合,那就是Eureka注册中心,中文名称尤里卡
注册中心是依赖于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的版本是完全一一对应的
- 构建注册中心模块
- 每个服务进行注册中心服务端依赖注入
<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
- 注册中心画面
- 如果存在任何服务下线的情况会直接进行显示
关于不同服务中注册中心中的Name-Speace理解
如果对应的服务没有设置AppLicationName 那么注册中心中会显示Unknown名称
- 设置Name-Speacing(容器思想不能丢)
spring:
application:
name: readerService
心跳机制
我们将服务注册到对应的注册中心的时候,我们的Eureka会定时的向我们服务发送续约心跳包,用于检测我们的服务是否存活,我们的服务也会对注册中心发送定期心跳来表明自己是存活状态
- 定期心跳:服务向注册中心发送的心跳
- 续约心跳:注册中心向服务发送的心跳
基于注册中心的多服务调用操作
- 远程调用操作
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带给我的思路!
- 独立远程调用接口类(实现负载均衡)
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();
}
}
- 实现地址解析然后进行相关的操作
@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了,我们还有其他的实例进行操作,这样我们就可以实现高可用的方案了
- 我们的实例主要设置就是通过我们的环境变量,将我们的实例放在不同的端口上进行服务操作,如果我们某个服务Down了我们还有其他端口的服务进行
多实例负载均衡
还记得我们之前对我们远程调用标记的@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);
}
}
当我们的服务每次被调用之后,我们的终端都能够显示调用信息,下面我们就从不同的服务中获取相关信息吧
两个实例,分别进行了调用,说明我们的注册中心进行了负载均衡操作
负载均衡:防止一个服务/端口多次调用而形成忙等的情况,分散调用请求,处理了高并发调用情况的瓶颈效应
多实例注册中心
我们上面做了多实例服务的操作以及负载均衡相关的理解操作,我们解决了服务的高可用问题与服务发现问题,那么我们整体的架构是否还存在一些问题呢?当然存在,那就是注册中心的高可用问题,如果我们的注册中心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
- 配置文件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
- 将主机配置到对应文件即可
- 配置环境变量
千万注意此处环境变量激活的位置,而不是有效的配置文件的地方,千万不能混为一谈了,之前就是混为一谈进而浪费多少时光啊!
- 设置完毕之后我们就能启动我们的最终项目了
- 不同的注册中心注册不同的服务
- 一旦有一个服务宕机,另外的服务自动具备宕机的注册中心的服务
这其实就是一种非常优质的负载均衡操作,注册中心是实现了负载均衡操作的!
总结:Eureka注册中心操作,其实是给予了一个非常中心化的服务管理者角色,他能够分派不同的服务进行链接操作,但是中心化必然还是会存在一些问题,多个实例解决,但是总体来说还是没多少效率的,因此我们的Cloud框架已经将此组件进行过时处理了!但是值得我们去学习其中的思维,后续会理解新的组件,任重道远啊同志!