SpringCloud Alibaba之 Nacos注册中心

文章目录

  • Nacos 更加全能的注册中心
    • 一、安装与部署 (服务端)
    • 二、服务注册与发现 (客户端)
      • 2.1 引入依赖
      • 2.2 启动类注解
      • 2.3 配置文件
      • 2.4 OpenFeign 远程调用
      • 2.5 OpenFeign 负载均衡
      • 2.6 临时实例和非临时实例
    • 三、集群分区
      • 3.1 开启集群分区
      • 3.2 开启区域优先调用机制
      • 3.3 开启权重优先调用机制
    • 四、配置中心
      • 4.1 Nacos 配置管理
      • 4.2 配置文件热更新
    • 五、命名空间
    • 六、实现可用性
      • 6.1 云服务环境准备
      • 6.2 配置外置数据源
      • 6.3 配置集群配置文件
      • 6.4 启动 nacos 集群
      • 6.5 Nginx 反向代理


提示:以下是本篇文章正文内容,SpringCloud Alibaba 系列学习将会持续更新

Spring Cloud Alibaba 官方学习文档
SpringCloud Alibaba之 Nacos注册中心_第1张图片

Nacos 更加全能的注册中心

Nacos(Naming Configuration Service)是一款阿里巴巴开源的服务注册与发现、配置管理的组件,相当于是 Eureka + Config 的组合形态。

一、安装与部署 (服务端)

①Nacos 服务器是独立安装部署的,因此我们需要下载最新的 Nacos 服务端程序,下载地址:https://github.com/alibaba/nacos
SpringCloud Alibaba之 Nacos注册中心_第2张图片
SpringCloud Alibaba之 Nacos注册中心_第3张图片
可以看到目前最新的版本是2.2.0.1版本(2023年03月02日发布的)。由于网络原因,所以我就从网上找了 2.0.3 版本的。

②接着我们将文件进行解压,得到以下内容:
SpringCloud Alibaba之 Nacos注册中心_第4张图片

③我们直接将其拖入到项目文件夹下,便于我们一会在 IDEA 内部启动,接着添加运行配置:
SpringCloud Alibaba之 Nacos注册中心_第5张图片

  • 其中 -m standalone 表示单节点模式。
  • Mac 和 Linux 下记得将 解释器路径 Interpreter path 设定为 /bin/bash
  • Nacos 在 Windows 下只能前台执行。而在 Mac/Linux 默认是后台启动模式,我们修改一下它的 startup.sh 文件,让它变成前台启动,这样 IDEA 关闭了 Nacos 就自动关闭了,否则开发环境下很容易忘记关。
# 注释掉最后两行
# nohup "$JAVA" "$JAVA_OPT_EXT_FIX" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
# echo "nacos is starting,you can check the ${BASE_DIR}/logs/start.out"
# 替换成下面的
$JAVA ${JAVA_OPT} nacos.nacos

④接着我们点击启动:
SpringCloud Alibaba之 Nacos注册中心_第6张图片
OK,启动成功。访问地址:http://localhost:8848/nacos/index.html
SpringCloud Alibaba之 Nacos注册中心_第7张图片
默认的用户名 和 管理员密码都是 nacos,直接登陆即可,可以看到进入管理页面之后功能也是相当丰富.
SpringCloud Alibaba之 Nacos注册中心_第8张图片
至此,Nacos 的安装与部署完成。

回到目录…

二、服务注册与发现 (客户端)

2.1 引入依赖

现在我们要实现基于 Nacos 的服务注册与发现,那么就需要导入 SpringCloudAlibaba 相关的依赖,我们在父工程将依赖进行管理:

<dependencyManagement>
    <dependencies>
      	
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>2021.0.1version>
          	<type>pomtype>
            <scope>importscope>
        dependency>
     	
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-alibaba-dependenciesartifactId>
            <version>2021.0.1.0version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

客户端:接着我们就可以在子项目中添加服务发现依赖了,比如我们以图书服务为例:

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>

2.2 启动类注解

我们需要用 @EnableDiscoveryClient 注解修饰所有服务启动类,这一步也可以省略。

@EnableDiscoveryClient
@SpringBootApplication
public class BookApplication {
    public static void main(String[] args) {
        SpringApplication.run(BookApplication.class, args);
    }
}

2.3 配置文件

和注册到 Eureka 一样,我们也需要在服务们的配置文件中配置 Nacos 注册中心的地址:

spring:
  application:
    name: bookservice
  cloud:
    nacos:
      discovery:
        # 配置 Nacos注册中心地址
        server-addr: localhost:8848

接着启动我们的图书服务,可以在 Nacos 的服务列表中找到:
在这里插入图片描述

我们可以将其它两个服务也注册到 Nacos 中
SpringCloud Alibaba之 Nacos注册中心_第9张图片

回到目录…

2.4 OpenFeign 远程调用

例如,我们的 borrowervice 服务需要远程调用另外两个服务,那么我们需要使用 OpenFeign,实现服务发现远程调用以及负载均衡。

①先在我们的 borrowservice 消费端导入依赖:

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
dependency>


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-loadbalancerartifactId>
dependency>

消费端的启动类添加 @EnableFeignClients 注解:

@EnableFeignClients
@SpringBootApplication
public class BorrowApplication {
    public static void main(String[] args) {
        SpringApplication.run(BorrowApplication.class, args);
    }
}

③编写远程接口:

  • 可以选择把接口创建到本系统模块的某个包下,但该接口仅能被该服务模块调用,这种方式仅适用于学习阶段。
  • 也可以创建 API 模块,将所有的远程接口放在该模块下。这样远程接口就可以被其它微服务共用了,这是分布式开发的推荐模式
    SpringCloud Alibaba之 Nacos注册中心_第10张图片
@FeignClient("bookservice")
public interface BookClient {
    @RequestMapping("/book/{bid}")
    Book getBookById(@PathVariable("bid") int bid);
}

④借阅服务中,调用接口 (远程调用):

@Service
public class BorrowServiceImpl implements BorrowService{
    @Resource
    BorrowMapper mapper;
    @Resource
    UserClient userClient;
    @Resource
    BookClient bookClient;

    @Override
    public UserBorrowDetail getUserBorrowDetailByUid(int uid) {
        List<Borrow> borrow = mapper.getBorrowsByUid(uid);
        User user = userClient.getUserById(uid);
        List<Book> bookList = borrow
                .stream()
                .map(b -> bookClient.getBookById(b.getBid()))
                .collect(Collectors.toList());
        return new UserBorrowDetail(user, bookList);
    }
}

启动,发现可以实现远程调用了!
在这里插入图片描述

回到目录…

2.5 OpenFeign 负载均衡

测试正常,可以自动发现服务,接着我们来多配置几个实例:
SpringCloud Alibaba之 Nacos注册中心_第11张图片

然后我们在图书服务和用户服务中添加日志打印方便之后查看:

@Slf4j
@Service
public class BookServiceImpl implements BookService {
    @Resource
    private BookMapper bookMapper;
    @Resource
    private Environment environment;
    
    @SneakyThrows
    @Override
    public Book getBookById(int bid) {
        String hostIp = InetAddress.getLocalHost().getHostAddress();
        String port = environment.getProperty("server.port");
        log.info(hostIp + ":" + port + " 的findBookById()被访问了!");
        return bookMapper.getBookById(bid);
    }
}

现在将全部服务启动:
SpringCloud Alibaba之 Nacos注册中心_第12张图片

可以看到 Nacos 中的实例数量已经显示为 2:
在这里插入图片描述

接着我们多次访问 http://localhost:8082/borrow/2 ,调用借阅服务,看看能否负载均衡远程调用:
在这里插入图片描述
在这里插入图片描述
OK,负载均衡远程调用没有问题,这样我们就实现了基于 Nacos 的服务的注册与发现,实际上大致流程与 Eureka 一致。

回到目录…

2.6 临时实例和非临时实例

值得注意的是,Nacos 区分了临时实例和非临时实例:
SpringCloud Alibaba之 Nacos注册中心_第13张图片

那么临时和非临时有什么区别呢?

  • 临时实例:和 Eureka 一样,采用心跳机制向 Nacos 发送请求保持在线状态,一旦心跳停止,代表实例下线,不保留实例信息。(当然现在 Eureka 有了自动保护机制)
  • 非临时实例:由 Nacos 主动进行联系,如果连接失败,那么不会移除实例信息,而是将健康状态设定为 false,相当于会对某个实例状态持续地进行监控。

我们可以通过配置文件进行修改临时实例:

spring:
  application:
    name: bookservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        # 将 ephemeral 修改为false,表示非临时实例
        ephemeral: false

接着我们在 Nacos 中查看,可以发现实例已经不是临时的了:可能需要重启 Nacos-Server
在这里插入图片描述
如果这时我们关闭一个实例,那么会变成这样:
在这里插入图片描述
只是将健康状态变为 false,而不会删除实例的信息。

回到目录…

三、集群分区

我们之前已经做过的 Eureka 集群,是这样配置的:没有做分区

server:
  port: 8802
spring:
  application:
    name: eurekaserver
eureka:
  instance:
    hostname: eureka02
  client:
    fetch-registry: false
    service-url:
      defaultZone: http://eureka01:8801/eureka
      # 这个defaultZone是个啥玩意,为什么要用这个名称?为什么要要用这样的形式来声明注册中心?

在一个分布式应用中,相同服务的实例可能会在不同的机器、位置上启动,比如我们的用户管理服务,可能在成都有1台服务器部署、重庆有一台服务器部署,而这时,我们在成都的服务器上启动了借阅服务,那么如果我们的借阅服务现在要调用用户服务,就应该优先选择同一个区域的用户服务进行调用,这样会使得响应速度更快。
SpringCloud Alibaba之 Nacos注册中心_第14张图片

因此,我们可以对部署在不同机房的服务进行分区,可以看到实例的默认集群分区: DEFAULT
SpringCloud Alibaba之 Nacos注册中心_第15张图片

3.1 开启集群分区

我们可以直接在配置文件中进行修改:

spring:
  application:
    name: borrowservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        # 修改为重庆地区的集群
        cluster-name: Chongqing

当然,如果我们需要不同的启动配置,也可以直接在启动配置项中添加环境变量-Dspring.cloud.nacos.discovery.cluster-name
这里我们将 用户服务 的两个实例分配到不同的区域:重庆、成都
SpringCloud Alibaba之 Nacos注册中心_第16张图片

修改完成之后,我们来尝试重新启动一下(Nacos也要重启),观察 Nacos 中集群分布情况:
SpringCloud Alibaba之 Nacos注册中心_第17张图片

可以看到现在有两个集群,并且都有一个实例正在运行。我们接着去调用借阅服务,但是发现并没有按照区域进行优先调用,而依然使用的是 轮询模式 的负载均衡调用。

回到目录…

3.2 开启区域优先调用机制

我们必须要提供 Nacos 的负载均衡实现才能开启区域优先调用机制,只需要在 borrowservice 的配制文件中进行修改:

spring:
  application:
    name: borrowservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: Chongqing
    # 将 loadbalancer 的 nacos 支持开启,集成 Nacos 负载均衡
    loadbalancer:
      nacos:
        enabled: true

现在我们重启借阅服务,会发现优先调用的是同区域的用户服务
SpringCloud Alibaba之 Nacos注册中心_第18张图片
如果我们把同区域的用户服务下线,那么借阅服务就只能调用其它区域的用户服务了。

3.3 开启权重优先调用机制

除了根据区域优先调用之外,同一个区域内的实例也可以单独设置权重值,Nacos 会优先选择权重更大的实例进行调用,我们可以直接在管理页面中进行配置:
SpringCloud Alibaba之 Nacos注册中心_第19张图片

或是在配置文件中进行配置:

spring:
  application:
    name: bookservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: Chengdu
        # 权重大小,越大越优先调用,默认为 1
        weight: 0.5

通过配置权重,某些性能不太好的机器就能够更少地被使用,而更多的使用那些网络良好性能更高的主机上的实例。

回到目录…

四、配置中心

前面我们学习了 SpringCloud Config,我们可以通过配置服务来加载远程配置,这样我们就可以在远端集中管理配置文件。

我们可以在 bootstrap.yml 中配置远程配置文件获取,然后再进入到配置文件加载环节,而 Nacos 也支持这样的操作。

4.1 Nacos 配置管理

①比如我们现在想要将图书服务的配置文件放到 Nacos 进行管理,那么这个时候就需要在 Nacos 中创建配置文件:
SpringCloud Alibaba之 Nacos注册中心_第20张图片

注意: Data ID 的格式跟我们之前一样,应用名称-环境.yml,如果只编写应用名称,那么代表此配置文件无论在什么环境下都会使用,然后每个配置文件都可以进行分组,也算是一种分类方式:
SpringCloud Alibaba之 Nacos注册中心_第21张图片

完成之后点击发布即可:
在这里插入图片描述

②然后在图书服务模块中导入依赖:

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-bootstrapartifactId>
dependency>
<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>

③接着我们在图书服务中添加 bootstrap.yml 文件: 原本的 application.yml 想删就删了

server:
  port: 8081
spring:
  application:
    name: bookservice  # 服务名称和配置文件保持一致
  profiles:
    active: dev  # 环境也是和配置文件保持一致
  cloud:
    nacos:
      config:
        file-extension: yml  # 配置文件后缀名
        # 配置中心服务器地址,也就是 Nacos 地址
        server-addr: localhost:8848

现在我们启动服务试试看:
在这里插入图片描述
可以看到成功读取配置文件并启动了,实际上使用上来说跟之前的 Config 是基本一致的。

回到目录…

4.2 配置文件热更新

Nacos 还支持配置文件的热更新: 比如我们在配置文件中新增/更改了一个属性,我们后端就可以收到信息并实时更新。

①比如:我们在配置文件新增一个属性。
在这里插入图片描述

当我们发布修改后的配置文件,后端立刻发现了。
在这里插入图片描述

②我们可以再创建一个 Controller 进行接收属性,来观察现象:需要用 @RefreshScope 注解修饰,以即时刷新接收到的信息。

@RestController
@RefreshScope
public class TestController {

    @Value("${my.name}") // org.springframework.beans.factory.annotation.Value
    private String name;

    @GetMapping("/name")
    public String getName() {
        return name;
    }
}

③现象: 访问获取的属性值。
SpringCloud Alibaba之 Nacos注册中心_第22张图片

我们修改一下配置文件:不需要重启
在这里插入图片描述
后端已经发现,配置文件中的属性值改变了。
在这里插入图片描述
再次访问,发现拿到新的数据了。
在这里插入图片描述

回到目录…

五、命名空间

我们还可以将配置文件或是服务实例划分到不同的命名空间中,其实就是区分开发、生产环境或是引用归属之类的:
在这里插入图片描述
这里我们创建一个新的命名空间:ID 可以自动生成
SpringCloud Alibaba之 Nacos注册中心_第23张图片

可以看到在 dev 命名空间下,没有任何配置文件和服务:
SpringCloud Alibaba之 Nacos注册中心_第24张图片

我们在不同的命名空间下,实例和配置都是相互之间隔离的。我们也可以在配置文件中指定当前的命名空间:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: 空间ID

回到目录…

六、实现可用性

本小节我们用 Linux 云服务器(Nacos 比较吃内存,2个Nacos服务器集群,至少2G内存)。

通过前面的学习,我们已经了解了如何使用 Nacos 以及 Nacos 的功能等,最后我们来看看,如果像之前 Eureka 一样,搭建 Nacos 集群,实现高可用。

官方部署说明:https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html

集群部署架构图:

因此开源的时候推荐用户把所有服务列表放到一个vip下面,然后挂到一个域名下面

  • http://ip1:port/openAPI 直连 ip 模式,机器挂则需要修改 ip 才可以使用。
  • http://SLB:port/openAPI 挂载 SLB 模式 (内网 SLB,不可暴露到公网,以免带来安全风险),直连SLB 即可,下面挂server 真实ip,可读性不好。
  • http://nacos.com:port/openAPI 域名 + SLB模式 (内网SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换ip方便,推荐模式

SpringCloud Alibaba之 Nacos注册中心_第25张图片
我们来看看它的架构设计,它推荐我们在所有的 Nacos 服务端之前建立一个负载均衡,我们通过访问负载均衡服务器来间接访问到各个 Nacos 服务器。实际上就,是比如有三个 Nacos 服务器做集群,但是每个服务不可能把每个 Nacos 都去访问一次进行注册,实际上只需要在任意一台 Nacos 服务器上注册即可,Nacos 服务器之间会自动同步信息,实现了整个集群高可用的状态。

  • 所以这里就需要在所有 Nacos 服务器之前搭建一个 SLB(服务器负载均衡),这样就可以避免上面的问题了。但是我们知道,如果要实现外界对服务访问的负载均衡,我们就得用比如之前说到的Gateway 来实现,而这里实际上我们可以用一个更加方便的工具:Nginx 来实现。

  • 关于 SLB 最上方还有一个 DNS,这个是因为 SLB 是裸 IP,如果 SLB 服务器修改了地址,那么所有微服务注册的地址也得改,所以这里是通过加域名,通过域名来访问,让 DNS 去解析真实 IP,这样就算改变 IP,只需要修改域名解析记录即可,域名地址是不会变化的。(由于成本高,这里我们就不搞了)

6.1 云服务环境准备

①云服务器:64 bit OS Linux/Unix/Mac,推荐使用 Linux 系统。

②下载安装 64 bit JDK 1.8+

③下载安装 MariaDB (MySQL):参考文章 - Linux下安装MariaDB

# 启动数据库
systemctl start mariadb

④下载 nacos-server-2.0.3.zip 安装包,并解压到云服务器。

unzip nacos-server-2.0.3.zip

SpringCloud Alibaba之 Nacos注册中心_第26张图片

回到目录…

6.2 配置外置数据源

  • 使用内置数据源:单节点 Nacos,无需进行任何配置。
  • 使用外置数据源:Nacos 集群模式,生产使用建议至少主备模式,或者采用高可用数据库。

初始化 MySQL 数据库:根据 nacos/conf/nacos-mysql.sql 文件建库建表
SpringCloud Alibaba之 Nacos注册中心_第27张图片

CREATE SCHEMA `nacos_config` DEFAULT CHARACTER SET utf8mb4 ;
use nacos_config;
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info   */
/******************************************/
CREATE TABLE `config_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) DEFAULT NULL,
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `c_desc` varchar(256) DEFAULT NULL,
  `c_use` varchar(64) DEFAULT NULL,
  `effect` varchar(64) DEFAULT NULL,
  `type` varchar(64) DEFAULT NULL,
  `c_schema` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
CREATE TABLE `config_info_aggr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) NOT NULL COMMENT 'group_id',
  `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
  `content` longtext NOT NULL COMMENT '内容',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
CREATE TABLE `config_info_beta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
CREATE TABLE `config_info_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
CREATE TABLE `config_tags_relation` (
  `id` bigint(20) NOT NULL COMMENT 'id',
  `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
  `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `nid` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`nid`),
  UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
CREATE TABLE `group_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (
  `id` bigint(64) unsigned NOT NULL,
  `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL,
  `group_id` varchar(128) NOT NULL,
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL,
  `md5` varchar(32) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `src_user` text,
  `src_ip` varchar(50) DEFAULT NULL,
  `op_type` char(10) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`nid`),
  KEY `idx_gmt_create` (`gmt_create`),
  KEY `idx_gmt_modified` (`gmt_modified`),
  KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
CREATE TABLE `tenant_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';


CREATE TABLE `tenant_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `kp` varchar(128) NOT NULL COMMENT 'kp',
  `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
  `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
  `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
  `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
  `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
  `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';

CREATE TABLE `users` (
	`username` varchar(50) NOT NULL PRIMARY KEY,
	`password` varchar(500) NOT NULL,
	`enabled` boolean NOT NULL
);

CREATE TABLE `roles` (
	`username` varchar(50) NOT NULL,
	`role` varchar(50) NOT NULL,
	UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);

CREATE TABLE `permissions` (
    `role` varchar(50) NOT NULL,
    `resource` varchar(255) NOT NULL,
    `action` varchar(8) NOT NULL,
    UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

回到目录…

6.3 配置集群配置文件

①修改:application.properties,包括 MySQL 服务器的信息:

### Default web server port:
server.port=8848

#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
db.user.0=root
db.password.0=123456

②修改:cluster.conf.example -> cluster.conf,重命名并修改

mv cluster.conf.example cluster.conf

每行配置成 ip:port,两台做集群的 nacos 服务器的IP (内网IP,使用 ifconfig 查看;端口号不能连号,否则会报错)

# ip:port
10.0.4.12:8848
10.0.4.12:8850

③ Nacos 的内存分配以及前台启动,直接修改nacos/bin/startup.sh文件
SpringCloud Alibaba之 Nacos注册中心_第28张图片
在这里插入图片描述

④将整个 nacos 文件夹复制 n 份,用于做集群的节点

cp -r nacos nacos2

仅仅更改 application.properties 中的 端口号 即可,其余配置不变。
在这里插入图片描述

回到目录…

6.4 启动 nacos 集群

分别在两个 nacos 目录下,启动 nacos 服务

sh bin/startup.sh

SpringCloud Alibaba之 Nacos注册中心_第29张图片
在这里插入图片描述

然后我们直接通过云服务器的外网来访问 http://1.15.76.95:8848/nacos ,注意一定要设置云服务器防火墙,允许访问端口。

打开管理面板,可以看到两个节点都已经启动了:
SpringCloud Alibaba之 Nacos注册中心_第30张图片

当有一个 Nacos 宕机后:
SpringCloud Alibaba之 Nacos注册中心_第31张图片

回到目录…

6.5 Nginx 反向代理

当我们的 Nacos 集群搭建好时,我们还需要做到服务器之间的负载均衡。此时我们需要添加一个 SLB,这里用 Nginx 做反向代理:

Nginx (engine x) 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。它相当于在内网与外网之间形成一个网关,所有的请求都可以由 Nginx 服务器转交给内网的其他服务器。

①首先我们要在云服务器上安装 nginx,参考往期文章:Linux 安装 nginx 详细步骤

启动 nginx 后,直接访问云服务器的外网IP就行,http://1.15.76.95,默认 80 端口,可省略。
SpringCloud Alibaba之 Nacos注册中心_第32张图片

②现在我们需要让其代理我们刚刚启动的两个 Nacos 服务器,我们需要对其进行一些配置。配置文件位于/etc/nginx/nginx.conf,添加以下内容:

http {
    ......
    # 添加两个 nacos 服务器
    upstream nacos-server {
        server 10.0.4.12:8848;
        server 10.0.4.12:8850;
    }

    server {
        listen   80;
        server_name  localhost;

		# 添加需要转发的路径
        location /nacos {
            proxy_pass http://nacos-server;
        }
        ......
    }
}

重启 Nginx 服务器,访问地址:http://1.15.76.95/nacos,成功连接到 Nacos 服务器上。
在这里插入图片描述

③然后我们将所有的服务全部修改为云服务器上 Nacos 的地址,启动试试看。

spring:
  cloud:
    nacos:
      discovery:
        # 配置到云服务器上的 Nacos 注册中心,因为有 nginx 代理,所以地址直接写云服务器的外网IP,端口也不用加
        server-addr: 1.15.76.95

SpringCloud Alibaba之 Nacos注册中心_第33张图片

这样,我们就搭建好了 Nacos 集群。

回到目录…


总结:
提示:这里对文章进行总结:
本文是对Nacos的学习,学习了更加全能的注册中心,不仅仅有服务的注册与发现,还具有配置中心的作用。也可以做集群分区和命名空间,最后也在Linux环境下搭建了Nacos集群,并且使用 Nginx 代理转发,实现了 nacos 之间的负载均衡。

你可能感兴趣的:(SpringCloud,spring,cloud,Nacos,nginx,linux)