Nacos—学习笔记

简介

1、什么是 nacos

是 alibaba 研发的,可以去 github.com/alibaba/spring-cloud-alibaba/wiki/版本说明 这个网址查看 alibaba与springcloud 之间的组件版本关系。Nacos服务器是独立安装部署的。

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施

Nacos = Spring Cloud Eureka + Spring Cloud Config

  • 服务发现与健康服务检查

  • 动态配置管理

  • 动态DNS服务

  • 服务和元数据管理 nacos 会根据相同的服务名称自动做负载均衡,即不同端口的同一个项目就是两个服务,就会自动做负载均衡。

2、下载

2.1、zip安装包

https://github.com/alibaba/nacos/releases

下载好后解压,然后打开 bin文件夹,Windows中用 startup.cmd启动,Linux中用 startup.sh

启动后访问 http://localhost:8848/nacos

用户名密码:nacos/nacos

Windows 下运行

修改运行模式

编辑 startup.cmd,把 MODE 改成 standalone。

2.1.1、取消后台运行

编辑 startup.cmd,(暂时还不知道如何修改)

如果是 Linux环境中,则把 startup.sh 的最后两行改一下。然后点编辑配置,+ 添加一个 Shell Script,修改下名称,脚本路径选择 startup.sh,脚本选项 -m standalone,工作目录就选 nacos目录,解释器路径改成 /bin/bash,然后就可以像允许项目一样允许 nacos 了。

nohup $JAVA ${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

2.2、源码

https://github.com/alibaba/nacos

2.2.1、idea 中以源码方式启动

2.2.1.1、Linux环境中的方式

3、配置

3.1、模式

编辑 startup.cmd,如果 set MODE 是cluster(集群的意思),就改成 standalone

3.2、端口

可以修改 conf/application.properties 中的端口号

3.3、从小型数据库改成数据库方式

conf 下有 nacos-mysql.sql 这个文件,通过这个 sql文件创建完数据库后需要修改 application.properties,打开一些注释。

spring.datasoure.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=nacos
db.password.0=nacos

4、nacos服务端的配置中心

4.1、nacos配置中心简介

我们可以在 nacos服务端网站中新建配置,然后就可以在客户端中统一使用了,更改的时候也是统一通知更新,实时修改,并且覆盖本地。

配置可以导出或导入,非常方便产线转换,并且每次修改都会保留历史版本,并且有哪些客户端监听了这个配置文件,会在监听查询中记录。

Nacos服务注册表结构:Map<namespace, Map<group::serviceName, service>>

即 NameSpace 下有 Group,Group下有 Service,Service下可有多个 Cluster,Cluster中可以有多个 Instance。

4.1.1、数据模型

配置文件由三元组唯一确定,以达到环境隔离的目的。

Nacos 的配置中心中,一般以 dev、prod 等作为 namespace。

Nacos 的数据模型 Key,由三元组唯一确定:namespace、group、DataID。

namespace 默认是公共命名空间(public)、分组默认是DEFAULT_GROUP。

4.1.2、加载多配置集

加载多配置集需要在同一个 namespace 下,然后配置的时候,group、name、refresh 都不需要单独配置了,改为配置 config.extension-configs[] 的 data-id、group、refresh,

用的时候就根据配置内容中的 key 进行取值就好了。

4.2、简单使用配置中心

4.2.1、实例1

4.2.1.1、nacos服务器中创建配置文件

在最上面一行选择 namespace,默认就是在 public 下;然后再配置 group 和 dataId。

4.2.1.2、项目的 pom.xml
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
​
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
4.2.1.3、项目的 bootstrap.yml
spring:
  application:
    # 服务名称和配置文件保持一致
    name: borrowservice
  profiles:
    # 环境也是和配置文件保持一致
    active: dev
  cloud:
    nacos:
      config:
        # Nacos服务器的 IP:端口
        server-addr: localhost:8848
        # 配置文件所在的 namespace,如果不对试试那一长串字符串
        namespace: ${spring.profiles.active}
        # 配置文件的后缀名
        file-extension: yml
        # 配置文件所在的 group
        group: business-service
        # 配置文件的 dataId 除去 profiles 后的前缀名,一般就是服务名称
        prefix: borrowservice
      discovery:
        server-addr: localhost:8848
        namespace: ${spring.profiles.active}
4.2.1.4、配置文件热更新

在使用了 nacos配置中心的配置文件的类上加上 @RefreshScope注解,表示支持热更新。

@RestController
@RefreshScope   // 添加此注解就能实现自动刷新了
public class TestController {
    @Value("${test.txt}")  // 获取 nacos配置中心的配置文件的属性
    String txt;
​
    @RequestMapping("/test")
    public String test(){
        return txt;
    }
}

5、服务领域模型

5.1、临时实例和非临时实例

一般启动项目注册到 Naocs注册中心,成为一个服务实例,都是临时实例。

  • 临时实例:和 Eureka一样,采用心跳机制向 Nacos 发送请求保持在线状态,一旦心跳停止,代表实例下线,不保留实例信息。

  • 非临时实例:由 Nacos 主动进行联系,如果连接失败,那么不会移除实例信息,而是将健康状态设定为 false,相当于会对某个实例状态持续地进行监控。 如果想要将服务变成非临时实例,可以修改配置文件。

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

6、高可用集群

6.1、集群分区

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

集群分区的名字是自定义的,并不需要在 nacos服务器中进行设置,并且默认创建的实例的分区是 default,并且设置分区后,需要开启 loadbalancer 对 nacos 的支持,才可以使得服务调用会默认优先调用同集群的服务。然后还可以通过配置权重来设置优先级。

6.1.1、给服务实例指定集群分区

spring:
  application:
    name: borrowservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: Chengdu
        # 权重大小,越大越优先调用,默认为1
        weight: 0.5
    # 将loadbalancer 的 nacos支持开启,集成 Nacos 的负载均衡
    loadbalancer:
      nacos:
        enabled: true

6.2、集群部署架构图

6.2.1、三种模式

  • http://ip1:port/openAPI:直连 ip模式,机器挂则需要修改 ip 才可以使用。

  • http://SLB:port/openAPI:挂载 SLB模式(内网 SLB,不可暴露到公网,以免带来安全风险),直连 SLB 即可,下面挂 server 真实 ip,可读性不好。

  • http://nacos.com:port/openAPI:域名 + SLB模式(内网 SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换 ip 方便,推荐模式

6.2.2、解读

它推荐我们在所有的 Nacos服务端之前建立一个负载均衡,我们通过访问负载均衡服务器来间接访问到各个 Nacos服务器。实际上就,是比如有三个 Nacos服务器做集群,但是每个服务不可能把每个 Nacos都去访问一次进行注册,实际上只需要在任意一台 Nacos服务器上注册即可,Nacos服务器之间会自动同步信息。

但是如果我们随便指定一台 Nacos服务器进行注册,如果这台 Nacos服务器挂了,但是其他 Nacos服务器没挂,这样就没办法完成注册了,但是实际上整个集群还是可用的状态。所以这里就需要在所有 Nacos服务器之前搭建一个 SLB(服务器负载均衡),这样就可以避免上面的问题了。但是如果要实现外界对服务访问的负载均衡,我们就得用 Gateway 来实现,或者是 Nginx。

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

最后就是 Nacos 的数据存储模式,在单节点的情况下,Nacos 实际上是将数据存放在自带的一个嵌入式数据库 nacos/data 中,但是做集群的话是需要共享数据的,不能这样各存各的,那么就得让多个 Nacos服务器都连接到同一个数据库中,Nacos 提供了 MySQL 统一存储支持,详情可见 3.3。

6.3、创建 Nacos服务器集群

是在 WIndows环境下的,但是 Linux环境下也是类似的步骤。Linux 是 .sh文件。

  1. 通过 nacos/conf/nacos-mysql.sql 这个文件创建数据库

  2. 新增一个 nacos数据库的用户,并把权限全部给它

  3. 将 nacos/bin/startup.cmd 的 MODE 从 standalone 改成 cluster,还可以设置环境参数。Linux环境下的话 .sh文件最后第二行,从 >> 开始删到行尾。

set MODE="cluster"

  1. 在 nacos/conf/application.properties 中添加配置,并指定 IP

nacos.inetutils.ip-address=127.0.0.1
server.port=8848
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://cloudstudy.mysql.cn-chengdu.rds.aliyuncs.com:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=nacos
db.password.0=nacos
  1. 将 conf/cluster.conf.example 这个文件删去 .example 这个后缀,这个文件中放的就是集群中各个服务器的地址,进行配置,在里面配上 nacos 集群机的 IP:端口,

127.0.0.1:8848
127.0.0.1:8849
  1. 复制 nacos 这整一个文件夹,因为这整一个就是一个项目,然后粘贴多份,修改 conf/application.properties 中的端口号,分别启动,就形成了集群

  2. 最后在项目的配置文件中指定集群各服务器的地址,config.server-addr 用 , 隔开集群地址(IP:端口, IP:端口),如果做了负载均衡的话,就只写一个 IP地址就好了。

  3. 分别启动,就是以集群模式启动了。

6.4、创建 SLB

做一个服务器负载均衡。

6.4.1、以 Nginx 作为 SLB

 下载 nginx
sudo apt install nginx
​
​
​
// 修改配置 /etc/nginx/nginx.conf,在 http{} 内添加
# 添加我们在上游刚刚创建好的两个nacos服务器,
# 10.0.0.12 是内网的 IP地址,ifconfig 看 eth0 的 inet 后面的。
upstream nacos-server {
    server 10.0.0.12:8848;
    server 10.0.0.12:8849;
}
​
server {
    listen   80;
    server_name  1.14.121.107;
​
    location /nacos {
            proxy_pass http://nacos-server;
    }
}
​
​
​
// 重启 nginx服务器
sudo systemctl restart nginx

7、简单使用

7.1、实例1

service-hospital服务模块远程调用 service-cmn模块

7.1.1、pom.xml

  • 父项目的依赖管理中必须有有:cloud、alibaba的框架依赖

<dependencyManagement>
    <dependencies>
        <!-- 这里引入最新的SpringCloud依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
​
          <!-- 这里引入最新的SpringCloudAlibaba依赖,2021.0.1.0版本支持SpringBoot2.6.X -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 子项目中引入依赖

<!-- nacos注册中心 -->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
​
<!-- 服务调用feign -->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
​
<!-- 这里需要单独导入LoadBalancer依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

7.1.2、application.yml

 spring:
  # nacos服务地址
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

7.1.3、启动类

在需要发现别的注册服务的项目的的启动类上添加注解,这样就可以在 nacos 中发现服务了。

// 让服务可被发现
@EnableDiscoveryClient
// 开启 feignClient 客户端
@EnableFeignClients(basePackages = {"com.chw"})

7.1.4、创建 feign 服务调用客户端模块

创建模块,此模块专门放 feign 服务调用客户端模块,然后再创建对应的子模块。

比如:service-client,创建子模块 service-cmn-client,此模块用于调用 cmn 的服务接口。

  • 创建对应接口 在接口上添加注解,并且将已开发好的 controller的对应方法放进去

// 要去调用的服务名
@FeignClient("service-cmn")
@Service
public interface DictFeignClient {
  @GetMapping("/admin/cmn/dict/findByDictCodeAndValue/{dictCode}/{value}")
  public String findByDictCodeAndValue(
          @PathVariable("dictCode") String dictCode,
          @PathVariable("value") String value);
          
  @GetMapping("/admin/cmn/dict/findByValue/{value}")
  public String findByAndValue(
          @PathVariable("value") String value);
}

7.1.5、调用者进行服务调用

  • 引入对应的 feign 服务调用模块 service_hospital 中引入 服务调用模块

<!--        引入模块-->
<dependency>
    <groupId>com.chw</groupId>
    <artifactId>service-cmn-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
  • 自动注入后使用方法

@Autowired
private DictFeignClient dictFeignClient;
​
//将医院等级、省 市 区的数据封装进去
private Hospital setHostype(Hospital hospital) {
  //远程服务调用
  //医院ERP系统中的 Hostype是数字,即我们系统中 dict表的 value字段,而我们想得到的是该记录的名称
  String hostypeString = dictFeignClient.findByDictCodeAndValue("Hostype", hospital.getHostype());
  
  String provinceString = dictFeignClient.findByValue(hospital.getProvinceCode());
  String cityString = dictFeignClient.findByValue(hospital.getCityCode());
  String districtString = dictFeignClient.findByValue(hospital.getDistrictCode());
  
  hospital.getParam().put("hostypeString", hostypeString);
  hospital.getParam().put("fullAddress", provinceString + cityString + districtString);
  return hospital;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值