1. Ribbon

1.Ribbon的定义

一个基于http和tcp的负载均衡器,服务间调用,api网关请求转发,都用Ribbon进行负载均衡
Ribbon的主要作用是:从注册服务器端拿到对应服务列表后以负载均衡的方式访问对应服务。
注意的是,nacos已经整合了Ribbon,所以只要导入了nacos依赖,Ribbon也就引入了

图解如下:
在这里插入图片描述

2.Ribbon实际应用

2.1配置application.yml

消费者配置的nacos-user-service是服务者的服务名字前面加上http

server:
  port: 8083
spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
#消费者将要去访问的微服务名称(注册成功的nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-provider
2.2 在启动类上面新建RestTemplate的Bean

两个注解一个bean和一个loadblanced

 	@Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return  new RestTemplate();
    }
2.3 创建controller去调用服务者
package com.gek.cloudalibabaconsumernacos8083.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class DemoController {
  @Autowired
  private RestTemplate restTemplate;

  @Value("${service-url.nacos-user-service}")
  private String serverURL;

  @GetMapping("/consumer/nacos")
  public String getDiscovery(){
    return   restTemplate.getForObject(serverURL+"/gek",String.class);
  }
}

restTemplate.getForObject(arg1,arg2,arg3…);三个参数解释

第一个参数url表示被调用的目标Rest接口位置

  1. url 的第一个部份是nacos中注册的服务者的名称,如果多个服务提供者的名称相同,则Ribbon会自动寻找其中一个提供者。并调用这个方法,这就是负载均衡的作用
  2. url表示的是请求的路径。
    第二个参数是返回值类型
  • JavaBean类型或者JavaBean数组类型,如果控制器返回的是List集合,需要使用数组类型接收。
  • 表示的是远程调用的方法返回值是什么就写什么,本实例返回值是String,所以填写String.class
    第三个参数是可变参数
  • 如果这个远程方法需要传入参数,则第三个参数就要传入相应的参数,本文中不需要传参,所以没填
  • 是传递给url的动态参数,使用参数时候需要在url上需要使用{1}、{2}、{3}进行参数占位,这样传递的参数就会自动替换占位符。
2.4 测试结果
访问:http://localhost:8083/consumer/nacos
结果:Hello Nacos Discovery9001/9002(负载均衡切换显示)

3. 服务注册中心比较

服务注册与发现框架CAP模型控制台管理社区活跃度
EurekaAP支持低(2.x版本闭源)
ZookeeperCP不支持
ConsulCP支持
NacosAP/CP支持
3.1 CAP模型
  • 一致性(Consistency):同一时刻的同一请求返回的结果相同,所有的数据要求具有强一致性(Strong Consistency)
  • 可用性(Availability):所有实例的读写请求在一定时间内可以得到正确的响应
  • 分区容错性(Partition tolerance):在网络异常(光缆断裂,设备故障、宕机)的情况下,系统能提供正常的服务
    以上三个特点就是CAP原则(又称CAP定理),但是三个特性不可能同时满足,所以分布式系统设计要考虑的是在满足P(分区容错性)的前提下选择C(一致性)还是A(可用性),即:CP或AP
3.2 CP原则:一致性 + 分区容错性原则

CP原则属于强一致性原则,要求所有节点可以查询到数据的时候,随时都要保持一致(数据在同步过程中不可查询),即:若干个节点形成一个逻辑的共享区域,某一个节点更新的数据都会立即同步到其他数据节点之中,当数据同步完成后才能返回成功的结果,但是在实际的运行过程中网络故障在所难免,如果此时若干个服务节点之间无法通讯时就会出现错误,从而牺牲了以可用性原则(A),例如关系型数据库中的事务。

3.3 AP原则: 可用性原则+分区容错性原则

AP原则属于弱一致性原则,在集群中所有节点发送过来请求都要得到正确的响应;在进行数据同步处理操作中即便某些节点没有成功的实现数据同步也返回成功,这样就牺牲一致性原则(C 原则)。
使用场景:对于数据的同步发出一定的指令,但是最终的节点是否实现了同步,并不保证,但是却可以及时的得到数据更新成功的响应,可以应用在网络不是很好的场景

3.4 Nacos支持AP和CP

市场上大多以单一的形式出现(如Zookeeper支持CP,而Eureka支持AP),但是Nacos支持AP和CP两种形式,可以动态切换

Nacos 何时选择切换模式

  1. 一般来说,如果不需要存储服务界别的信息,且服务实例通过nacos-client注册,并保持心跳上传,那么就可以选中AP模式,如springcloud和dubbo都适用于AP模式,由于减弱了数据一致性,则AP只支持临时实例
  2. 如果需要服务级别的存储数据或者配置信息,那么CP是必须的,K8S和DNS服务则属于CP
    CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

切换命令(默认是AP)

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

== 注意:临时和持久化的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。 ==

4. Nacos 配置中心的使用

4.1 新建cloudalibaba-config-3377项目,配置pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.gek</groupId>
        <artifactId>SpringCloudAlibabaMSB</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gek</groupId>
    <artifactId>cloudalibaba-config-3377</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloudalibaba-config-3377</name>
    <description>cloudalibaba-config-3377</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--        nacos服务注册依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
4.2 新建bootstrap.yml配置文件
server:
 port: 3377
spring:
application:
  name: nacos-config-client
cloud:
  nacos:
    discovery:
      server-addr: 127.0.0.1:8848
    config:
      server-addr: 127.0.0.1:8848
      file-extension: yaml
4.3 新建application.yml配置文件
spring:
 profiles:
 active: dev #开发环境
4.4 主启动类
package com.gek.cloudalibabaconfig3377;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class CloudalibabaConfig3377Application {

 public static void main(String[] args) {
     SpringApplication.run(CloudalibabaConfig3377Application.class, args);
 }

}

4.5 业务类

其中@RefreshScope表示的意思是,可以动态刷新配置中心的文件,不需要重启项目

package com.gek.cloudalibabaconfig3377.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope //支持nacos动态刷新配置文件
public class ConfigClientController {
 @Value("${config.info}")
 private String configInfo;

 @GetMapping(value = "/config/info")
 public String getConfigInfo(){
     return configInfo;
 }
}

4.6 往配置中心去新建配置文件

在这里插入图片描述

在这里插入图片描述
Nacos配置规则
在 Nacos Spring Cloud 中,dataId 的完整格式如下(详情可以参考官网 https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html):

${prefix}-${spring.profiles.active}.${file-extension}
1. `prefix` 默认为 `spring.application.name` 的值,也可以通过配置项 `spring.cloud.nacos.config.prefix`来配置。
2. `spring.profiles.active` 即为当前环境对应的 profile,注意:**当 `spring.profiles.active` 为空时,对应的连接符 `-` 也将不存在,dataId 的拼接格式变成 `${prefix}.${file-extension}`**(不能删除)
3. `file-exetension` 为配置内容的数据格式,可以通过配置项 `spring.cloud.nacos.config.file-extension` 来配置。目前只支持 `properties` 和 `yaml` 类型。
4. 通过 Spring Cloud 原生注解 `@RefreshScope` 实现配置自动更新:
5. 所以根据官方给出的规则我们最终需要在Nacos配置中心添加的配置文件的名字规则和名字为:
# ${spring.application.name}-${spring.profiles.active}.${file-extension}
# nacos-config-client-dev.yaml
# 微服务名称-当前环境-文件格式

在这里插入图片描述
在这里插入图片描述
测试
启动服务访问服务来测试(没有修改之前是1,修改之后不需要重启项目既可以直接获取最新配置):http://localhost:3377/config/info

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐