nacos 實戰(史上最全)


目錄:小圈的 springCloud 高併發系列

推薦閱讀
nacos 實戰(史上最全)
sentinel (史上最全+入門教程)
springcloud + webflux 高併發實戰
Webflux(史上最全)
SpringCloud gateway (史上最全)
和 1000+ Java 高併發 發燒友、 一塊兒 交流 、學習、入大廠、作架構,GO

一、Nacos 優點

問題,既然有了Eureka ,爲啥還要用Nacos?

而 Nacos 做爲微服務核心的服務註冊與發現中心,讓你們在 Eureka 和 Consule 以外有了新的選擇,開箱即用,上手簡潔,暫時也沒發現有太大的坑。git

1.1與eureka對比

1 eureka 2.0閉源碼了。web

2 從官網來看nacos 的註冊的實例數是大於eureka的,面試

3 由於nacos使用的raft協議,nacos集羣的一致性要遠大於eureka集羣.redis

分佈式一致性協議 Raft,自 2013 年論文發表,以後就受到了技術領域的熱捧,與其餘的分佈式一致性算法比,Raft 相對比較簡單而且易於實現,這也是 Raft 能異軍突起的主要因素。算法

img

Raft 的數據一致性策略

Raft 協議強依賴 Leader 節點來確保集羣數據一致性。即 client 發送過來的數據均先到達 Leader 節點,Leader 接收到數據後,先將數據標記爲 uncommitted 狀態,隨後 Leader 開始向全部 Follower 複製數據並等待響應,在得到集羣中大於 N/2 個 Follower 的已成功接收數據完畢的響應後,Leader 將數據的狀態標記爲 committed,隨後向 client 發送數據已接收確認,在向 client 發送出已數據接收後,再向全部 Follower 節點發送通知代表該數據狀態爲committed。spring

1.2與springcloud config 對比

三大優點:

  • springcloud config大部分場景結合git 使用, 動態變動還須要依賴Spring Cloud Bus 消息總線來經過全部的客戶端變化.sql

  • springcloud config不提供可視化界面

  • nacos config使用長鏈接更新配置, 一旦配置有變更後,通知Provider的過程很是的迅速, 從速度上秒殺springcloud原來的config幾條街,

二、Spring Cloud Alibaba 套件

目前 Spring Cloud Alibaba 主要有三個組件:

  • Nacos:一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。

  • Sentinel:把流量做爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。

  • AliCloud OSS: 阿里雲對象存儲服務(Object Storage Service,簡稱
    OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。您能夠在任何應用、任什麼時候間、任何地點存儲和訪問任意類型的數據。

Spring Cloud Alibaba 套件和Spring Cloud Netflix套件類比

仔細看看各組件的功能描述,Spring Cloud Alibaba 套件和Spring Cloud Netflix套件大體的對應關係:

  • Nacos = Eureka/Consule + Config + Admin
  • Sentinel = Hystrix + Dashboard + Turbine
  • Dubbo = Ribbon + Feign
  • RocketMQ = RabbitMQ
  • Schedulerx = Quartz
  • AliCloud OSS、AliCloud SLS 這三個應該是獨有的
    鏈路跟蹤(Sleuth、Zipkin)不知道會不會在 Sentinel 裏
    以上只是猜想,待我從坑裏爬出來以後再回來更新。也歡迎你們一塊兒交流探討~
    這裏我就先試試 Nacos。

三、Nacos 的架構和安裝

3.一、Nacos 的架構

image

這是 Nacos 的架構圖,能夠看到它確實是融合了服務註冊發現中心、配置中心、服務管理等功能,相似於 Eureka/Consule + Config + Admin 的合體。

另外經過官方文檔發現,Nacos 除了能夠和 Spring Cloud 集成,還能夠和 Spring、SpringBoot 進行集成。

不過咱們只關注於 Spring Cloud,別的就略過了,直接上手實戰吧。

3.二、Nacos Server 的下載和安裝

在使用 Nacos 以前,須要先下載 Nacos 並啓動 Nacos Server。

安裝的參考教程:

http://www.javashuo.com/article/p-cyttksif-oa.html

四、Nacos Server 的運行

4.1兩種模式

Nacos Server 有兩種運行模式:

  • standalone
  • cluster

4.二、standalone 模式

此模式通常用於 demo 和測試,不用改任何配置,直接敲如下命令執行

sh bin/startup.sh -m standalone

Windows 的話就是

cmd bin/startup.cmd -m standalone

而後從 http://cdh1:8848/nacos/index.html 進入控制檯就能看到以下界面了

image

默認帳號和密碼爲:nacos nacos

4.三、cluster 模式

測試環境,能夠先用 standalone 模式擼起來,享受 coding 的快感,可是,生產環境可使用 cluster 模式。

cluster 模式須要依賴 MySQL,而後改兩個配置文件:

conf/cluster.conf
conf/application.properties

大體以下:

1: cluster.conf,填入要運行 Nacos Server 機器的 ip

192.168.100.155
192.168.100.156
  1. 修改NACOS_PATH/conf/application.properties,加入 MySQL 配置
db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=root

建立一個名爲nacos_config的 database,將NACOS_PATH/conf/nacos-mysql.sql中的表結構導入剛纔建立的庫中,這幾張表的用途就本身研究吧

4.4 Nacos Server 的配置數據是存在哪裏呢?

問題來了: Nacos Server 的配置數據是存在哪裏呢?

咱們沒有對 Nacos Server 作任何配置,那麼數據只有兩個位置能夠存儲:

  • 內存
  • 本地數據庫

若是咱們如今重啓剛剛在運行的 Nacos Server,會發現剛纔加的 nacos.properties 配置還在,說明不是內存存儲的。

這時候咱們打開NACOS_PATH/data,會發現裏邊有個derby-data目錄,咱們的配置數據如今就存儲在這個庫中。

Derby 是 Java 編寫的數據庫,屬於 Apache 的一個開源項目

若是將數據源改成咱們熟悉的 MySQL 呢?固然能夠。

注意:不支持 MySQL 8.0 版本

這裏有兩個坑:

Nacos Server 的數據源是用 Derby 仍是 MySQL 徹底是由其運行模式決定的:

standalone 的話僅會使用 Derby,即便在 application.properties 裏邊配置 MySQL 也照樣無視;
cluster 模式會自動使用 MySQL,這時候若是沒有 MySQL 的配置,是會報錯的。

官方提供的 cluster.conf 示例以下

#it is ip
#example
10.10.109.214
11.16.128.34
11.16.128.36
12345

以上配置結束後,運行 Nacos Server 就能看到效果了。

5 實戰1:使用Nacos做爲註冊中心

實戰的工程

實戰的工程的目錄結構以下:

在這裏插入圖片描述

5.1如何使用Nacos Client組件

首先引入 Spring Cloud Alibaba 的 BOM

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath/>
</parent>
<properties>
    <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    <spring-cloud-alibaba.version>0.2.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

這裏版本號有坑,文檔上說和 Spring Boot 2.0.x 版本兼容,可是實測 2.0.6.RELEASE 報錯

java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapable

5.二、演示的模塊結構

服務註冊中心和服務發現的服務端都是由 Nacos Server 來提供的,咱們只須要提供 Service 向其註冊就行了。

這裏模擬提供兩個 service:provider 和 consumer

alibaba
├── service-provider-demo
│   ├── pom.xml
│   └── src
└── sevice-consumer-demo
│   ├── pom.xml
│   └── src
└── pom.xml

5.三、provider 微服務

step1:在 provider 和 consumer 的 pom 添加如下依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

step2:啓動類

使用 Spring Cloud 的原生註解 @EnableDiscoveryClient 開啓服務註冊與發現

package com.crazymaker.cloud.nacos.demo.starter;

import com.crazymaker.springcloud.standard.context.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

@EnableSwagger2
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class ServiceProviderApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext =   SpringApplication.run(ServiceProviderApplication.class, args);

        Environment env = applicationContext.getEnvironment();
        String port = env.getProperty("server.port");
        String path = env.getProperty("server.servlet.context-path");
        System.out.println("\n--------------------------------------\n\t" +
                "Application is running! Access URLs:\n\t" +
                "Local: \t\thttp://localhost:" + port + path+ "/index.html\n\t" +
               "swagger-ui: \thttp://localhost:" + port + path + "/swagger-ui.html\n\t" +
                "----------------------------------------------------------");

    }
}

step3:服務提供者的 Rest 服務接口

service-provider-demo 提供 一個很是簡單的 Rest 服務接口以供訪問

package com.crazymaker.cloud.nacos.demo.controller;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/echo")
public class EchoController {
    //回顯服務
    @RequestMapping(value = "/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
        return "echo: " + string;
    }
}

step4:配置文件

spring:
  application:
    name: service-provider-demo
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER:cdh1:8848}
server:
  port: 18080

step5:啓動以後,經過swagger UI訪問:

在這裏插入圖片描述

5.四、Consumer 微服務演示RPC遠程調用

在 NacosConsumerApplication 中集成 RestTemplate 和 Ribbon

@LoadBalanced
@Bean
public RestTemplate restTemplate() {
  return new RestTemplate();
}

消費者的controller 類

package com.crazymaker.cloud.nacos.demo.consumer.controller;

import com.crazymaker.cloud.nacos.demo.consumer.client.EchoClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/echo")
@Api(tags = "服務- 消費者")
public class EchoConsumerController {


    //注入 @FeignClient 註解配置 所配置的 EchoClient 客戶端Feign實例
    @Resource
    EchoClient echoClient;


    //回顯服務
    @ApiOperation(value = "消費回顯服務接口")
    @RequestMapping(value = "/{string}", method = RequestMethod.GET)
    public String echoRemoteEcho(@PathVariable String string) {
        return "provider echo is:" + echoClient.echo(string);
    }
}

消費者配置文件

spring:
  application:
    name: sevice-consumer-demo
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
server:
  port: 18081

經過swagger UI訪問消費者:

在這裏插入圖片描述

訪問遠程的echo API:

在這裏插入圖片描述

在這裏插入圖片描述

5.5涉及到的演示地址:

服務提供者 service-provider-demo:

http://localhost:18080/provider/swagger-ui.html#/Echo_%E6%BC%94%E7%A4%BA

服務消費者:

[http://localhost:18081/consumer/swagger-ui.html#/服務- 消費者/echoRemoteEchoUsingGET](http://localhost:18081/consumer/swagger-ui.html#/服務- 消費者/echoRemoteEchoUsingGET)

註冊中心Nacos:

http://cdh1:8848/nacos/index.html#/serviceManagement?dataId=&group=&appName=&namespace=

5.六、Nacos Console

這時候查看 Nacos Console 也能看到已註冊的服務列表及其詳情

在這裏插入圖片描述

六、實戰2:使用Nacos做爲配置中心

6.一、基本概念

1. Profile

Java項目通常都會有多個Profile配置,用於區分開發環境,測試環境,準生產環境,生成環境等,每一個環境對應一個properties文件(或是yml/yaml文件),而後經過設置 spring.profiles.active 的值來決定使用哪一個配置文件。

例子:

spring:
  application:
    name: sharding-jdbc-provider
  jpa:
    hibernate:
      ddl-auto: none
      dialect: org.hibernate.dialect.MySQL5InnoDBDialect
      show-sql: true
  profiles:
     active: sharding-db-table    # 分庫分表配置文件
    #active: atomiclong-id    # 自定義主鍵的配置文件
    #active: replica-query    # 讀寫分離配置文件

Nacos Config的做用就把這些文件的內容都移到一個統一的配置中心,即方便維護又支持實時修改後動態刷新應用。

2. Data ID

當使用Nacos Config後,Profile的配置就存儲到Data ID下,即一個Profile對應一個Data ID

Data ID的拼接格式:${prefix} - ${spring.profiles.active} . ${file-extension}

  • prefix 默認爲 spring.application.name 的值,也能夠經過配置項 spring.cloud.nacos.config.prefix 來配置

  • spring.profiles.active 取 spring.profiles.active 的值,即爲當前環境對應的 profile

  • file-extension 爲配置內容的數據格式,能夠經過配置項 spring.cloud.nacos.config.file-extension 來配置

3. Group

Group 默認爲 DEFAULT_GROUP,能夠經過 spring.cloud.nacos.config.group 來配置,當配置項太多或者有重名時,能夠經過分組來方便管理

最後就和原來使用springcloud同樣經過@RefreshScope 和@Value註解便可

6.2 經過Nacos的console 去增長配置

這回首先要在nacos中配置相關的配置,打開Nacos配置界面,依次建立2個Data ID

  • nacos-config-demo-dev.yaml 開發環境的配置
  • nacos-config-demo-test.yaml 測試環境的配置

一、nacos-config-demo-dev.yaml

內容以下圖:

在這裏插入圖片描述

二、nacos-config-demo-sit.yaml

內容以下圖:

在這裏插入圖片描述

6.3 使用Nacos Config Client組件

問題2:微服務Provider實例上,如何使用Nacos Config Client組件的有哪些步驟?

1 加載nacos config 的客戶端依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${nacos.version}</version>
</dependency>

啓動類

package com.crazymaker.cloud.nacos.demo.consumer.starter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@EnableSwagger2
@EnableDiscoveryClient
@Slf4j
@SpringBootApplication(
        scanBasePackages =
                {
                        "com.crazymaker.cloud.nacos.demo",
                        "com.crazymaker.springcloud.standard"
                },
        exclude = {SecurityAutoConfiguration.class,
                //排除db的自動配置
                DataSourceAutoConfiguration.class,
                DataSourceTransactionManagerAutoConfiguration.class,
                HibernateJpaAutoConfiguration.class,
                //排除redis的自動配置
                RedisAutoConfiguration.class,
                RedisRepositoriesAutoConfiguration.class})
//啓動Feign
@EnableFeignClients(basePackages =
        {"com.crazymaker.cloud.nacos.demo.consumer.client"})
public class ConfigDomeProviderApplication
{
    public static void main(String[] args)
    {
        ConfigurableApplicationContext applicationContext = null;
        try
        {
            applicationContext = SpringApplication.run(ConfigDomeProviderApplication.class, args);
            System.out.println("Server startup done.");
        } catch (Exception e)
        {
            log.error("服務啓動報錯", e);
            return;
        }

        Environment env = applicationContext.getEnvironment();
        String port = env.getProperty("server.port");
        String path = env.getProperty("server.servlet.context-path");
        System.out.println("\n----------------------------------------------------------\n\t" +
                "Application is running! Access URLs:\n\t" +
                "Local: \t\thttp://localhost:" + port + path + "/index.html\n\t" +
                "swagger-ui: \thttp://localhost:" + port + path + "/swagger-ui.html\n\t" +
                "----------------------------------------------------------");

    }
}

控制類:

package com.crazymaker.cloud.nacos.demo.config.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/config")
@Api(tags = "Nacos 配置中心演示")
public class ConfigGetController {


    @Value("${foo.bar:empty}")
    private String bar;


    @Value("${spring.datasource.username:empty}")
    private String dbusername;

    //獲取配置的內容
    @ApiOperation(value = "獲取配置的內容")
    @RequestMapping(value = "/bar", method = RequestMethod.GET)
    public String getBar() {
        return "bar is :"+bar;
    }
    //獲取配置的內容
    @ApiOperation(value = "獲取配置的db username")
    @RequestMapping(value = "/dbusername", method = RequestMethod.GET)
    public String getDbusername() {
        return "db username is :"+bar;
    }
}

2 bootstrap配置文件

而後是在配置文件(bootstrap.yml)中加入如下的內容:

spring:
  application:
    name: nacos-config-demo-provider
  profiles:
    active:  dev
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER:cdh1:8848}
      config:
        server-addr: ${NACOS_SERVER:cdh1:8848}
        prefix: nacos-config-demo
        group: DEFAULT_GROUP
        file-extension: yaml
server:
  port: 18083
  servlet:
    context-path: /config

6.4 測試結果

啓動程序,經過swagger ui訪問:

http://localhost:18083/config/swagger-ui.html#

在這裏插入圖片描述

執行結果以下:

在這裏插入圖片描述

6.4 能夠端如何與服務端的配置文件相互對應

  • config.prefix 來對應主配置文件

  • 使用spring.cloud.nacos.config.ext-config 選項來對應更多的文件

    eg:

spring:
  application:
    name: nacos-config-demo-provider
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_SERVER:cdh1:8848}
      config:
        server-addr: ${NACOS_SERVER:cdh1:8848}
        prefix: nacos-config-demo
        group: DEFAULT_GROUP
        file-extension: yaml
        ext-config:
          - data-id: crazymaker-db-dev.yml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: crazymaker-redis-dev.yml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: crazymaker-common-dev.yml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: some.properties
            group: DEFAULT_GROUP
            refresh: true

啓動程序,發現能夠獲取到其餘data-id的配置 ,你們能夠自行配置。

七、配置的隔離

在實際的應用中,存在着如下幾種環境隔離的要求:

一、開發環境、測試環境、準生產環境和生產環境須要隔離

二、不一樣項目須要隔離

三、同一項目,不一樣的模塊須要隔離

能夠經過三種方式來進行配置隔離:Nacos的服務器、namespace命名空間、group分組,在bootstrap.yml文件中能夠經過配置Nacos的server-addr、namespace和group來區分不一樣的配置信息。

  • Nacos的服務器 spring.cloud.nacos.config.server-addr
  • Nacos的命名空間 spring.cloud.nacos.config.namespace,注意,這裏使用命名空間的ID不是名稱
  • Nacos的分組 spring.cloud.nacos.config.group
相關文章
相關標籤/搜索