SpringCloudAlibaba-Nacos服务注册与配置中心

Nacos简介

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

Nacos 的关键特性包括:

  • 服务发现和服务健康监测:Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&API查找和发现服务。
  • 动态配置服务:动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
  • 动态 DNS 服务:动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。
  • 服务及其元数据管理:Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

nacos官网https://nacos.io/zh-cn/docs/what-is-nacos.html

Nacos 快速开始

可以参考官网https://nacos.io/zh-cn/docs/quick-start.html

1. 下载源码

  • 因为github下载的速度特别慢,这里使用gitee的国内镜像下载源码,这里使用官方建议的1.3.1稳定版本

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 进入nacos目录,执行mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

在这里插入图片描述

2. 启动服务

  • 到Nacos\distribution\target\nacos-server-1.3.1\nacos\bin目录下找到startup.cmd

在这里插入图片描述

  • 右键编辑,如果是单机使用,必须是standalone,如果是集群使用,是cluster

在这里插入图片描述

  • 双击启动

在这里插入图片描述

  • 启动成功

-

  • 访问http://localhost:8848/nacos,用户名密码默认都是nacos

在这里插入图片描述
在这里插入图片描述

服务注册

参考官方文档https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery

1. 创建一个micro-order的module

在这里插入图片描述

2. 引入依赖

  • 版本之间需要匹配

在这里插入图片描述

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>micro-order</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>micro-order</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>
    <!--使用了springboot就要引入这个-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <!--springcloud版本号-->
        <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
        <!--springcloudalibaba版本号-->
        <spring.cloud.alibaba.version>2.2.3.RELEASE</spring.cloud.alibaba.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <!--需要springcloud组件支撑需要引入这个-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--需要springcloudalibaba组件支撑需要引入这个-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--web启动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--健康检查-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--服务注册-->
        <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>


    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

3. 配置文件

  • 使用bootstrap.properties,后面使用nacos作为注册中心要求文件名必须是bootstrap,不能使用application
  • 指定端口号,服务名称,nacos地址,开放全部请求端点

在这里插入图片描述

server.port=8081
spring.application.name=micro-order
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*

4. 创建启动类

  • 开启服务注册功能@EnableDiscoveryClient

在这里插入图片描述

package org.example;

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

@SpringBootApplication
@EnableDiscoveryClient
public class MicroOrderApplication {

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

5. 创建一个controller

package org.example.Controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@RestController
public class UserController {

    @RequestMapping("/queryUser")
    public String queryUser(HttpServletRequest request, HttpServletResponse response) {
        log.info("========micro-order===queryUser");
        return "========micro-order===queryUser" + request.getServerPort();
    }

}

6. 启动服务

在这里插入图片描述

  • 刷新服务列表

在这里插入图片描述

  • 再启动一个服务,使用8082端口

在这里插入图片描述

  • 创建一个启动类MicroOrderApplication2使用8082端口再次启动

在这里插入图片描述
在这里插入图片描述

  • 刷新服务列表,这时候有2个实例了

在这里插入图片描述
在这里插入图片描述

负载均衡

1. 创建一个micro-web的module

在这里插入图片描述

2. 引入依赖

<?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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>micro-web</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>micro-web</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <!--springcloud版本号-->
    <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
    <!--springcloudalibaba版本号-->
    <spring.cloud.alibaba.version>2.2.3.RELEASE</spring.cloud.alibaba.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>
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring.cloud.alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
  </dependencies>


  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

3. 配置文件

在这里插入图片描述

server.port=8091
spring.application.name=micro-web
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*

4. 创建启动类

  • 使用带有负载均衡的RestTemplate

在这里插入图片描述

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class MicroWebAppliaction {

    //开启负载均衡
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {//http请求客户端
        return new RestTemplate();
    }

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

5. 创建controller

在这里插入图片描述

package org.example.Controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@Slf4j
@RestController
public class UserController {
    //指定调用的服务名称
    private static String SERVER_NAME = "micro-order";

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/queryUser")
    public String queryUser() {
        String result = restTemplate.getForObject("http://" + SERVER_NAME
                + "/queryUser", String.class);
        log.info(result);
        return result;
    }
}

6. 启动服务

在这里插入图片描述
在这里插入图片描述

7. 服务调用

  • 第一次请求http://localhost:8091/queryUser,请求到了8082端口的micro-order

在这里插入图片描述
在这里插入图片描述

  • 第二次请求http://localhost:8091/queryUser,请求到了8081端口的micro-order

在这里插入图片描述
在这里插入图片描述

  • 这里是默认的轮询负载均衡策略

配置中心

参考官网https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config

1. 引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2. 配置文件

在这里插入图片描述

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.file-extension=properties

3. 修改controller

  • 返回从配置中心获得的值

在这里插入图片描述

package org.example.Controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//动态刷新
@RefreshScope
@Slf4j
@RestController
public class UserController {
	//获取配置中心的值
    @Value("${server-name}")
    private String serverName;
	//获取配置中心的值
    @Autowired
    Environment environment;

    @RequestMapping("/queryUser")
    public String queryUser(HttpServletRequest request, HttpServletResponse response) {
        log.info("========micro-order===queryUser");
        return "serverName=" +serverName+";environmentValue="+
                environment.getProperty("server-name");
    }

}

4. 添加配置

properties

1、micro-order

  • Data Id使用服务名称,不带properties后缀

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 对应的配置文件

在这里插入图片描述

  • 启动服务,请求http://localhost:8081/queryUser,查看打印

在这里插入图片描述
2、micro-order.properties

在这里插入图片描述
在这里插入图片描述

  • 再次请求http://localhost:8081/queryUser,不需要重启服务,查看打印

在这里插入图片描述

  • 这里实现了动态刷新配置
  • 这里得出结论,当data id只存在micro-order时,会获取micro-order配置下的值,如果data id既有micro-order又有micro-order.properties时,会优先获取micro-order.properties下的值

3、fisher-dev.properties

  • 使用fisher作为data id的前缀,dev作为-dev,.properties必须要带上
spring.cloud.nacos.config.prefix=fisher
#需要配合spring.cloud.nacos.config.prefix使用,单独使用无效
spring.profiles.active=dev

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 重启服务,请求http://localhost:8081/queryUser,查看打印

在这里插入图片描述

yaml

1、micro-order

  • 配置文件使用bootstrap.yml

在这里插入图片描述

  • 把之前的data id为micro-order的配置改为yaml格式,这里server-name: micro-order使用冒号,不能用等号

在这里插入图片描述
在这里插入图片描述

  • 重启服务,请求http://localhost:8081/queryUser,查看打印

在这里插入图片描述
2、micro-order.yaml

  • 添加data id为micro-order.yaml的配置

在这里插入图片描述
在这里插入图片描述

  • 再次请求http://localhost:8081/queryUser,不需要重启服务,查看打印

在这里插入图片描述

  • 和properties格式的配置一样,这里也实现了动态刷新配置
  • 同样的结论,当data id只存在micro-order时,会获取micro-order配置下的值,如果data id既有micro-order又有micro-order.yaml时,会优先获取micro-order.yaml下的值
    3、myPrefix.yaml
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

nacos的弱一致性协议distro

  • nacos支持cap理论中的cp和ap,ap使用的是distro协议,cp使用的是raft协议,这里介绍阿里自研的弱一致性协议distro。
  1. Client 与 Server 有两个重要的交互,服务注册与心跳发送;
  2. Client 向 Server 注册一个服务,继而以执行任务的模式向 Server 发送一次心跳,心跳包需要带上 Client 的全部信息, 站在 Client 的角度 Server 集群所有的节点对等,所以请求 Server 集群中的节点是随机的;
  3. Client 如果请求失败则换一个 Server 的节点重新发送请求;
  4. Server 集群的任意一个节点都存储所有数据,但每个节点只负责其中一部分服务,在接收到 Client 的“写“(注册、心跳、下线等)请求后,Server 节点判断请求的服务是否为自己负责,如果是,则处理,否则交由负责的节点处理;
  5. 每个 Server 节点主动发送健康检查到其他节点,响应的节点被该节点视为健康节点;
  6. Server 在接收到 Client 的心跳后,如果该服务不存在,则将该心跳请求当做注册请求来处理;
  7. Server 如果 15s 没有收到 Client 心跳,则把该 Client 标记为不健康;如果 30s 没有收到心跳,则下线该 Client ;
  8. 负责的 Server 节点在接收到 Client 的服务注册、服务心跳等写请求后将数据写入后即返回,后台异步地将数据同步给其他节点;
  9. Server 节点在收到读请求后直接从本机获取后返回,不管数据是否为最新 com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl#put taskDispatcher.addTask(key);
  10. 任意一个 Server 节点在启动的时候会去判断当前 Server 集群当中的节点是否大于 1;如果大于 1 则会去执行远程同步;否则会让线程睡眠 1s 继续判断集群节点是否大于 1;
  11. Client 在启动的时候(spring 容器启动的时候会实例化 NacosAutoServiceRegistration,会实例化 NacosServiceRegistry 构造方法,里面会调用 namingServiceInstance—>createNamingService---- >createNamingService–>new NacosNamingService—构造方法— init----xxxx----udp 等待 Server 发送数据)会建立一个 UDP 的接受方;Client 在向 Server 获取服务列表的时候 Server 会收集到 Client 的 UDP 信息;以后当 Server 更新的时候会把更新信息推送给 Client ;但是 Server 默认不发这个 Client 的?因为 Server 不知道这个 Client 需要数据;
  12. Client 在第一次向 Server 获取服务列表的时候;会创建一个线程池每隔 10s 钟会去 Server 获取一次最新的服务列表, 同时还会把当前 Client 的所有信息(包括udp)发给Server,Server 接受到信息之后把 Client 添加到发送 upd 的列表当中;
  13. Client 会把服务列表缓存到本地,下次请求会直接从本地缓存拿服务列表,如果 Server 中的服务列表有变化,就会通过 udp 把最新的服务列表发送给 Client ;
  14. distro 判断一个请求属于 Server 集群中的那个节点负责用的是一个非常简单的 hash 算法(int target = distroHash(serviceName) % healthyList.size();),假设 Server 某个节点发生故障,则会重新计算,其实可以采用一致性的 hash 算法,这样只会重新计算以前分发到这个故障节点的机器上的请求, 不需要全部重新计算。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值