1 微服务
1.1 spring cloud 是什么
- 他是一套分布式框架集合,基于 spring boot 开发的。
- 他是一种规范。
- 将不同公司生产的不同组件以 spring boot 的风格来集成。
- 这样的话,开发者就不用关心组件之间的整合,开箱即用,需要哪个组件直接用 spring boot 整合进来。
1.2 什么是 spring cloud alibaba
- 在 spring cloud 规范下出现的具体一套解决方案。
2 eureka 注册中心
2.1如何在多个微服务中发送远程 http 请求
2.1.1 首先我们在配置类中向 spring 容器注入 RestTemplate 对象的 Bean:
- 这里我们直接在启动类中注册,因为启动类也是一个配置类
package cn.itcast.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* 创建 RestTemplate 并注入 Spring 容器中
* @return RestTemplate
*/
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.1.2 我们接着修改 service 层中的服务信息
package cn.itcast.order.service;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
// 自动装配 RestTemplate
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.利用 RestTemplate 的实例来向别的服务发送 http 远程调用,这里我们查询用户
// 2.1 远程请求的 url 路径
String url = "http://localhost:8081/user/" + order.getUserId();
// 2.2 发送 http 请求
User user = restTemplate.getForObject(url, User.class);
// 3.封装 user 到 order
order.setUser(user);
// 4.返回
return order;
}
}
2.1.3 最后启动两个不同的服务即可
2.2 搭建 eureka 服务
2.2.1 引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud-demo</artifactId>
<groupId>cn.itcast.demo</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-server</artifactId>
<dependencies>
<!-- eureka服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
2.2.2 在启动类上添加 eureka 自动装配注解 @EnableEurekaServer
package cn.itcast.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
2.2.3 新建 application.yml 配置文件配置 eureka 如下信息
#eureka服务端口
server:
port: 10006
#以下两步都是为了服务注册才配置的
#eureka服务名称
spring:
application:
name: eurekaserver
#eureka地址信息:eureka自己也注册进来,方便之后集群部署注册中心之间的通信。
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10006/eureka
2.3 eureka 服务注册
2.3.1 引入如下依赖
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.3.2 在该 module 的 application.yml 下注册 eureka 服务
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: userservice #注册这个module的服务名称
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10006/eureka
2.3.3 注册多个相同的服务
- 在 idea 中我们在左下角 service 中可以看到服务列表,我们在服务列表中可以copy一份想要增加的服务。。
- 千万不要忘记更改端口号为未使用过的端口号。
右键 --> copy configuration --> 改名 --> environment --> VMoptions 中输入 -Dserver.port=端口号。
2.3.4 服务发现并且负载均衡
- 引入 eureka-client 依赖。
- 在当前 moudule 的 application.yml 中配置 eureka 地址。
- 给我们的 RestTemplate 添加 @LoadBalanced 注解让 eureka 自动进行负载均衡。
package cn.itcast.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* 创建 RestTemplate 并注入 Spring 容器中
* @return RestTemplate
*/
@Bean
// ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@LoadBalanced
// ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- 最后将服务提供者的服务名称远程调用
- 如:UserService 这个 Moudule 的远程调用服务名称在这个 Moudule 中的 application.yml 文件中配置了,叫做 userservice。
package cn.itcast.order.service;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.利用 RestTemplate 的实例来向别的服务发送 http 远程调用,这里我们查询用户
// 2.1 远程请求的 url 路径
// ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
String url = "http://userservice/user/" + order.getUserId();
// ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// 2.2 发送 http 请求
User user = restTemplate.getForObject(url, User.class);
// 3.封装 user 到 order
order.setUser(user);
// 4.返回
return order;
}
}
3 Ribbon 负载均衡
3.1 源码理解
3.1.1 @LoadBalanced 注解:标记的方法发起的请求要被 robbin 拦截去做负载均衡。
3.1.2 LoadBalancerInterceptor 核心类实现 ClientHttpRequestInterceptor 接口。
3.1.3 ClientHttpRequestInterceptor 接口是客户端http请求拦截器。
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.client.loadbalancer;
import java.io.IOException;
import java.net.URI;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
/**
* @author Spencer Gibb
* @author Dave Syer
* @author Ryan Baxter
* @author William Tran
*/
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer,
LoadBalancerRequestFactory requestFactory) {
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
}
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
// for backwards compatibility
this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
}
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
// 走到这一步就去找eureka拉取服务,这里是获得远程调用服务名称。
Assert.state(serviceName != null,
"Request URI does not contain a valid hostname: " + originalUri);
// 将服务名称传给 RobbinLoadBalancerClient 的对象 loadBalancer 来执行
return this.loadBalancer.execute(serviceName,
this.requestFactory.createRequest(request, body, execution));
}
}
3.1.4 在 RibbonLoadBalancerClient 中的 execute 方法中进行如下操作
/**
* New: Execute a request by selecting server using a 'key'. The hint will have to be
* the last parameter to not mess with the `execute(serviceId, ServiceInstance,
* request)` method. This somewhat breaks the fluent coding style when using a lambda
* to define the LoadBalancerRequest.
* @param <T> returned request execution result type
* @param serviceId id of the service to execute the request to
* @param request to be executed
* @param hint used to choose appropriate {@link Server} instance
* @return request execution result
* @throws IOException executing the request may result in an {@link IOException}
*/
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
throws IOException {
// 通过 serviceId 也就是我们远程调用服务的名称,找 eureka 拉取服务列表
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
// 这行代码就是在做负载均衡
Server server = getServer(loadBalancer, hint);
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonServer ribbonServer = new RibbonServer(serviceId, server,
isSecure(server, serviceId),
serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
}
我们此时可以在调试的 loadBalancer 对象中查看到我们注册在 eureka 上的服务:
this = {RibbonLoadBalancerClient@9301}
serviceId = "userservice"
request = {LoadBalancerRequestFactory$lambda@9355}
balancers = {ConcurrentHashMap@9796} size = 0
triggeringLoad = null
triggeringBlackoutPercentage = null
isSecure = false
useTunnel = false
serverListUpdateInProgress = {AtomicBoolean@9797} "false"
serverListImpl = {DomainExtractingServerList@9798}
filter = {ZonePreferenceServerListFilter@9799} "ZonePreferenceServerListFilter{zone='defaultZone'}"
updateAction = {DynamicServerListLoadBalancer$1@9800}
serverListUpdater = {PollingServerListUpdater@9801}
rule = {ZoneAvoidanceRule@9802}
pingStrategy = {BaseLoadBalancer$SerialPingStrategy@9803}
ping = {NIWSDiscoveryPing@9804}
allServerList = {ArrayList@9805} size = 2
upServerList = {ArrayList@9806} size = 2
// 在这
0 = {DomainExtractingServer@9826} "LAPTOP-EM069R1M:8082"
1 = {DomainExtractingServer@9827} "LAPTOP-EM069R1M:8081"
3.1.5 负载均衡实现
RobbinLoadBalancerClient类 ——> protected Server getServer(ILoadBalancer loadBalancer, Object hint) 方法 ——>
ZoneAwareLoadBalancer类 ——> public Server chooseServer(Object key) 方法 ——> BaseLoadBalancer类 ——>
public Server chooseServer(Object key) 方法 ——> IRule类 ——> RoundRibbonRule轮询负载均衡方法
3.1.6 自定义负载均衡策略
- 通过自定义配置类来实现(全局起作用):
package cn.itcast.order.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomIRuleConfig {
/**
* 自定义负载均衡策略
* @return IRule
*/
@Bean
public IRule randomRule(){
return new RandomRule();
}
}
- 通过 yml 文件来配置(指定微服务):
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: orderservice #注册这个module的服务名称
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10006/eureka
#该负载均衡规则只对名为 userservice 的微服务起作用
userservice:
robbin:
NFLoadBalancerRuleClassName: com.netflix.loadBalancer.RandomRule #负载均衡规则
- 这俩个全局的作用的负载均衡策略优先级高!!
3.1.7 饥饿加载
- Ribbon 默认是懒加载,既第一次访问的时候才去创建 LoadBalancerClient,请求时间会很长。
- 饥饿加载则会在项目启动时创建,降低第一次访问所需要的时间。
- 开启饥饿加载的配置:
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: orderservice #注册这个module的服务名称
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10006/eureka
userservice:
robbin:
NFLoadBalancerRuleClassName: com.netflix.loadBalancer.RandomRule #负载均衡规则
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ribbon:
eager-load:
enabled: true #开启饥饿加载
clients: #指定饥饿加载的服务名称
- userservice
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.1.8 总结
- Ribbon 负载均衡规则:
- 规则接口叫做 IRule。
- 默认实现是 ZoneAvoidanceRule ,根据 zone 选择服务列表然后轮询负载均衡。
- 负载均衡自定义方式:
- 代码方式:
- 配置类,配置灵活,但修改时需要重新打包发布。
- 配置文件方式:
- 直观方便,无需重新打包,但是无法做全局配置。
- 饥饿加载:
- 通过配置文件开启饥饿加载。
- 指定要饥饿加载的服务名称,是个数组。
- 代码方式:
3 Nacos 注册中心
3.1 Nacos windos 启动命令
startup.cmd -m standalone
3.2 Nacos 依赖
- 一般将其引入到父工程中。
- 引入 nacos 后得把 eureka 的依赖注释或删除,防止冲突。
<!-- nacos服务端管理依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- nacos客户端依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3.3 nacos 简易使用
3.3.1 客户端引入依赖
<!-- nacos客户端依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3.2.2 修改客户端 application.yml 文件中的 nacos 配置
server:
port: 8080
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: orderservice #注册这个module的服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos服务地址
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
#eureka:
# client:
# service-url:
# defaultZone: http://127.0.0.1:10006/eureka
userservice:
robbin:
NFLoadBalancerRuleClassName: com.netflix.loadBalancer.RandomRule #负载均衡规则
ribbon:
eager-load:
enabled: true #开启饥饿加载
clients: #指定饥饿加载的服务名称
- userservice
3.4 nacos 服务分级存储模型
3.4.1 概念
- 一个服务包含多个实例。
- 例如提供一个叫做 userservice 的服务,他的实例为 userservice:8080、userservice:8081 等等。
- 随着业务规模越来越大,以前服务小,所有服务可能放在一个机房,机房炸了,服务也就没了。
- 为了解决这个问题,我们会将一个服务的多个实例,部署到多个机房。
3.4.2 集群粗解释
- 拿上面的例子来说,一个服务可能有八个实例,八个实例被两两分配在四个机房,那么此时装有两个服务实例的一个机房就叫做集群。
3.4.3 nacos 服务分级存储模型定义
- 三级:服务 ——> 集群 ——> 实例
3.4.5 服务跨集群调用问题
- 由于跨集群调用,可能涉及两个不同集群之间距离很远,调用的话延迟很高。
- 所以我们一般情况都是先本地调用,如果本地调用无法调用才去进行远程集群调用。
3.5 如何配置一个服务的集群属性
3.5.1 修改 application.yml 文件中的配置
- 如果我们有多个实例,我们可以先将 cluster-name 设置为其中一个集群名称,然后启动其中几个实例。
- 然后我们再修改 cluster-name 为别的集群名称。
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: userservice #注册这个module的服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos服务地址
discovery:
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cluster-name: SH #设置集群所在地区名称 SH 代指上海 HZ 代指杭州
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cluster-name: HZ #设置集群所在地区名称 SH 代指上海 HZ 代指杭州
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
#eureka:
# client:
# service-url:
# defaultZone: http://127.0.0.1:10006/eureka
3.5.2 nacos控制台结果
| 结果 |
|---|
![]() |
3.5.3 nacos 根据服务分级存储模型的负载均衡策略
- 我们可以在两个集群:
- SH集群:orderservice、userservice1、userservice2、
- HZ集群:userservice3
- 我们在用 orderservice 向 userservice 发起几次不同的请求。
- 我们会发现,在 orderservice 同一集群的服务没有挂掉的时候,它也去请求了远程 HZ集群的 userservice3。
- 所以我们要解决这个问题,我们使用 nacos 根据服务分级存储模型的负载均衡策略。
- 在 orderservice 的 application.yml 文件中完成如下配置:
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: orderservice #注册这个module的服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos服务地址
discovery:
cluster-name: HZ
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
userservice: # 要做配置的微服务名称
robbin:
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ribbon:
eager-load:
enabled: true #开启饥饿加载
clients: #指定饥饿加载的服务名称
- userservice
3.5.4 nacos 权重负载均衡
- 实际部署中每台机器的性能都不一样,我们希望性能好的机器多承担一些请求,性能差的少承担一点。
- 为了解决这个问题,nacos 帮我提供了权重设置,权重越高,访问率就越高。
- 我们可以直接在 nacos 的网页控制端直接修改不同的权重。
- 这个带给我们的好处,我们可以用在服务升级的过程中。
3.5.5 nacos 环境隔离
- nacos 中服务存储和数据存储这俩者的最外层都是一个叫做 命名空间(namespace) 的东西用来做最外层隔离。
- 包含关系:
- namespace > group > service/data
- 我们可以在 nacos 控制台新建新的命名空间,然后到代码层面去实现分配。
# ...
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.cj.jdbc.Driver
application:
name: orderservice #注册这个module的服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos服务地址
discovery:
cluster-name: HZ
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
namespace: 55f76e06-f468-4723-a8f7-29a7f2004cbf # dev 命名空间的id
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ...
3.5.6 nacos 临时实例和非临时实例
- 我们可以在 orderservice 的 application.yml 文件中完成如下配置:
# ...
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
username: root
password: mysql123456
driver-class-name: com.mysql.cj.jdbc.Driver
application:
name: orderservice #注册这个module的服务名称
cloud:
nacos:
server-addr: localhost:8848 #nacos服务地址
discovery:
cluster-name: HZ
namespace: 55f76e06-f468-4723-a8f7-29a7f2004cbf # dev 命名空间的id
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ephemeral: false # 设置为非临时实例
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ...
- 如果是非实例状态,服务即使停了也不会被剔除,你可以再次启动。
3.5.7 nacos 和 eureka 的区别
- nacos 支持服务端主动检测服务提供者状态。
- 临时实例
- 临时实例采用心跳模式。
- 心跳不正常会被剔除服务列表。
- 非临时实例
- 非临时实例采用主动检测模式。
- 心跳不正常不会被剔除服务列表。
- 会对服务器造成比较大的压力。
- 临时实例
- nacos 支持服务列表更新就主动推送给消费者的消息推送模式,服务列表可以及时更新。
- nacos 集群默认采用 AP 方式,当集群中存在非临时实例时,采用 CP 模式,而 eureka 采用 AP 模式。
本文介绍了SpringCloud的SpringBoot集成、Eureka注册中心的使用、Ribbon负载均衡原理,以及Nacos作为服务注册中心的配置和分级存储模型。重点讲解了服务发现、负载均衡策略的定制和Nacos的环境隔离功能。

&spm=1001.2101.3001.5002&articleId=120240938&d=1&t=3&u=3b44c1713a5944aa9b832b30908ffb20)
1546

被折叠的 条评论
为什么被折叠?



