目录
注册中心对比
Feign的服务负载
RoundRobinRule(默认)
RandomRule:
AvailabilityFilteringRule
WeightedResponseTimeRule
RetryRule
BestAvailableRule
ZoneAvoidanceRule
配置项
创建项目
pom文件
服务提供者
服务消费者
application.yml
provider-1
provider-2
消费者代码
启动服务成功
调用服务,测试
源码地址
AP和CP的切换
注册中心对比
对比项目 | Nacos | Eureka | Consul | Zookeeper |
一致性协议 | 支持AP和CP模型 | AP模型 | CP模型 | CP模型 |
健康检查 | TCP/HTTP/MYSQL/Client Beat | Client Beat | TCP/HTTP/gRPC/Cmd | Keep Alive |
负载均衡策略 | 权重/metadata/Selector | Ribbon | Fabio | - |
雪崩保护 | 有 | 有 | 无 | 无 |
自动注销实例 | 支持 | 支持 | 不支持 | 支持 |
访问协议 | HTTP/DNS | HTTP | HTTP/DNS | TCP |
监听支持 | 支持 | 支持 | 支持 | 支持 |
多数据中心 | 支持 | 支持 | 支持 | 不支持 |
跨注册中心同步 | 支持 | 不支持 | 支持 | 不支持 |
SpringCloud集成 | 支持 | 支持 | 支持 | 不支持 |
Dubbo集成 | 支持 | 不支持 | 不支持 | 支持 |
k8s集成 | 支持 | 不支持 | 支持 | 不支持 |
Feign的服务负载
Feign是通过 ribbon进行负载均衡,重试等一系列的访问机制
Ribbon 核心组件 IRule 是负载均衡策略接口,它有如下实现,大家仅做了解:
RoundRobinRule(默认)
: 轮询,即按一定的顺序轮换获取实例的地址。
RandomRule:
随机,即以随机的方式获取实例的地址。
AvailabilityFilteringRule
: 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务 , 以及并发的连接数量超过阈值的服务, 然后对剩余的服务列表按照轮询策略进行访问 ;
WeightedResponseTimeRule
: 根据平均响应时间计算所有服务的权重 , 响应时间越快 , 服务权重越大 , 被选中的 机率越高; 刚启动时, 如果统计信息不足 , 则使用 RoundRobinRule 策略 , 等统计信息足够时 , 会切换到 WeightedResponseTimeRule
RetryRule
: 先按照 RoundRobinRule 的策略获取服务 , 如果获取服务失败 , 则在指定时间内会进行重试 , 获取可用的服务;
BestAvailableRule
: 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务 , 然后选择一个并发量最小的服务;
ZoneAvoidanceRule
: 默认规则 , 复合判断 server 所在区域的性能和 server 的可用性选择服务器 ;
配置项
官网快速开始: https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery
配置项 | Key | 默认值 | 说明 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
创建项目
nacos-provider-1 服务提供者
nacos-provider-1 服务提供者
nacos-consumer 服务消费者
pom文件
服务提供者
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.sys.yang.NacosProviderApplication1</mainClass>
</configuration>
</plugin>
</plugins>
</build>
服务消费者
相比服务提供者,增加了
<!-- ribbon 点对点直连 -->
<!-- 添加 EnableFeignClients 的jar包 -->
<!-- 引入生产者的jar包 -->
<dependencies>
<!-- 引入生产者的jar包 -->
<dependency>
<groupId>com.sys.yang</groupId>
<artifactId>nacos-provider-1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- ribbon 点对点直连 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!-- 添加 EnableFeignClients 的jar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
application.yml
由于是使用单机进行测试,所以这里将服务设置为了不同端口, 但是 服务的名称是一致的,这样在注册到 nacos后,这两个服务会被看做一个服务的两个实例
由于 namespace 在创建命名空间的时候没有指定,nacos 会自动生成,这里在进行配置的时候,需要使用 你的项目自己生成的 namespace id
provider-1
server:
port: 8881 #端口
spring:
application:
name: nacos-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850 # nacos服务器地址
namespace: 5129a7bf-a75e-4b17-9f17-36b252547732 #命名空间
group: NACOS_PROVIDER #群组
provider-2
server:
port: 8882 #端口
spring:
application:
name: nacos-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850 # nacos服务器地址
namespace: 5129a7bf-a75e-4b17-9f17-36b252547732 #命名空间
group: NACOS_PROVIDER #群组
消费者代码
启动类,增加远程调用需要扫描的包
/**
* @author yangLongFei 2021-01-08-21:13
*/
@SpringBootApplication
@EnableDiscoveryClient //启动注册发现
@EnableFeignClients(basePackages = {"com.sys.yang.remote"}) //远程调用的的接口的文件夹
public class NacosConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConsumerApplication.class, args);
}
}
远程接口,需要使用配置文件中,配置的服务提供者的服务名称
/**
* value = "${yang.provide.name}" 配置文件中,配置的生产者服务的名称
*/
@FeignClient(value = "${yang.provide.name}")
public interface ProductServiceClint extends ProductServiceApi {
}
启动服务成功
调用服务,测试
http://localhost:8890/consumer/get/1223
源码地址
https://github.com/YANG-sty/study
AP和CP的切换
何时选择哪种模式?
一般来说不需要存储服务级别的信息,且服务实例是通过nacos-client注册的,并且能够保持心跳上报,那么就可以选择而AP模式,AP选择了高可用减弱了一致性,因此AP模式下只能够注册临时的实例
如果需要在服务级别编辑或者存储配置信息,那么CP就是必须的,K8S服务和DNS服务则适用于CP模式
CP模式下注册持久化实例,此时是以raft协议为集群运行模式,
该模式下注册实例必须先注册服务,如果服务不存在,则返回错误
curl -X PUT `$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
配置文件,添加 ephemeral
server:
port: 8882 #端口
spring:
application:
name: nacos-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850 # nacos服务器地址
namespace: 5129a7bf-a75e-4b17-9f17-36b252547732 #命名空间
group: NACOS_PROVIDER #群组
ephemeral: false #false为永久实例,true表示临时实例开启,注册为临时实例