为了避免单点故障,微服务架构下会采取集群方式的高可用部署

  • 注册中心解决的问题
    1.维护集群的每个节点的请求地址
    2.防止请求发送到已宕机的节点上造成请求失败
  • 注册中心功能
    1.服务地址管理
    2.服务注册
    3.服务动态感知

ZooKeeper、Eureka、Consul、Etcd、Nacos等组件都可以实现以上功能

什么是Alibaba Nacos

官网地址: https://nacos.io/zh-cn/docs/what-is-nacos.html
image.png
Nacos致力于解决为服务中的统一配置、服务注册与发现,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理
看到nacos修复一个安全漏洞,🤣!!!
企业微信截图_5e85381e-21df-4fc9-9231-0c7671651427
Nacos地图
nacosMap

!!!踩坑:Nacos编译后的版本不支持Mysql8

image.png
如果需要支持使用Mysql8,需要自己下载源码修改支持Mysql8的依赖后再编译

Nacos的关键特性

  • 服务发现和服务健康检测
    1.消费者可适用DNS、HTTP、API查找和发现服务
    2.提供对服务的实时的健康检查,阻止向不健康主机或服务实例发送请求
    3.提供统一的健康检查仪表盘,帮助根据健康状态管理服务的可用性及流量
  • 动态配置服务
    1.动态配置服务可去中心化,配置变更时不用重新打包部署,配置管理变得更加高效和敏捷
    2.简洁易用的UI帮助用户管理所有服务和应用
  • 动态DNS服务
    更容易实现中间层负载均衡、更灵活的路由策略、流量控制
  • 服务及其元数据管理
    管理数据中心所有的服务及元数据

Nacos的基本使用

基于Java编写,需要JRE环境

Nacos的安装

https://nacos.io/zh-cn/docs/quick-start.html
官网说的很详细,不再赘述,贴个图,我选择编译好的1.4.1版本
image.png

Nacos服务注册与发现相关API说明

image.png
官网提供了Java SDK和Open API,其他语言的SDK非官方发布,官网也说的很详细,简单罗列服务注册相关核心接口

注册实例

将服务地址信息注册到Nacos Server

  • OPAPI
    image.png
  • Java SDK
    image.png

获取全部实例列表

  • OPAPI
    image.png
  • Java SDK
    image.png

监听服务

监听指定服务下的实例变化,让客户端及时感知服务提供者实例变化

  • OPAPI
    image.png
    和获取全部实例列表的API是一样的
  • Java SDK
    image.png

Nacos集成Spring Boot实现服务注册与发现

实现一个简单的服务注册与发现

  • 1.添加nacos注册中心依赖
 <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-discovery-spring-boot-starter</artifactId>
            <version>0.2.4</version>
        </dependency>
  • 2.使用Nacos的@NacosInjected注解注入Nacos的NamingService,通过getAllInstances方法可得到所有实例
@RestController
public class DiscoveryController {

    @NacosInjected
    private NamingService namingService;

    @GetMapping("/discovery")
    public List<Instance> get(@RequestParam String serviceName) throws NacosException {
        return namingService.getAllInstances(serviceName);
    }
}

image.png

  • 添加配置文件
nacos.discovery.server-addr=127.0.0.1:8848
  • 单机启动Nacos(sh startup.sh -m standalone)及该项目
    根据Open API调用查询名为example的提供者,返回空对象
    image.png
  • 利用Open API向Nacos注册提供者
    image.png
    注册成功后Nacos控制台可以查看到刚刚注册的提供者信息
    image
    image.png
  • 由于Nacos的心跳机制健康检查,几秒后该服务提供者会从Nacos删去信息
    image.png

Nacos的高可用部署(集群)

分布式架构中,任何中间件及应用都不应该单点存在,开源组件一般都支持高可用集群解决方案。
类似于ZooKeeper和Redis,Nacos集群也采用主从节点,其数据一致性算法采用Raft和Redis Sentinel选举一样
image.png

安装配置环境要求

  • JDK1.8及以上
  • Maven3.2及以上
  • MySQL
  • ...
    image.png

image.png
官网有详细步骤不细说

Dubbo使用Nacos实现注册中心

Dubbo支持多种注册中心
image.png

接口暴露模块

public interface IHelloService {

    String sayHello(String name);
}

接口实现模块

  • 依赖
dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.gupaoedu.book.nacos</groupId>
            <version>1.0-SNAPSHOT</version>
            <artifactId>nacos-sample-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-discovery-spring-boot-starter</artifactId>
            <version>0.2.4</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.spring</groupId>
                    <artifactId>spring-context-support</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.5</version>
        </dependency>
  • 接口实现类及启动类
@Service
public class HelloServiceImpl implements IHelloService {

    @Override
    public String sayHello(String name) {
        return "Hello World:"+name;
    }
}
@DubboComponentScan
@SpringBootApplication
public class NacosSampleProviderApplication {

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

}
  • Nacos控制台数据
    image.png

Spring Cloud Alibaba Nacos Discovery整合

Spring Cloud Alibaba Nacos Discovery可以基于Spring Cloud规范快速接入Nacos,实现服务注册与发现

服务端

接口暴露模块

public interface IHelloService {
    String sayHello(String name);
}

接口实现模块

  • 项目依赖
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-context</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>com.gupaoedu.book.nacos</groupId>
            <artifactId>spring-cloud-nacos-sample-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-context</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
  • 实现类
@Service
public class HelloServiceImpl implements IHelloService {

    @Override
    public String sayHello(String s) {
        return "Hello World:"+s;
    }
}
  • 启动类
@SpringBootApplication
public class SpringCloudNacosSampleProviderApplication {

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

  • 配置文件
spring.application.name=spring-cloud-nacos-sample

dubbo.scan.base-packages=com.gupaoedu.book.nacos.bootstrap

dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#Dubbo注册中心挂载到Spring Cloud注册中心,不配置会报没有注册中心的错误错
dubbo.registry.address=spring-cloud://localhost
#Nacos注册中心地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  • 启动提供者
    image.png
    image.png

消费端

  • 项目依赖
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.gupaoedu.book.nacos</groupId>
            <artifactId>spring-cloud-nacos-sample-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
            <version>2.1.1.RELEASE</version>
  • 配置文件
dubbo.cloud.subscribed-services=spring-cloud-nacos-sample
dubbo.scan.base-packages=com.gupaoedu.book.nacos.bootstrap
spring.application.name=spring-cloud-nacos-consumer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  • 远程引用类
@RestController
public class HelloController {

    @Reference
    private IHelloService helloService;

    @GetMapping("/say")
    public String sayHello(){
        return helloService.sayHello("Mic");
    }
}
  • 启动类
@SpringBootApplication
public class SpringCloudNacosConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudNacosConsumerApplication.class, args);
    }
}
  • 启动项目,调取接口
    image.png

总结

Zookeeper和Nacos基于Spring Cloud标准实现,所以集成方式差不大多

Nacos实现原理分析

Nacos架构图

https://nacos.io/zh-cn/docs/architecture.html
官网N多架构图,贴一张
1561217892717-1418fb9b-7faa-4324-87b9-f1740329f564

  • Provider APP:服务提供者
  • Consumer APP:服务消费者
  • Name Server:通过VIP(Vritual IP)或者DNS实现Nacos高可用集群路由
  • Nacos Server:Nacos服务提供者,包含:
    1.Open API:功能访问入口
    2.Config Service:配置服务
    3.Name Service:名字服务
    4.Consistency Protocol:一致性协议,实现集群节点数据同步使用Raft算法
  • Nacos Console:Nacos控制台

注册中心的原理

image.png
注册中心的功能体现

  • 服务实例在启动时注册到服务注册表,关闭时注销
  • 消费者轮询查询注册表,获得可用实例
  • 注册中心可以调用服务实例的健康检查API验证其能否处理请求

解读Nacos源码

分析:

  • 服务注册
  • 服务地址的获取
  • 服务地址变化感知

Spring Cloud注册服务

Spring Cloud规范提供服务注册标准的接口为ServiceRegistry,集成到Spring Cloud中实现注册服务的组件都需要实现该接口

package org.springframework.cloud.client.serviceregistry;

public interface ServiceRegistry<R extends Registration> {
    void register(R registration);

    void deregister(R registration);

    void close();

    void setStatus(R registration, String status);

    <T> T getStatus(R registration);
}

Spring Cloud集成Nacos的实现过程

image.png
spring.factories文件类里面包含自动装配的信息,这也是SpringBoot自动装配的原理,
AutoServiceRegistrationAutoConfiguration是实现自动装配服务注册相关的配置类

@Configuration
@Import({AutoServiceRegistrationConfiguration.class})
@ConditionalOnProperty(
    value = {"spring.cloud.service-registry.auto-registration.enabled"},
    matchIfMissing = true
)
public class AutoServiceRegistrationAutoConfiguration {
    @Autowired(
        required = false
    )
    private AutoServiceRegistration autoServiceRegistration;
    @Autowired
    private AutoServiceRegistrationProperties properties;

    public AutoServiceRegistrationAutoConfiguration() {
    }

    @PostConstruct
    protected void init() {
        if (this.autoServiceRegistration == null && this.properties.isFailFast()) {
            throw new IllegalStateException("Auto Service Registration has been requested, but there is no AutoServiceRegistration bean");
        }
    }
}

//其他源代码略
//TODO


这个家伙很懒,啥也没有留下😋