关键词:
目录
1. 概念
注册中心:
- 需求:当一个服务提供者 Service 部署了多个实例交给 User 远程调用时:
- 服务消费者 User 应该调用哪个实例,如何获取其对应地址和端口?
- User 如何获知实例是否健康?
- 注册中心作用:
- 帮助管理服务,并帮助服务调用者选择并调用服务
- 实时监测服务实例是否健康
Eureka:
- 构成:
- eureka-server:服务端,注册中心
记录服务信息,心跳监控 - eureka-client:客户端,
服务提供者(注册到服务端,定期向服务端发送心跳)、服务消费者(从服务端拉取服务列表,基于负载均衡选择服务)
- eureka-server:服务端,注册中心
- 作用:
- 服务注册: Service实例启动后,会将自己的信息注册到 eureka服务端
- 服务拉取: User 根据 实例名 获取 Service 地址列表
- 负载均衡: User 根据负载均衡算法 从 拉去的 Service 地址列表中 选择一个服务实例
- 心跳检查: Service实例 每隔一段时间(默认30s)就会向 eureka服务端 发起请求,报告自己的状态,当超过一段时间没向 eureka服务端 发送心跳,eureka 就会将此实例从 地址列表中剔除
nacos
- 概念:
- 服务注册中心
- 作用:
- 心跳检查: 不同于 eureka 只能 Service实例 主动发起心跳,nacos 对于非临时实例可以主动发起心跳检查
- 临时心跳检查异常的会被剔除出 服务地址列表
- 非临时心跳检查异常的不会被剔除
- 定时推送变更: nacos 支持服务列表变更的消息推送模式,服务列表更新更及时
- 心跳检查: 不同于 eureka 只能 Service实例 主动发起心跳,nacos 对于非临时实例可以主动发起心跳检查
2. Eureka
1. 服务搭建
1. 依赖导入
依赖:
-
父项目依赖
我用的是2.6.11版本的springboot,所以要选择2021.0.5版本的springcloud<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring.cloud-version>2021.0.5</spring.cloud-version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>$spring.cloud-version</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
子项目依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
2. 配置文件
我们需要将 eureka 注册到spring容器中,所以需要在配置文件中做相关配置。
server:
port: 8099
spring:
application:
name: eureka_server
eureka:
client:
# 配置eureka服务地址
service-url:
defaultZone: http://127.0.0.1:8099/eureka
3. 启动项目
为了让项目能启动 eureka,需要在启动类上加一个注解:@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class ServerApplication
public static void main(String[] args)
SpringApplication.run(ServerApplication.class, args);
启动项目,访问地址:http://127.0.0.1:8099:
注册的服务名称就是配置文件中的名称的大写。
2. 服务注册
在上一步,已经将 eureka-server (eureka服务中心)搭建完毕,现在就开始注册服务实例了。
1. 依赖导入
注意:
-
无论是 服务提供者 还是 服务消费者,他们的身份都是 eureka-client
-
记得添加 spring-boot-starter-web 的依赖,不然会报错:Field optionalArgs in org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration required a bean of type ‘com.netflix.discovery.AbstractDiscoveryClientOptionalArgs’ that could not be found.
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
服务发现、服务注册统一都封装在eureka-client依赖。
2. 配置文件
需要在配置文件中配置 eureka-server 的地址。
spring:
application:
name: service_provider
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8099/eureka
3. 启动多个实例
为了让项目能启动 eureka,需要在启动类上加一个注解:@EnableEurekaClient。
@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication
public static void main(String[] args)
SpringApplication.run(ProviderApplication.class, args);
我们可以通过 IDEA 自带功能模仿启动多个服务实例。
-
打开 Service 面板
-
复制原来的 provider 启动配置
-
查看 eureka注册中心
3. 服务发现
1. 依赖导入
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. 配置文件
配置文件:
spring:
application:
name: service_user
server:
port: 8084
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8099/eureka
3. 服务拉取和负载均衡
服务拉取:
-
修改 controller 代码,将 url 路径的 ip、端口 修改为 服务名:
@RestController @RequestMapping("user") public class UserController @Autowired private RestTemplate restTemplate; @GetMapping("/id") public Book getBookById(@PathVariable("id") Integer id) // String url = "http://127.0.0.1:8081/provider" + id; String url = "http://service_provider/provider"; if (id != null) url = url + id; Book book = restTemplate.getForObject(url, Book.class); return book;
-
注册 RestTemplate 的时候加上注解 @LoadBalanced
@LoadBalanced @Bean public RestTemplate restTemplate() return new RestTemplate();
-
接口调用:
@RestController @RequestMapping("user") public class UserController @Autowired private RestTemplate restTemplate; @GetMapping("/id") public Book getBookById(@PathVariable("id") Integer id) // String url = "http://127.0.0.1:8081/provider" + id; String url = "http://PROVIDER/pro/"; if (id != null) url = url + id; Book book = restTemplate.getForObject(url, Book.class); return book;
-
访问接口:
访问报错:
解决方案: 命名别带下划线。
多测试几下接口,可以发现,user一会儿调用的是 provider:8081 一会儿调用的是 provider:8082。这就是负载均衡算法选择的。
4. 小结
eureka-server 搭建:
-
引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
启动类添加 @EnableEurekaServer
-
配置文件配置 eureka 地址
server: port: 8099 spring: application: name: server eureka: client: # 配置eureka服务地址 service-url: defaultZone: http://127.0.0.1:8099/eureka
服务注册:
- 引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
- 启动类添加 @EnableEurekaClient
- 配置文件配置 eureka 地址
server: port: 8081 spring: application: name: provider eureka: client: # 配置eureka服务地址 service-url: defaultZone: http://127.0.0.1:8099/eureka
服务发现:
- 引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
- 启动类添加 @EnableEurekaClient
- 配置文件配置 eureka 地址
server: port: 8089 spring: application: name: user eureka: client: # 配置eureka服务地址 service-url: defaultZone: http://127.0.0.1:8099/eureka
3. Ribbon
1. 负载均衡流程
Ribbon负载均衡流程图:
http://PROVIDER/pro/4 并非真实的地址,这个需要Ribbon负载均衡去拦截,然后选择具体的服务地址。而,Ribbon就是通过 LoadBalancerInterceptor 的 intercept 方法来实现拦截请求并解析选择地址。
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException
URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
负载均衡流程:
2. 负载均衡策略
Ribbon的负载均衡策略是由 IRule 接口来定义的。
IRule常见规则:
内置负载均衡规则类 | 规则描述 |
---|---|
RoundRobinRule | 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。 |
AvailabilityFilteringRule | 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit属性进行配置。 |
WeightedResponseTimeRule | 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
ZoneAvoidanceRule (默认) | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。 |
BestAvailableRule | 忽略那些短路的服务器,并选择并发数较低的服务器。 |
RandomRule | 随机选择一个可用的服务器。 |
RetryRule | 重试机制的选择逻辑 |
自定义负载均衡策略:
-
方式一: 在user中,@Bean 注入自定义 IRule
@Bean public IRule randomRule() return new RandomRule();
-
方式二: 在user,配置文件修改 IRule
provider: # 给某个微服务配置负载均衡规则,这里是userservice服务 ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
注意: 方式一的作用范围是:在访问任何微服务的时候,都是使用 RandomRule 负载均衡策略;方式二的作用范围是:在访问 provider 微服务的时候才是采用 RandomRule 策略,其他的还是使用默认策略。
3. 加载策略
Ribbon默认采用懒加载,即会在第一次访问时才会去创建 LoadBalanceClient ,所以会在第一次请求的时候花上较长的等待时间。
可以通过配置文件更改加载策略为饿加载策略,即初始化时就创建 LoadBalanceClient ,降低第一次访问的耗时。
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: provider # 指定饥饿加载的服务名称
4. Nacos
1. 下载安装
Nacos下载地址: https://github.com/alibaba/nacos/releases
下载好之后,解压就行了。
默认端口: 8848 ,可通过 conf/application.properties 的 server.port 修改端口。
单击启动: bin/
-
方式一:双击 startup.cmd
-
方式二:
startup.cmd -m standalone
登录:默认账号、密码都是 nacos 。
2. 注册中心
1. 引入依赖、修改配置
父工程添加 SpringCloudAlibaba 的管理依赖。
<!--spring-cloud-alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
子工程中注释掉 eureka 依赖,引入 nacos 依赖。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置文件配置nacos地址:
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos服务地址
启动 user 和 provider :
注意: eureka 注册名会变成大写,nacos 不会,所以改成 nacos 之后,需要把访问地址改成小写。
请求测试:
2. 服务分级存储模型
一个服务可以拥有多个实例,如:provider 的 8081 和 8082,如果这些实例分布于全国不同的机房,如:provider:8081 在成都机房、provider:8082 在重庆机房,Nacos就将同一机房内的实例 划分为一个集群。
即,一个服务可以拥有多个集群,一个集群中可以拥有多个实例。
微服务相互之间访问时,访问本地的速度更快,所以应该尽可能访问相同集群的实例,只有当本集群内存不够时,才去访问其他集群。
1. 配置集群
配置服务集群:
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos服务地址
discovery:
cluster-name: CD
VM Options:
-Dserver.port=8082 -Dspring.cloud.nacos.discovery.cluster-name=CQ
2. 同集群优先的负载均衡
默认的 ZoneAvoidanceRule 负载均衡策略并不能实现据同集群优先来实现负载均衡,因此Nacos中提供了一个NacosRule
的实现,可以优先从同集群中挑选实例。
修改负载均衡策略:
-
方式一:
@Bean public IRule nacosRule() return new NacosRule();
-
方式二:
provider: # 访问的服务名 ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
3. 权重配置
服务器的性能之间存在差异,为了让性能能好的服务器承担更多的用户请求,Nacos提供了权重配置来控制访问率:权重越大、访问率越高。
注意: 权重为0的服务永远不会被访问。
4. 环境隔离
Nacos提供了namespace来实现环境隔离功能。
- nacos中可以有多个namespace
- namespace下可以有group、service等
- 不同namespace之间相互隔离(不同namespace的服务互相不可见)
1. 创建 namespace
Nacos默认的namespace是:public 。
Nacos创建命名空间流程:
2. 配置命名空间
spring:
cloud:
nacos:
discovery:
namespace: e11eb3bc-8eed-4cdd-93f0-7a6c01b85eb4 # 命名空间,填ID
注意: 因为此时 dev 命名空间中只有 user,导致无法访问到 public 中的 provider ,发起访问请求会报错。
3. 永久实例
Nacos的服务实例分为两种类型:
-
临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型
-
非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例
临时实例是实例向注册中心发起心跳,永久实例是注册中心主动向实例询问心跳。
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为永久实例
3. 配置管理
Nacos不仅可以担任微服务的注册中心,还可以担任配置管理。
1. 统一配置管理
可以使用统一配置管理来处理因为部署的微服务数量过多,配置繁杂等问题。
Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
注意: 只把那些需要热更新的配置文件交给Nacos
1. nacos添加配置文件
Data ID: 配置文件id:服务名称-profile.后缀名 。
2. 从nacos拉取配置
spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:
-
引入nacos-config依赖:
<!--nacos配置管理依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
-
添加bootstrap.yml
spring: application: name: user # 服务名称 profiles: active: dev #开发环境,这里是dev cloud: nacos: server-addr: localhost:8848 # Nacos地址 config: file-extension: yaml # 文件后缀名
这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据
$spring.application.name-$spring.profiles.active.$spring.cloud.nacos.config.file-extension
作为文件id,来读取配置。 -
读取nacos配置
@Value("$pattern.dateformat") private String dateformat; @GetMapping("now") public String now() return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
启动报错: org.springframework.beans.factory.BeanCreationException: Error creating bean with name xxx
解决方案:
- 检查 namespace,配置文件与服务要在同一个 namespace 中
- 名称是否拼错
- 升级 nacos 版本
- @Value 切换为 @NacosValue
2. 配置热更新
配置热更新: 修改nacos中的配置后,微
springcloudalibaba实战(7:nacos注册中心管理微服务)(代码片段)
...部署,这一节我们学习如何将Nacos作为注册中心,管理微服务。1、注册中心简介1.1、什么是注册中心在微服务的体系里,注册中心是最重要的组件之一,我们来简单了解一下什么是注册中心。注册中心和DNS类似,大家想一想,我... 查看详情
微服务高可用方案(代码片段)
微服务高可用方案一、微服务的高可用在注册中心、配置中心高可用方案之前,了解一下注册中心的工作原理,下面分为两个部分来解释,一是注册中心和各个微服务的注册表的获取与同步,二是注册中心如何去维护注册表。1.1... 查看详情
微服务-服务注册与发现(代码片段)
1.服务注册与发现基础架构注册中心:接受服务提供者的注册、存储服务提供者的服务信息,比如ip端口号服务名这些信息;并且与微服务保持心跳,如果心跳不能保持则注销该实例。所以注册中心主要提供服务提供者信息的存... 查看详情
springcloudalibaba实战(7:nacos注册中心管理微服务)(代码片段)
...ff0c;这一节我们学习如何将Nacos作为注册中心,管理微服务。1、注册中心简介1.1、什么是注册中心在微服务的体系里,注册中心是最重要的组件之一,我们来简单了解一下什么 查看详情
springcloud微服务技术栈的注册中心eureka(代码片段)
文章目录SpringCloud微服务技术栈的注册中心Eureka简介Eureka特点操作步骤环境准备创建EurekaServer注册服务提供方调用服务消费方总结SpringCloud微服务技术栈的注册中心Eureka简介在微服务架构中,服务的数量庞大,而且每个服... 查看详情
配置nacos注册中心(代码片段)
Nacos内容一、什么是服务治理二、常见注册中心三、Nacos简介四、Nacos实战入门(掌握)1.搭建Nacos环境2.将商品服务注册到Nacos3.将订单服务注册到Nacos总结内容微服务配置请看我的上篇博客:微服务环境搭建一、什么是服务治理... 查看详情
nacos注册中心的部署与用法详细介绍(代码片段)
一、什么是注册中心: 我们知道微服务彼此间独立部署、具有清晰的边界,服务间通过远程调用来构建复杂的业务功能。而服务册中心在微服务项目中扮演着非常重要的角色,那么注册中心又是什么,... 查看详情
升级微服务架构2:服务注册(代码片段)
微服务架构中,服务是最小的可伸缩的独立部署的单位,同一个服务提供可以有多个实例,这些实例都会注册到服务注册中心(EurekaServer)上进行统一的管理及调用的负载均衡。 因SpringCloud的是已Java为主要开发语言,本... 查看详情
springcloudalibaba微服务组件nacos注册中心(代码片段)
文章目录前言:基础铺垫什么是微服务架构?微服务架构和集中式架构的区别?Spring全家桶之间的递进关系思考:微服务和微服务之间调用存在什么问题,需要用到什么技术?思考:没有微服务架构... 查看详情
初探微服务架构(代码片段)
之前介绍了什么时候进行服务化,以及服务化拆分的两种方式即横向拆分和纵向拆分,还提到了引入微服务架构需要解决的问题。这篇文章将进行介绍微服务架构的各个组成部分。下图是微服务架构的模块图,在具体介绍之前先... 查看详情
springcloudalibaba微服务介绍及nacos注册中心实战(代码片段)
文章目录前言I、微服务与SpringCloudII、Nacos注册中心III、SpringCloudAlibabaNacos实战1、新建父工程2、新建demo-a服务3、新建demo-b服务4、实现服务调用:传统方式5、实现服务调用:Nacos+Ribbon方式总结最后前言SpringCloudAlibaba微... 查看详情
springcloud之微服务实用篇1(代码片段)
今天我们主要学习的内容包含5个部分,分别为认识微服务,分布式服务架构案例,euraka注册中心,Ribbon负载均衡原理,nacos注册中心。目录一、微服务1.1、认识微服务1.2、服务的拆分及远程调用1.3、 euraka注册... 查看详情
微服务服务注册中心注册和发现
】微服务服务注册中心注册和发现【英文标题】:Microservicesserviceregistryregistrationanddiscovery【发布时间】:2015-09-0819:58:40【问题描述】:小域介绍我实际上有两个微服务:用户-管理用户的CRUD帐单-管理帐单上的CRUD,并带有与帐单... 查看详情
springcloudalibaba微服务2,注册中心演变+nacos注册中心与配置中心(代码片段)
...ff1f;二、注册中心演变及其设计思想1、RestTemplate调用远程服务2、通过Nginx维护服务列表(upStream)3、通过Nacos实现注册中心4、心跳版Nacos三、NacosDiscovery四、Nacos核心功能1、服务注册2、服务心跳3、服务同步4、服务发现5、... 查看详情
eureka注册中心(代码片段)
使用场景在微服务架构中由于服务很多,彼此之间存在各种相互调用,所以各个服务的访问地址查询管理以及多副本的负载均衡问题就出现了,在传统架构中通常可以用nginx来解决此问题,由于微服务众多,如果用nginx就会涉及... 查看详情
alibaba微服务组件nacos注册中心
Alibaba微服务组件Nacos注册中心什么是NacosNacos注册中心注册中心配置项详解什么是Nacos官方概念:一个易于构建云原生应用的动态服务发现(NacosDiscovery)、服务配置(NacosConfig)和服务管理平台。Nacos的关键特性包括:1》服务发... 查看详情
springcloud系列服务注册中心eureka基础(代码片段)
启动Eureka服务注册中心1、微服务的注册中心1.1、注册中心的主要作用1.2、常见的注册中心1.3、常见注册中心的异同点2、Eureka概述2.1、Eureka的基础知识2.2、Eureka的交互流程与原理3、搭建Eureka注册中心案例3.1、搭建Eureka服务中心3.2... 查看详情
流量调度微服务可寻址性和注册中心(代码片段)
...观且无感的(DNS+Nginx就可以完成一次流量调度)。演进到微服务结构(服务粒度变得更细、服务伸缩更灵活(上下线更加频繁),团队松耦合),流量调度并没有消失,而是变得更加复杂。关键名词解释1.控制平面/数据平面控制平面... 查看详情