• Nacos注册中心


    一、安装和启动Nacos

    前面已经学习了Eureka注册中心,为什么还要学习Nacos注册中心。

    原因: Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比于Eureka功能更加丰富,在国内受欢迎程度较高

    nacos下载链接

    链接:https://pan.baidu.com/s/1hxt4Kn8ChcoGkarmuV95gA 
    提取码:mfkw

     第一步: 在D盘新建Nacos目录,把下载下来的nacos压缩包复制到D盘下的Nacos目录,并解压

    第二步: 查看nacos的启动端口

    第三步: 启动nacos。进入nacos包的bin目录,命令行打开。m表示启动模式,standalone表示单机启动。除了单机启动模式,还有集群启动的模式

    startup.cmd -m standalone

    第四步: 浏览器访问,访问上面的路径

    二、Nacos快速入门

    第一步: 在cloud-demo父工程中添加spring-cloud-alibaba的管理依赖,作用是管理nacos版本

    1. <dependency>
    2. <groupId>com.alibaba.cloudgroupId>
    3. <artifactId>spring-cloud-alibaba-dependenciesartifactId>
    4. <version>2.2.5.RELEASEversion>
    5. <type>pomtype>
    6. <scope>importscope>
    7. dependency>

    第二步: 在order-service和user-service微服务的pom.xml里面,注释掉原有的eureka依赖 

    第三步: 在order-service和user-service微服务的pom.xml里面,添加nacos的客户端依赖

    1. <dependency>
    2. <groupId>com.alibaba.cloudgroupId>
    3. <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    4. dependency>

    第四步: 在order-service和user-service微服务的application.yml里面,注释掉eureka地址,添加nacos地址

    1. # 因为nacos是spring的配置,所以要写在spring配置的下面
    2. cloud:
    3. nacos:
    4. server-addr: localhost:8848

     配置完后user-service的yml文件如下

    1. server:
    2. port: 8081
    3. spring:
    4. datasource:
    5. url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    6. username: root
    7. password:
    8. driver-class-name: com.mysql.jdbc.Driver
    9. application:
    10. # user的服务名称。也就是这个user-service注册到Eureka之后,这个user-service会叫什么名字
    11. name: UserService
    12. # 因为nacos是spring的配置,所以要写在spring配置的下面
    13. cloud:
    14. nacos:
    15. server-addr: localhost:8848
    16. mybatis:
    17. type-aliases-package: cn.itcast.user.pojo
    18. configuration:
    19. map-underscore-to-camel-case: true
    20. logging:
    21. level:
    22. cn.itcast: debug
    23. pattern:
    24. dateformat: MM-dd HH:mm:ss:SSS
    25. #eureka:
    26. # client:
    27. # service-url:
    28. # # eureka的服务地址。如果有多个的话,逗号隔开。也就是把当前这个user-service微服务注册给哪个Eureka
    29. # defaultZone: http://localhost:8686/eureka

    配置完后order-service的yml文件如下 

    1. server:
    2. port: 8080
    3. spring:
    4. datasource:
    5. url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    6. username: root
    7. password:
    8. driver-class-name: com.mysql.jdbc.Driver
    9. application:
    10. # order的服务名称。也就是这个order-service注册到Eureka之后,这个order-service会叫什么名字
    11. name: OrderService
    12. # 因为nacos是spring的配置,所以要写在spring配置的下面
    13. cloud:
    14. nacos:
    15. server-addr: localhost:8848
    16. mybatis:
    17. type-aliases-package: cn.itcast.user.pojo
    18. configuration:
    19. map-underscore-to-camel-case: true
    20. logging:
    21. level:
    22. cn.itcast: debug
    23. pattern:
    24. dateformat: MM-dd HH:mm:ss:SSS
    25. #eureka:
    26. # client:
    27. # service-url:
    28. # # eureka的服务地址。如果有多个的话,逗号隔开。也就是把当前这个order-service微服务注册给哪个Eureka
    29. # defaultZone: http://localhost:8686/eureka
    30. ribbon:
    31. eager-load:
    32. enabled: true # 开启饥饿加载
    33. # 指定对UserService这个服务开启饥饿加载
    34. #UserService是你注册到Eureka时的服务名称。如果有多个服务需要做饥饿加载,就-往下写
    35. clients:
    36. - UserService

    第五步: 服务注册,启动order-service和user-service微服务。浏览器输入访问地址 

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

    第六步: 服务发现。浏览器输入http://localhost:8080/order/101,多次访问。查看OrderService是否能正常请求UserService并拿到数据。查看负载均衡 

     

    可以看到id为2、3的是8081端口返回的;id为1、4的是8082端口返回的。有做负载均衡

    三、Nacos服务分级存储模型

    概念

    • nacos注册中心里面可以多个服务。例如user-service、order-service,这俩在nacos的服务名称分别是UserService、OrderService
    • 一个服务可以有多个实例。例如UserService服务有两个实例,分别是8081端口、8222端口
    • 多个实例不一定只在一个服务里面,多个实例可以各自分布在不同的机房(或地区),这个机房我们就叫集群,把多个实例划分成多个集群的作用是容灾

    容灾系统是指在相隔较远的异地,建立两套或多套功能相同的IT系统,互相之间可以进行健康状态监视和功能切换,当一处系统因意外(如火灾、地震等)停止工作时,整个应用系统可以切换到另一处,使得该系统功能可以继续正常工作。容灾技术是系统的高可用性技术的一个组成部分,容灾系统更加强调处理外界环境对系统的影响,特别是灾难性事件对整个IT节点的影响,提供节点级别的系统恢复功能

    服务跨集群调用问题的方案

    • 服务调用尽可能选择本地集群的服务,跨集群调用的缺点是延迟高
    • 当本地集群不可访问时,再去访问其它集群

    四、Nacos配置集群属性

    上面学习了集群的分级存储模型,那怎么在代码上配置集群属性呢,下面就来学习

    浏览器查看集群属性的信息,点击UserService服务的详情

    跨集群部署的具体操作如下

    第一步: 在复制出一个UserApplication3实例,端口为8283。此时我们就有三台服务名称为UserService的实例

    分别修改这三台实例的application.yml实现把UserApplication、UserApplication2放到杭州集群,把UserApplication3放到上海集群,来模拟跨集群部署

    首先配置user-service的application.yml文件如下,把集群设置为HZ(意为杭州),然后启动UserApplication和UserApplication2工程

    1. spring:
    2. # 要写在spring:属性下
    3. cloud:
    4. nacos:
    5. # nacos 服务地址
    6. server-addr: localhost:8848
    7. # 跨集群部署
    8. discovery:
    9. # 自定义集群名称。注意不能使用中文,我下面截图使用中文在启动时就报错了,大家记得用英文
    10. cluster-name: HZ

    然后配置user-service的application.yml文件如下,把集群设置为SH(意为上海),然后启动UserApplication3工程

    1. spring:
    2. # 要写在spring:属性下
    3. cloud:
    4. nacos:
    5. # nacos 服务地址
    6. server-addr: localhost:8848
    7. # 跨集群部署
    8. discovery:
    9. # 自定义集群名称。注意不能使用中文,我下面截图使用中文在启动时就报错了,大家记得用英文
    10. cluster-name: SH

    第四步: 测试。浏览器访问

    http://10.104.15.48:8848/nacos/index.html#/serviceDetail?name=UserService&groupName=DEFAULT_GROUP

     五、NacosRule负载均衡

    上面只是把user-service微服务(内含三个实例)部署成了两个集群,我们需要实现的是如何在order-service微服务去向user-service微服务发送请求,远程调用user-service微服务时,优先选择本地集群(相对而言),如果order-service是hangzhou集群,那么 '本地集群' 就是hangzhou集群,也就是order-service此时会远程向user-service的hangzhou集群发送请求,而不会向user-service的shanghai集群发送请求。如何实现,如下

    1. 配置集群

    第一步: 由于order-service还没有配置集群属性,所以我们先要给order-service集群配置集群属性。在order-service微服务的application.yml添加如下,然后重启OrderService

    1. spring:
    2. # 要写在spring:属性下
    3. cloud:
    4. nacos:
    5. # nacos 服务地址
    6. server-addr: localhost:8848
    7. # 跨集群部署
    8. discovery:
    9. # 自定义集群名称
    10. cluster-name: HZ

    第二步: 根据集群,重新启动user-service微服务(如果你已经启动了就不用重启)

    到这里,可以明确OrderService的本地集群是HZ,UserService有三个实例,UserApplication和UserApplication2的本地集群是HZ,UserApplication3的本地集群是SH

    第三步: 浏览器访问order-service微服务,去请求user-service微服务的数据,请求多次。看一下请求的是user-service微服务的哪个实例(有三个实例)

     

    2. Nacos配置同集群优先

    此时三个实例都会接受OrderService的请求,依然访问策略依旧采用轮循方案,那么我们想要优先访问同集群的实例?可以进行如下配置

    修改order-service中的application.yml,设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务。也就是让OrderService优先向集群为HZ的user-service实例发送请求

    1. # Nacos的负载均衡策略,优先向本地集群发送请求,注意UserService是你本地集群对应的服务名称,也就是注册到注册中心时的服务名称
    2. UserService:
    3. ribbon:
    4. # 负载均衡规则为NacosRule
    5. NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

    添加后的order-service中的application.yml如下

    1. server:
    2. port: 8080
    3. spring:
    4. datasource:
    5. url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    6. username: root
    7. password:
    8. driver-class-name: com.mysql.jdbc.Driver
    9. application:
    10. # order的服务名称。也就是这个order-service注册到Eureka之后,这个order-service会叫什么名字
    11. name: OrderService
    12. # 因为nacos是spring的配置,所以要写在spring配置的下面
    13. cloud:
    14. nacos:
    15. server-addr: localhost:8848
    16. discovery:
    17. cluster-name: HZ
    18. mybatis:
    19. type-aliases-package: cn.itcast.user.pojo
    20. configuration:
    21. map-underscore-to-camel-case: true
    22. logging:
    23. level:
    24. cn.itcast: debug
    25. pattern:
    26. dateformat: MM-dd HH:mm:ss:SSS
    27. # Nacos的负载均衡策略,优先向本地集群发送请求,注意UserService是你本地集群对应的服务名称,也就是注册到注册中心时的服务名称
    28. UserService:
    29. ribbon:
    30. # 负载均衡规则为NacosRule
    31. NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
    32. #eureka:
    33. # client:
    34. # service-url:
    35. # # eureka的服务地址。如果有多个的话,逗号隔开。也就是把当前这个order-service微服务注册给哪个Eureka
    36. # defaultZone: http://localhost:8686/eureka
    37. ribbon:
    38. eager-load:
    39. enabled: true # 开启饥饿加载
    40. # 指定对UserService这个服务开启饥饿加载
    41. #UserService是你注册到Eureka时的服务名称。如果有多个服务需要做饥饿加载,就-往下写
    42. clients:
    43. - UserService

    重启OrderService,多次访问,看IDEA控制台信息

    http://localhost:8080/order/105

     

    这里做了8次请求访问,查看控制台,UserApplication3即集群地在SH的控制台无任何日志信息

    即优先调用了HZ的集群中的实例

    实现了让OrderService优先访问本地集群的UserService实例,此时OrderService服务的负载均衡策略就是在集群上,使用随机负载均衡

    注意: UserService服务有三个实例,其中有两个实例的集群是跟OrderService服务是一样的,这两个实例我们称为是OrderService服务的本地集群。当OrderService服务的本地集群全部宕机时,此时OrderService服务才会向非本地集群发送请求,也就是此时UserService服务的集群为SH的实例才会生效。虽然是生效了访问成功,但是OrderService服务的控制台会报一个警告: "在UserService服务里面发生了一次跨集群访问,原本访问的集群是HZ,实际访问的集群是SH"

    总结:

    • NacosRule规则会优先选择同集群的服务实例列表,进行随机访问
    • 如果本地集群找不到提供者,才会去其它集群寻找,并且会报警告
    • 确认了可用实例列表后,再采用随机负载均衡挑选实例

    3. debug

    如果在配置同集群优先,没生效,可能是我们order-service启动类中配置的负载均衡规则为随机的RandomRule没有注释,注释掉即可

    1. // /**
    2. // * 配置负载均衡规则为随机
    3. // * 注入spring容器
    4. // * @return
    5. // */
    6. // @Bean
    7. // public IRule randomRule(){
    8. // return new RandomRule();
    9. // }

    六、服务实例权重配置

    注意下面的是在上面的基础上接上去的,所以OrderService和UserService不需要关闭,保持运行即可

    上面我们已经学了完整的多集群部署,但是,实际部署中会出现如下的场景:

    由于服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求

    解决方法就是使用Nacos提供的权重配置,就可以实现控制访问频率。权重越大,则访问频率越高

    权重的取值范围是在0~1

    具体操作如下

    第一步: 浏览器访问。进行权重修改

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

    第二步: 验证请求是否能被权重控制。浏览器访问order-service微服务,去请求user-service微服务的数据,请求10次

    思考:如果把权重设置为0呢?

    那这个服务就不会被访问

    权重为0的使用场景: 如果要对某个实例进行版本升级,我们就不需要对这个实例进行重启,可以逐渐减低服务权重直至把这个实例的权重降为0。也叫降权重启(或灰度重启),升级完后再把权重调整回去,用户没有任何感知

    七、namespace环境隔离

    Nacos首先是注册中心,而且还是数据中心,Nacos为了做数据和服务的管理,就有了一个环境隔离的概念。环境隔离最重要的就是namespace,也叫命名空间。Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离。在namespace内部有一个group属性,作用是同一个namespace里面的多个东西,可以进行分组。group属性内部就是Service/Data,也就是具体的服务或数据。我们学的是隔离Service服务,不对隔离Data进行深入学习

    Service里面的是集群,集群里面的是实例。环境隔离的本质就是对不同的服务进行隔离

    我们可以把业务相关度比较高(例如订单服务和支付服务)的服务放到同一个Group组

    具体操作如下

    第一步: 浏览器访问。创建命名空间

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

    第二步: 把实例添加进刚刚创建的dev命名空间。修改order-service微服务的application.yml,添加namespace命名空间,值为刚才创建的dev命名空间的ID

    1. spring:
    2. # 要写在spring:属性下
    3. cloud:
    4. nacos:
    5. server-addr: localhost:8848
    6. discovery:
    7. cluster-name: HZ
    8. namespace: d8ec5ecb-2268-4551-ac2d-f08953292b28

    第三步: 重新启动OrderService服务

    第四步: 浏览器访问,查看dev命名空间是否有OrderService服务实例

    http://10.104.15.48:8848/nacos/index.html#/configurationManagement?dataId=&group=&appName=&serverId=&namespace=&pageSize=&pageNo=

    第五步: 这样分组隔离有什么用呢?作用: 此时OrderService服务是无法向UserService访问发送请求,因为这俩服务已经被隔离了

    总结:

    namespace用来做环境隔离

    每个namespace都有唯一id

    不同namespace下的服务不可见

    八、Nacos和Eureka的对比

    什么是临时实例,什么是非临时实例。可在服务里面的application.yml设置 

    1. spring:
    2. # 要写在spring:属性下
    3. cloud:
    4. nacos:
    5. server-addr: localhost:8848
    6. discovery:
    7. ephemeral: false # 设置为非临时实例

    例如把OrderService服务设置为非临时实例,User-service服务不设置(默认是临时实例)

    启动order-service,打开nacos控制台,可以看到order-service为非临时实例

    临时实例的特点: 当服务或服务里面的某个实例出现问题时,注册中心就会把出问题的剔除

    非临时实例的特点: 当服务或服务里面的某个实例出现问题时,注册中心不会把出现问题的剔除掉,注册中心会一直主动询问直到问题恢复

    这里我们把order-service停止

     打开控制台

    总结:

    一、Nacos和Eureka共同点

    • 都支持服务注册和服务拉取
    • 都支持服务提供者心跳方式做健康检测

    二、Nacos和Eureka不同点

    • Nacos支持服务端主动检测提供者状态: 临时实例采用心跳模式,非临时实例采用主动检测模式(非临时实例对服务器压力比较大,推荐使用临时实例)
    • 临时实例心跳不正常就会被剔除,非临时实例则不会被剔除
    • Nacos支持服务列表变更的消息推送模式,服务列表更新速度更快
    • Nacos集群默认采用AP方式(强调服务的可用性)。当集群中存在非临时实例时,采用CP模式强调数据可靠性和一致性)。Eureka采用AP方式
  • 相关阅读:
    ros2与windows入门教程-ROS2 导航Navigation2
    【JavaWeb】之文件上传与下载
    pdf生成:wkhtmltopdf
    springboot---优雅永不过时
    瑞芯微rk356x板子快速上手
    Feign远程调用
    SpringBoot项目打包成jar后,使用ClassPathResource获取classpath(resource)下文件失败
    HTML 笔记:初识 HTML(HTML文本标签、文本列表、嵌入图片、背景色、网页链接)
    Kafka 社区KIP-382中文译文(MirrorMaker2/集群复制/高可用/灾难恢复)
    POC模拟攻击利器 —— Nuclei入门(一)
  • 原文地址:https://blog.csdn.net/m0_63732435/article/details/134082958