草庐IT

微服务架构 | 3.2 Alibaba Nacos 注册中心

多氯环己烷 2023-03-28 原文


前言

参考资料
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》
《Nacos 官网》

Nacos 致力于解决微服务中的统一配置、服务注册与发现等问题。它提供了一组简单易用的特性集,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理;


1. Nacos 基础知识

1.1 Nacos 命名方式

  • 前四个字母分别为 Naming 和 Configuration 的前两个字母,最后的 s 为 Service;

1.2 Nasoc 是什么

  • 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台;
  • Nacos: Dynamic Naming and Configuration Service;
  • Nacos 是注册中心 + 配置中心的组合,相当于:Nacos = Eureka+Config +Bus;

1.3 Nacos 的 4 个关键特性

  • 服务发现和服务健康监测
    • Nacos 支持基于 DNS 和基于 RPC(HTTP&API)的服务发现;
    • Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求;
    • 对于复杂的云环境和网络拓扑环境中(如VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报和服务端主动检测两种健康检查模式;
    • Nacos 还提供了统一的健康检查仪表盘,帮助用户根据健康状态管理服务的可用性及流量;
  • 动态配置服务
    • Nacos 提供了一个简洁易用的 UI(控制台样例 Demo)帮助用户管理所有服务和应用的配置;
    • Nacos 还提供了包括配置版本跟踪、金丝雀发布、一键回滚配置及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性;
  • 动态 DNS 服务
    • 动态 DNS 服务支持权重路由,让开发者更容易地实现中间层负载均衡、更灵活的路由策略、流量控制,以及数据中心内网的简单 DNS 解析服务;
  • 服务及其元数据管理
    • Nacos 可以使开发者从微服务平台建设的视角管理数据中心的所有服务及元数据;
    • 包括;管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 及最重要的 metrics 统计数据;

1.4 Nacos 生态图

1.5 Nacos 架构图

  • 服务提供者通过 VIP(Virtual IP)访问 Nacos Server 高可用集群,基于 Open API 完成服务的注册和服务查询;
  • Nacos Server 本身可以支持主备模式,所以底层会采用数据一致性算法来完成从节点的数据同步;
  • 服务消费者也是如此,基于 Open API 从 Nacos Server 中查询服务列表;

1.6 Nacos 支持 AP 和 CP 模式的切换

  • 简单来说
    • C 是所有节点在同一时间看到的数据是一致的;而 A 的定义是所有的请求都会收到响应;
  • 模式选择
    • 如果不需要存储服务级别的信息且服务实例是通过 nacos-client 注册,并能够保持心跳上报,那么就可以选择 AP 模式;
    • 当前主流的服务如 Spring cloud 和 Dubbo 服务,都适用于 AP 模式,AP 模式为了服务的可能性而减弱了一致性,因此 AP 模式下只支持注册临时实例;
    • 如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须, K8S 服务和 DNS 服务则适用于 CP 模式;
    • CP 模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误;
  • 切换模式
    • curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

1.7 Nacos 文件结构说明

  • bin 目录:服务启动/停止脚本;
  • conf 目录:配置文件;
    • application.properties 文件:Spring Boot 项目默认的配置文件;
    • cluster.conf.example:集群配置样例文件;
    • nacos-mysql.sql:MySQL 数据库脚本;
    • nacos-logback.xml:Nacos 日志配置文件;
  • data 目录:Derby 数据库存储;
  • logs 目录:日志;
  • target 目录:编译打包后的文件;

1.8 Nacos 服务注册与发现的源码分析


2. 安装并运行 Nacos 服务器

Nacos 依赖 Java 1.8 以上环境,有两种安装方式:使用已经编译好的安装包和源码部署;由于《*3.5 Nacos 服务注册与发现的源码分析》要对 Nacos 源码进行分析,这里推荐源码部署;
这里选择的版本是 2.0.3;

2.1 安装包安装 Nacos 服务器

2.1.1 下载 Nacos

2.1.2 直接运行报错

  • 下载解压后如图:
  • 直接双击运行 startup.cmd 会报错:
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:156)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)

  • 原因是 Nacos 默认以集群模式启动,我们需要单机模式,修改启动方式即可;

2.1.3 修改启动方式后启动

  • 修改 startup.cmd 里第26行为 standalone

  • 保存后启动,访问 http://localhost:8848/nacos 即可;

  • 默认起始密码和账号都是 nacos

2.2 源码部署 Nacos 服务器

由于 2.0.3 版本笔者一直部署失败,因此这里以 1.4.2 版本为例;

2.2.1 下载源码

  • 创建 Nacos 1.4.2 分支(名字可以自己取);

  • 由于 GitHub Http 默认拉取 default 标签下的代码,因此这里选择修改 default 为 1.4.2 标签,再拉取代码;


  • 点击 Update;

  • 然后在 idea 上拉取代码即可;

2.2.2 本地编译

  • 源码下载后,会自动导入依赖 jar 包,有导入不成功的可以尝试手动导入,亲测有效;
  • 需要使用 Maven 对源码进行编译。进入到 Nacos 源码目录,使用如下mvn命令,开始本地编译:
  • mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

  • 编译完成后截图如下:

2.2.3 修改配置

  • 跟安装包部署一样,我们需要以单机方式启动 Nacos;
  • 因此需要在启动参数中进行设置,在 JVM 的启动参数中,添加:-Dnacos.standalone=true

2.2.4 启动 Nacos

  • 找到 nacos-console 模块下的启动类 com.alibaba.nacos.Nacos 启动即可;
  • 浏览器访问:http://localhost:8848/nacos
  • 默认账号和密码都是 nacos;

2.2.5 启动报错

  • 如果启动失败报错 找不到 entity 包,这需要编译 nacos-consistency 模块,刷新下 Maven,然后重新启动即可;


3. 使用 Nacos 管理服务提供者

使用 Nacos 构建服务提供者大致与 Zookeeper 和 Consul 相同; Zookeeper 与 Consul 的构建方式详情请见《3.3 Apache Zookeeper 注册中心》与《3.4 HashiCorp Consul 注册中心》;

3.1 引入 pom.xml 依赖文件

  • 父工程的依赖:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.1.0.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
  • 本模块的依赖:
<!--SpringCloud ailibaba nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3.2 修改 application.yml 配置文件

server:
  port: 9001

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'

3.3 在主程序类上添加注解

  • @EnableDiscoveryClient:使用其他组件(Nacos、zookeeper、Consul)作为注册中心;

3.4 编写业务类

这里编写一个简单接口仅作为示例;

@RestController
public class providerController{
    @Value("${server.port}")
    private String serverPort;

    @RequestMapping(value = "/provider/nacos")
    public String providerNacos(){
        return "springcloud with nacos: "+serverPort+"\t"+ UUID.randomUUID().toString();
    }
}

4. 使用 Nacos 管理服务消费者

使用 Nacos 构建服务提供者大致与 Zookeeper 和 Consul 相同; Zookeeper 与 Consul 的构建方式详情请见《3.3 Apache Zookeeper 注册中心》与《3.4 HashiCorp Consul 注册中心》;

4.1 引入 pom.xml 依赖文件

<!--SpringCloud ailibaba nacos -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

4.2 修改 application.yml 配置文件

server:
  port: 80

spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-provider

4.3 在主程序类上添加注解

  • 同提供者;
  • @EnableDiscoveryClient:使用其他组件(Nacos、zookeeper、Consul)作为注册中心;

4.4 编写业务类

  • 由于我们使用 Ribbon + RestTemplate 的负载均衡策略,因此需要在 IoC 容器中添加一个 RestTemplate JavaBean;
  • 详情请见《4.1 基于 Ribbon 的负载均衡详解》;
  • 该 Bean 可以在主启动类中添加;也可以在主启动类所在包或子包的 config 包中添加,如下:
@Configuration
public class ApplicationContextBean{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
  • 我们在 controller 层开放接口给客户端,并在该接口里调用提供者的 API;
@RestController
public class ComsumerNacosController{
    public static final String INVOKE_URL = "http:// nacos-provider";

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/consumer/nacos")
    public String paymentInfo(){
        String result = restTemplate.getForObject(INVOKE_URL+"/provider/nacos", String.class);
        System.out.println("消费者调用提供者获取服务--->result:" + result);
        return result;
    }
}

5. Nacos 持久化配置

  • 在 0.7 版本之前,在单机模式时 Nacos 使用嵌入式数据库 Derby 实现数据的存储,不方便观察数据存储的基本情况。0.7 版本增加了支持 MySQL 数据源能力;
  • Derby 数据库是一种文件类型的数据库,在使用时会存在一定的局限性。比如它无法支持多用户同时操作,在数据量大、连接数多的情况下会产生大量连接的积压。所以在生产环境中,可以用 MySQL 替换;
  • 在 pom.xml 里可以找到 Derby 依赖

5.1 切换成 MySQL

  • 首先在 nacos-server-2.0.3\nacos\conf 目录下找到 sql 脚本 nacos-mysql.sql
#需要自己先创建数据库,再执行 sql 脚本;
CREATE DATABASE nacos_config;
USE nacos_config;
  • 在 MySQL 里执行该脚本新建数据库;

5.2 修改配置文件

  • 接着在 nacos-server-2.0.3\nacos\conf 目录下找到 application.properties 配置文件,修改成 MySQL 相关;
  • 源码部署需要在 ..\nacos\console\src\main\resources\application.properties 文件里配置;

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
  • 再以单机模式启动 Nacos,Nacos 所有写嵌入式数据库的数据都写到了 MySQL;

6. Nacos 的高可用部署

6.1 环境要求

  • 64 bit OS Linux/UNIX/Mac,推荐 Linux 系统;
  • 64bit JDK1.8 及以上;
  • Maven3.2.x 及以上;
  • 3 个或 3 个以上 Nacos 节点才能构成集群;
  • MySQL 数据库,版本 5.6.5+;

6.2 安装包及环境准备

unzip nacos-server-2.0.3.zip

6.3 修改集群配置

  • 在 Nacos 的解压目录 nacos/conf 下,有配置文件集群的 cluster.conf 文件,里面配置 ip:port,需要配置3个或3个以上节点;
cd ${NACOS_HOME}/config
cp cluster.conf.example cluster.conf
  • 使用 vi 编辑器打开 cluster.config,按 a/i/o 键可进入插入模式,输入以下内容(3 台机器都需要修改);
#ip:port
10.51.10.128:8848
10.51.10.129:8848
10.51.10.130:8848
  • 然后按ESC键返回到命令模式,再按shif+:进入末行模式,输入wq敲回车(保存并退出);
  • 由于 3 台机器需要彼此通信,在部署时需要防火墙对外开放 8848 端口;

6.4 初始化 MySQL

  • 参考:《5. Nacos 持久化配置》,将每个 Nacos 的数据源换成 MySQL;
  • 同样,3 台机器都需要配置 MySQL 数据库;

6.5 启动 Nacos 服务

  • 分别进入 3 台机器的 bin 目录,执行 sh startup.sh 或者 startup.cmd-m cluster 命令启动服务;
  • 服务启动成功之后,在 ${NACOS_HOME}\logs\start.out 下可以获得如下日志,表示服务启动成功:
2020-01-2814:26:25,654INFO Nacos Log files:/data/program/nacos/1ogs/
2020-01-2014:26:25,654 INFO Nacos Conf files:/data/program/nacos/conf/
2020-01-20 14:26:25,654 INFO Nacos Data files:/data/program/nacos/data/
2020-01-20 14:26:25,654 INFO Nacos started successfully in cluster mode.
  • 通过 http://$NACOS_CLUSTER_IP:8848/nacos 即可访问 Nacos 控制台;

7. 包含 Nginx 的 Nacos 高可用示例

  • 即要完成上图的集群配置;
  • 在《6. Nacos 的高可用部署》的基础上,还需要配置 Nginx 服务器;

7.1 [可选] 修改 startup.sh 启动配置

  • 这里指在一台服务器上启动 3 个 Nacos 实例模拟集群时才需要配置;
  • 比如 cluster.config 的配置如下(指一台服务器上开放三个端口模拟集群):
#ip:port
192.168.111.144:3333
192.168.111.144:4444
192.168.111.144:5555
  • 目的:使 Nacos 能够接受不同的启动端口,即传递不同的端口号启动不同的 Nacos 实例;
  • ${NACOS_HOME}\bin\startup.sh 文件里:

  • 修改完后,我们可以指定不同的端口启动不同的 Nacos 实例;

7.2 配置 Nginx 负载均衡器

  • 如果需要通过 Nignx 对 Nacos 实例进行负载均衡,需要以下配置;
  • 修改 Nginx 的配置文件 nginx/conf/nginx.conf

  • 按照指定启动:

7.3 测试通过 Nginx 访问 Nacos

  • 需要修改服务提供者的 application.yml 文件指向 Nginx 服务器:
server:
  port: 9002

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        #配置Nacos地址
        #server-addr: localhost:8848
        # 换成nginx的1111端口,做集群
        server-addr: 192.168.111.144:1111

management:
  endpoints:
    web:
      exposure:
        include: '*'
  • 访问连接:http://192.168.111.144:1111/nacos/#/login
  • 结果如下:



8. Dubbo 使用 Nacos 作为注册中心

  • 详情请见:本系列另外一篇文章《12.1 使用 Apache Dubbo 实现远程通信》里的《6. Dubbo 使用 Nacos 作为注册中心》;


最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!

有关微服务架构 | 3.2 Alibaba Nacos 注册中心的更多相关文章

  1. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  2. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  3. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  4. ruby-on-rails - 设计注册确认 - 2

    我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:

  5. ruby-on-rails - Rails 3.2 防止使用错误保存对象 - 2

    我有一个ActiveRecord对象,我想在不对模型进行永久验证的情况下阻止它被保存。您过去可以使用errors.add执行类似的操作,但它看起来不再有效了。user=User.lastuser.errors.add:name,"namedoesn'trhymewithorange"user.valid?#=>trueuser.save#=>true或user=User.lastuser.errors.add:base,"myuniqueerror"user.valid?#=>trueuser.save#=>true如何在不修改用户对象模型的情况下防止将用户对象保存在Rails3.2中

  6. ruby - Ruby 和 Ruby on Rails 中的三层架构 - 2

    我是一名决定学习Ruby和RubyonRails的ASP.NETMVC开发人员。我已经有所了解并在RoR上创建了一个网站。在ASP.NETMVC上开发,我一直使用三层架构:数据层、业务层和UI(或表示)层。尝试在RubyonRails应用程序中使用这种方法,我发现没有关于它的信息(或者也许我只是找不到它?)。也许有人可以建议我如何在RubyonRails上创建或使用三层架构?附言我使用ruby​​1.9.3和RubyonRails3.2.3。 最佳答案 我建议在制作RoR应用程序时遵循RubyonRails(RoR)风格。Rails

  7. ruby-on-rails - 特征未注册 : attribute name - 2

    完成这个有困难。我正在使用seed.rb+factory_girl来使用rakedb:seed填充数据库。(我知道固定装置存在,但我想以这种方式完成,这只是一个示例,数据库将填充复杂的关联对象。)我的种子.rb:require'factory_girl_rails'["QM","CDC","SI","QS"].eachdo|n|FactoryGirl.create(:grau,nome:n)end还有我的/factories/graus.rbFactoryGirl.definedofactory:graudonomeendend但是当我运行时:rakedb:seed我得到:rakeab

  8. ruby-on-rails - 带有自定义处理器的 CarrierWave 未注册 - 2

    我正在使用carrierwave上传视频然后有一个名为thumb的版本,带有自定义处理器,可以获取视频并使用streamio-ffmpeg创建屏幕截图。视频和文件都已正确上传,但在调用uploader.url(:thumb)时我得到:ArgumentError:Versionthumbdoesn'texist!VideoUploader.rbrequire'carrierwave/processing/mime_types'require'streamio-ffmpeg'classVideoUploader5)File.renamethumb_path,current_pathendd

  9. ruby - 在 Heroku Cedar 上的 Rails 3.2 中,是否有一种标准的方式来提供预压缩的 Assets ? - 2

    我有一个正在HerokuCedar堆栈上部署的Rails3.2应用程序。这意味着应用程序本身负责为其静态Assets提供服务。我希望对这些Assets进行gzip压缩,所以我在production.rb的中间件堆栈中插入了Rack::Deflater:middleware.insert_after('Rack::Cache',Rack::Deflater)...curl告诉我这与宣传的一样有效。但是,由于Heroku将全力运行rakeassets:precompile,生成一堆预gzipAssets,我很想使用它们(而不是让Rack::Deflater再次完成所有工作)。我已经看到使用

  10. ruby-on-rails - 具有六边形架构和 DCI 模式的框架和数据库适配器 - 2

    我尝试用Ruby设计一个基于Web的应用程序。我开发了一个简单的核心应用程序,在没有框架和数据库的情况下在六边形架构中实现DCI范例。核心六边形中有小六边形和网络,数据库,日志等适配器。每个六边形都在没有数据库和框架的情况下自行运行。在这种方法中,我如何提供与数据库模型和实体类的关系作为独立于数据库的关系。我想在将来将框架从Rails更改为Sinatra或数据库。事实上,我如何在这个核心Hexagon中实现完全隔离的rails和mongodb的数据库适配器或框架适配器。有什么想法吗? 最佳答案 ROM呢?(Ruby对象映射器)。还有

随机推荐