微服务笔记之Eureka(1)
1、Eureka是什么?
Eureka由Netflix开源,并被Pivatal集成到SpringCloud体系中,它是基于 RestfulAPI 风格开发的服务注册与发现组件,它是一个服务注册中心。
服务注册中心本质上是为了解耦服务提供者和服务消费者。
在服务注册中心之前,服务消费者调用服务提供者,会把服务提供者的url地址硬编码到代码中(代码如下),这样做的坏处是不方便后期维护,以及不知道服务提供者的状态信息。
@RestController
@RequestMapping("/page")
public class PageController {
@Resource
private RestTemplate restTemplate;
@GetMapping("/query/{id}")
public Products getProductById(@PathVariable int id){
Products products = restTemplate.getForObject("http://localhost:9999/product/query/" + id, Products.class);
return products;
}
}
2、服务注册中心如何解耦?
分布式微服务架构中服务注册中心用于存储服务提供者地址信息、服务发布相关的属性信息,消费者通过主动查询和被动通知的方式获取服务提供者的地址信息,而不再需要通过硬编码方式得到提供者的
地址信息。消费者只需要知道当前系统发布了那些服务,而不需要知道服务具体存在于什么位置, 这就是透明化路由。如下图:
上图说明:
- 服务提供者、服务消费者启动
- 服务提供者将相关服务信息主动注册到注册中心
- 服务消费者获取服务注册信息:服务消费者直接调用服务提供者
- pull模式:服务消费者可以主动拉取可用的服务提供者清单
- push模式:服务消费者订阅服务(当服务提供者有变化时,注册中心也会主动推送更新后的服务清单给消费者
- 服务消费者直接调用服务提供者
注册中心也需要完成服务提供者的健康监控,当发现服务提供者失效时需要及时剔除;
3、那么讲完服务注册中心,我们来看看Eureka的基础架构
Eureka交互流程
Eureka 包含两个组件:Eureka Server 和 Eureka Client,Eureka Client是一个Java客户端,用于简化与Eureka Server的交互;Eureka Server提供服务发现的能力,各个微服务启动时,会通过EurekaClient向Eureka Server 进行注册自己的信息(例如网络信息),Eureka Server会存储该服务的信息;
- Application Service作为服务提供者向Eureka Server中注册服务,Eureka Server接受到注册事件会在集群和分区中进行数据同步,ApplicationClient作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信息,进行服务调用。
- 微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒,默认Eureka Server 90S会将还没有续约的给剔除)以续约自己的信息
- Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)
- 每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务 注册列表的同步
- Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者
总之,Eureka通过心跳检测、健康检查和客户端缓存等机制,提高系统的灵活性、可伸缩性和高可用性。
4、Eureka服务端详解
4.1、服务下线
当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer
服务中心接收到请求后,将该服务置为下线状态
4.2、失效剔除
Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进行检查,如果发现实例在一定时间(此值由客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到心跳,则会注销此实例
4.3、自我保护机制
自我保护模式正是一种针对网络异常波动的安全保护措施,使用自我保护模式能使Eureka集群更加的健壮、稳定的运行。自我保护机制的工作机制是:如果在15分钟内超过85%的客户端节点都没有正常心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现一下几种情况:
- Eureka Server不再从注册列表中移除,因为长时间没收到心跳而应该过期的服务
- Eureka Server仍然能够接收新服务的注册和查询请求,但是不会被同步到其他节点上,保证当前节点依然可用
- 当网络稳定时,当前Eureka Server新的注册信息会被同步到其他节点中
- 当我们导入eureka-client依赖坐标,配置Eureka服务注册中心地址
- 服务在启动时会向注册中心发起注册请求,并携带服务元数据信息
- Eureka注册中心会把服务的信息保存在Map中(ConcurrentHashMap)
5.2、服务续约详解(服务提供者)
服务每隔30s回向注册中心续约一次,如果没有续约,租约在90s后到期,然后服务会被失效。每隔30s的续约操作我们称之为心跳检测。
- Eureka Client:30s续约一次,在Eureka Server更新自己的状态(Client端进行配置)
- Eureka Server:90s还没有进行续约,将该微服务实例从服务注册表(Map)剔除(Client端进行配置)
- Eureka Client: 30s拉取服务最新的注册表并缓存到本地(Client端进行配置)
通过以下配置
#向Eureka服务中心集群注册服务
eureka:
instance:
# 租约续约间隔时间,默认30秒
lease-renewal-interval-in-seconds: 30
# 租约到期,服务时效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列 表移除
lease-expiration-duration-in-seconds: 90
5.3、获取服务列表详解
每个30s服务会从注册中心拉取一份服务列表,这个时间可以通过配置修改。但往往不需要我们调整
- 服务消费者启动时,从Eureka Server服务列表获取只读备份,缓存到本地
- 每隔30s会重新获取并更新数据
- 每隔30s可以通过配置eureka.client.registry-fetch-interval-seconds修改
#向Eureka服务中心集群注册服务
eureka:
client:
# 每隔多久拉取一次服务列表
registry-fetch-interval-seconds: 30
6、Eureka的元数据
Eureka元数据有两种:标准元数据和自定义元数据
6.1、标准元数据
它包含主机名、IP地址、端口号等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用
6.2、自定义元数据
它可以使用eureka.instance.metadata-map配置,符合KEY/VALUE的存储格式。这些元数据可以在远程客户端中访问
通过以下代码调试获取
@RestController
@RequestMapping("/metadata")
public class MetaDataController { @Resource
private DiscoveryClient discoveryClient; @GetMapping("/show")
public Map<String,String> getMetaData(){
List<ServiceInstance> instances = discoveryClient.getInstances("hy-service-product");
ServiceInstance serviceInstance = instances.get(0);
Map<String, String> metadata = serviceInstance.getMetadata();
return metadata;
}
}
7、Eureka的应用
项目结构
第一步、在父目录的pom文件中引入下面内容
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.1.6.RELEASE</version>
</parent>
其中dependency里面的version内容要和parent里面的version要对应,否则会报错
第二步:在两个Eureka服务的pom文件引入
<!--引入Eureka Server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
第三步:配置Eureka服务下面的yml文件(记得服务端口号要修改)
server:
port: 11111
spring:
application:
name: hy-cloud-eureka-server # 应用名称,会在Eureka中作为服务的id标识(serviceId)
eureka:
instance:
hostname: HyCloudEurekaServiceA
client:
service-url: # 客户端与EurekaServer交互的地址,如果是集群,也需要写其它Server的地址
defaultZone: http://HyCloudEurekaServiceB:22222/eureka/
register-with-eureka: true # 自己就是服务不需要注册自己
fetch-registry: true #自己就是服务不需要从Eureka Server获取服务信息,默认为true,置为false
第四步:启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication { public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
第五步:配置两个微服务下的yml文件
page:
server:
port: 8888 # 后期该微服务多实例,端口从9100递增(10个以内)
Spring:
application:
name: hy-service-page
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/hy?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: "root"
password: "123456"
eureka:
client:
serviceUrl: # eureka server的路径
defaultZone: http://HyCloudEurekaServiceA:11111/eureka/,http://HyCloudEurekaServiceB:22222/eureka/
instance:
#使用ip注册,否则会使用主机名注册了(此处考虑到对老版本的兼容,新版本经过实验都是ip)
prefer-ip-address: true
#自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddress
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
product:
server:
port: 9999 # 后期该微服务多实例,端口从9100递增(10个以内)
Spring:
application:
name: hy-service-product
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/hy?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: "root"
password: "123456"
eureka:
client:
serviceUrl: # eureka server的路径
defaultZone: http://HyCloudEurekaServiceA:11111/eureka/,http://HyCloudEurekaServiceB:22222/eureka/
instance:
#使用ip注册,否则会使用主机名注册了(此处考虑到对老版本的兼容,新版本经过实验都是ip)
prefer-ip-address: true
#自定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddress
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
第六步:编写Product的Controller
@RestController
@RequestMapping("/product")
public class ProductController { @Resource
private ProductService productService; @RequestMapping("/query/{id}")
public Products query(@PathVariable Integer id){
return productService.findById(id);
}
}
此处省略service代码
第七步:编写Page微服务的Controller
@RestController
@RequestMapping("/page")
public class PageController {
@Resource
private RestTemplate restTemplate; @Resource
private DiscoveryClient discoveryClient; @GetMapping("/query/{id}")
public Products getProductById(@PathVariable int id){
List<ServiceInstance> instances = discoveryClient.getInstances("hy-service-product");
System.out.println(instances);
ServiceInstance serviceInstance = instances.get(0);
String host = serviceInstance.getHost();
int port = serviceInstance.getPort();
System.out.println(host + " " + port);
String url = "http://"+host +":" + port +"/product/query/" + id;
Products products = restTemplate.getForObject(url, Products.class);
return products;
}
}
第八步:启动四个服务:随便登录一个Eureka的服务如下图所示,表明启动成功
第九步:测试
微服务笔记之Eureka(1)的更多相关文章
- 微服务之服务中心—Eureka
Eureka 简介Eureka 是 Spring Cloud Netflix 的一个子模块,也是核心模块之一,用于云端服务发现,是一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故 ...
- 将微服务注册到Eureka Server
一.微服务程序编写 1.在已写好的微服务程序中添加pom依赖: <dependency> <groupId>org.springframework.cloud</grou ...
- SpringCloud系列三:将微服务注册到Eureka Server上
1. 回顾 通过上篇博客的讲解,我们知道硬编码提供者地址的方式有不少问题.要想解决这些问题,服务消费者需要一个强大的服务发现机制,服务消费者使用这种机制获取服务提供者的网络信息.不仅如此,即使服务提供 ...
- spring cloud之docker微服务客户端注册eureka问题
正常我们起一个微服务注册到eureka他的实例id是默认这样的主机名称:服务名称:服务端口号, 如果配置eureka.instance.prefer-ip-address=true则实例id为主机Ip ...
- 【一起学源码-微服务】Nexflix Eureka 源码十:服务下线及实例摘除,一个client下线到底多久才会被其他实例感知?
前言 前情回顾 上一讲我们讲了 client端向server端发送心跳检查,也是默认每30钟发送一次,server端接收后会更新注册表的一个时间戳属性,然后一次心跳(续约)也就完成了. 本讲目录 这一 ...
- 【一起学源码-微服务】Nexflix Eureka 源码十三:Eureka源码解读完结撒花篇~!
前言 想说的话 [一起学源码-微服务-Netflix Eureka]专栏到这里就已经全部结束了. 实话实说,从最开始Eureka Server和Eureka Client初始化的流程还是一脸闷逼,到现 ...
- 2021升级版微服务教程3—Eureka完全使用指南
2021升级版SpringCloud教程从入门到实战精通「H版&alibaba&链路追踪&日志&事务&锁」 默认文件1610014380163 教程全目录「含视 ...
- Spring Cloud之微服务注册到Eureka Server集群
在Spring Cloud之服务注册中心搭建Eureka Server服务注册中⼼ - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中已经搭建好了Eureka Server集群,本文就利用 ...
- Spring Cloud微服务笔记(三)服务治理:Spring Cloud Eureka快速入门
服务治理:Spring Cloud Eureka 一.服务治理 服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册与发现. 1.服务注册: 在服务治理框架中,通常会构 ...
- 微服务架构:Eureka集群搭建
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 服务注册.发现是微服务架构的关键原理之一,由于微服务架构是由一系列职责单一的细粒度服务构成的网状结构,服务之间通过轻量机制进行通信,这就必 ...
随机推荐
- 【Azure Cache for Redis】Python Djange-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
问题描述 使用Python连接Azure Redis服务,因为在代码中使用的是Djange-redis组件,所以通过如下的配置连接到Azure Redis服务: CACHES = { "de ...
- JS 格式化时间字符串
// 格式时间字符串 formatDateTimeStr(date, type) { if (date === '' || !date) { return '' } var dateObject = ...
- 2021级《JAVA语言程序设计》上机考试试题
勉强写完了 Card package Bean; public class Card { private String CardId; private String CardData; private ...
- 记一次完整的PHP代码审计——yccms v3.4审计
一.环境搭建与使用工具 (一)环境搭建 打开源码查看安装要求 PHP 5.4+,Mysql 5.0.*,直接使用phpstudy配置即可 查看源码目录结构,发现是mvc模式的,那么我们重点关注的就是c ...
- 题解 [SCOI2005]王室联邦
之前树分块也只是听说,今天亲手学了一下(?)( 首先你会发现这个 \(B\) 和 \(3B\) 的约束就很迷(我也不知道为什么搞这种奇怪的约束(悲)),学了才知道... 所以这题的分块方法好像叫&qu ...
- 利用反射和代理简单模拟mybatis实现简单的CRUD
利用反射接口做java数据库操作 今天突发奇想,好像一些基本的CRUD操作路数都是一样的,又想到mybatis中的操作,便想着简单的模拟一下.随便写写,就当练习反射了. Dao接口类: 这里使用泛型, ...
- GeoServer发布Oracle空间数据
1. 概述 Oracle是常用的数据库,Oracle数据库包含空间数据库,可以在Oracle中进行空间数据的存储,更详细的信息可参考: 空间数据库 | Oracle 中国 GeoServer是常用的开 ...
- 基于C++的OpenGL 02 之着色器
1. 概述 本文基于C++语言,描述OpenGL的着色器 环境搭建以及绘制流程可参考: 基于C++的OpenGL 01 之Hello Triangle - 当时明月在曾照彩云归 - 博客园 (cnbl ...
- PostgreSQL处理膨胀与事务回卷
一.表膨胀查询与处理 1.创建扩展 create extension pgstattuple; 2.表膨胀查询 pgstattuple提供了pgstatetuple()和pgstatindex()两个 ...
- Python Socket 基础多用户编程
简介 写下这篇小记的原因是想记录一下自己学习Python Socket编程的心路历程.之前在中专的时间学过一些基础的Socket编程,知道了一些比较基础的内容比如基础的socket.bind()类 ...