SpringCloud Eureka学习记录
微服务
微服务的定义
简单来说微服务就是一种将单一应用程序拆分为一小组小型服务的方法,拆分完成后,每一个服务都运行在独立的进程中,服务与服务之间采用轻量级的通信进行沟通
为什么要用微服务
互联网应用产品的两大特点:
1、需求变化快
2、用户群体大
综上,使用传统的开发方式已经无法满足需求,需要一个能够灵活扩展,快读应对外部环境的应用
微服务的优势
复杂度可控 ,独立部署,技术选型灵活,较好的容错性,较强的可扩展性
SpringCloud概述
什么是SpringCloud
SpringCloud内部包含许多框架,这些框架互相协作,共同构建分布式系统
核心特性
服务注册与发现,负载均衡,服务之间调用,容错,服务降级,熔断器,消息总线,分布式配置中心
Eureka
Eureka是SpringCloud的注册中心
Eureka的组成部分
服务端
- 注册中心,用来接收其他服务的注册
客户端
- 客户端是一个java客户端,用来注册,并可以实现负载均衡等功能
Eureka的三个角色
Eureka Server:注册中心
- Eureka 服务器是服务注册中心,它负责维护服务提供者和服务消费者的信息。所有的服务提供者都向 Eureka 服务器注册自己的信息,而服务消费者则可以从 Eureka 服务器获取服务提供者的信息。
Eureka Provider:服务提供者
- 服务提供者是一个运行中的微服务应用,它将自己注册到 Eureka 服务器,以便其他服务能够发现和调用它。服务提供者向 Eureka 服务器发送心跳以表明其健康状态,并定期更新自己的信息,比如IP地址、端口号等。
Eureka Consumer :服务消费者
- 服务消费者是依赖某个服务的微服务应用。它通过 Eureka 服务器来查找需要调用的服务提供者的信息,以便发起请求。
搭建Eureka服务端
在启动类上添加
@EnableEurekaServer
注解来启用Euerka
注册中心功能@EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
添加配置文件
# 给当前服务取一个名字 spring.application.name=eureka
设置端口号
server.port=1111 eureka.client.register-with-eureka=false # 表示是否从 Eureka Server 上获取注册信息 eureka.client.fetch-registry=false
出现此界面即为搭建成功
搭建Eureka客户端
1、添加pom.xml依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、在main方法添加@EnableDiscoveryClient注解
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
3、application.properties添加配置文件
server.port=1114
spring.application.name=eureka-client
eureka.client.service-url.defaultZone=http://localhost:1111/eureka
出现以下界面则为成功
搭建Eureka注册中心集群
由于所有服务都会注册到注册中心去,服务之间的调用都是通过从注册中心获取的服务列表来调用,注册中心一旦宕机,所有服务调用都会出现问题。所以我们需要多个注册中心组成集群来提供服务,下面将搭建一个双节点的注册中心集群。
1、 修改hosts
新建两个配置文件
配置文件a
# 给当前服务取一个名字 spring.application.name=eureka # 设置端口号 server.port=1111 eureka.instance.hostname=eureka1 eureka.client.register-with-eureka=true # 表示是否从 Eureka Server 上获取注册信息 eureka.client.fetch-registry=true # A 服务要注册到 B 上面 eureka.client.service-url.defaultZone=http://eureka2:1112/eureka
配置文件b
# 给当前服务取一个名字 spring.application.name=eureka # 设置端口号 server.port=1112 eureka.instance.hostname=eureka2 eureka.client.register-with-eureka=true # 表示是否从 Eureka Server 上获取注册信息 eureka.client.fetch-registry=true # A 服务要注册到 B 上面 eureka.client.service-url.defaultZone=http://eureka1:1111/eureka
运行两个实例
Eureka 的工作细节
Eureka 服务器(Server)的功能:
服务注册表管理:
服务器记录所有已注册的服务实例的信息,以供其他服务查询。
服务注册信息存储:
服务器保存服务实例的注册信息,以便快速响应查询请求。
服务实例健康检查:
服务器定期检查服务实例的心跳信息,确保它们正常工作。
服务实例信息同步:
服务器把服务实例的变化通知给客户端,保持注册表的最新状态。
自我保护机制:
服务器在与大多数客户端通信故障时,保护注册表中的服务实例,防止服务之间完全失联。
Eureka 客户端(Client)的功能:
- 服务注册:
客户端将自己的服务信息告诉服务器,让其他服务可以找到它。
心跳和续约:
客户端定期向服务器发送信号,表明它还活着。让服务器就知道实例还在运行,并保持最新的信息。
服务下线:
客户端通知服务器,自己即将关闭或停止服务,服务器将把它从列表中移除。
服务发现
客户端向服务器询问需要访问的其他服务的信息,服务器返回可用的服务实例。
服务注册与消费
服务注册
- 服务提供者在启动时会向 Eureka 服务器发送注册请求,包含自身的服务名称、主机名、端口号等信息。Eureka 服务器会将这些信息记录在注册表中,并为服务提供者分配一个唯一的标识符(通常是服务实例的ID)。这样,其他服务消费者可以通过查询 Eureka 服务器来获取服务提供者的信息,并与其进行通信。
服务消费
- 服务消费者通过向 Eureka 服务器发送查询请求,获取需要访问的服务提供者的信息。Eureka 服务器返回一个或多个可用的服务实例给服务消费者。然后,服务消费者可以使用这些信息来建立与服务提供者的通信连接,并发送请求获取所需的数据或执行相应的操作。
示例
服务注册端:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello javaboy";
}
}
服务调用端:
controller
@RestController
public class ConsumController {
@Autowired
@Qualifier("restTemplate")
RestTemplate restTemplate;
@GetMapping("/hello3")
public String hello3() {
return restTemplate.getForObject("http://eureka-client/hello", String.class);
}
}
启动类
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaConsumApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumApplication.class, args);
}
@Bean
RestTemplate restTemplateOne() {
return new RestTemplate();
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
运行结果