服务注册

Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。
主要差异在于:

  • 依赖不同
  • 服务地址不同

    引入依赖

    父工程依赖

    1. <dependency>
    2. <groupId>com.alibaba.cloud</groupId>
    3. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    4. <version>2.2.5.RELEASE</version>
    5. <type>pom</type>
    6. <scope>import</scope>
    7. </dependency>

    客户端依赖,就是各个服务模块

    1. <!-- nacos客户端依赖包 -->
    2. <dependency>
    3. <groupId>com.alibaba.cloud</groupId>
    4. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    5. </dependency>

    :::danger 注释掉eureka的依赖 :::

    配置nacos地址

    在每个微服务模块的application.yaml中添加nacos地址,案例中是user-service和order-service:

    1. #在spring下的
    2. spring:
    3. cloud:
    4. nacos:
    5. server-addr: localhost:8848

    :::danger 注释掉eureka的地址 :::

    启动微服务

    启动user-service和order-service微服务后,在看Nacos控制台的服务管理
    image.png

    服务分级存储模型概念

    一个服务可以有多个实例,例如我们的user-service,可以有:

  • 127.0.0.1:8081

  • 127.0.0.1:8082
  • 127.0.0.1:8083

假如这些实例分布于全国各地的不同机房,例如:

  • 127.0.0.1:8081,在上海机房
  • 127.0.0.1:8082,在上海机房
  • 127.0.0.1:8083,在杭州机房

Nacos就将同一机房内的实例 划分为一个集群
也就是说,user-service是服务,一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例,形成分级模型,如图:
image-20210713232522531.png
微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。例如:
杭州机房内的order-service应该优先访问同机房的user-service。

image-20210713232658928.png

配置集群

集群的配置

  1. spring:
  2. cloud:
  3. nacos:
  4. server-addr: localhost:8848
  5. discovery:
  6. cluster-name: HZ # 集群名称,随便写

我们把user-service多开几个实例。

怎么开多个不同的配置的实例?

先配置好user-service的配置文件的集群配置。 然后通过这个配置启动两个user-service实例,前面有说怎么复制配置开新的实例。 然后,已经运行的实例不要重启,修改user-service的配置的集群配置,然后又启动几个新的user-service实例。 image.png

8002,8003集群是HZ,8004,8005集群是SH
启动完成查看nacos的控制面板的详情就能看到集群的情况了
image.png

同集群优先负载均衡

提供者有多个集群,消费者去向注册中心拉取提供者的地址信息,因该优先返回和消费者同集群的提供者。如果同集群的没法用,才返回其他集群的,这叫同集群优先负载均衡。
默认的ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡。
因此Nacos中提供了一个NacosRule的实现,可以优先从同集群中挑选实例。

  1. 我们给消费者(order-service)也加一个集群名字

    1. cloud:
    2. nacos:
    3. server-addr: localhost:8848
    4. discovery:
    5. cluster-name: HZ
  2. 修改负载均衡规则

修改order-service的application.yml文件,修改负载均衡规则:

  1. userservice:
  2. ribbon:
  3. NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
  1. 或者在配置类中修改负载均衡的规则,和第2部同样的功能,不要都配置。这这种是全局的,第二步那种是只针对userservice ```java package cn.itcast.order.config;

@Configuration public class MyConfig {

  1. @Bean
  2. @LoadBalanced
  3. public RestTemplate restTemplate(){
  4. return new RestTemplate();
  5. }
  6. @Bean
  7. public IRule myRule(){
  8. return new NacosRule();
  9. }

}

  1. 4. 重新启动order-service
  2. 就会发现只访问同一个集群HZ下的两个user-service,同一个集群下的多个实例,是采用随机的方式。如果HZ集群下的user-service都挂了,才会去访问其他集群下的实例。
  3. <a name="xbAdy"></a>
  4. # 权重配置
  5. 实际部署中会出现这样的场景:<br />服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。<br />但默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题。<br />因此,Nacos提供了权重配置来控制访问频率,**权重越大则访问频率越高**。<br />在nacos控制台,找到user-service的实例列表,点击编辑,即可修改权重:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21464164/1654657364641-cfd0aae8-5044-416b-93ca-69245114a575.png#clientId=u2acc93d1-ff82-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=231&id=u740dc56c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=460&originWidth=2873&originalType=binary&ratio=1&rotation=0&showTitle=false&size=59708&status=done&style=none&taskId=ua97d3abc-3f29-4c4a-8b7b-bca0cde5168&title=&width=1444.3333740234375)
  6. :::danger
  7. 如果权重修改为0,则该实例永远不会被访问
  8. :::
  9. <a name="Tt0Wu"></a>
  10. # 环境隔离
  11. Nacos提供了namespace来实现环境隔离功能。
  12. - nacos中可以有多个namespace
  13. - namespace下可以有groupservice
  14. - 不同namespace之间相互隔离,例如不同namespace的服务互相不可见
  15. ![image-20210714000101516.png](https://cdn.nlark.com/yuque/0/2022/png/21464164/1654657501534-8fe34df5-61fa-4bf4-af69-716b3dc1c890.png#clientId=u2acc93d1-ff82-4&crop=0&crop=0&crop=1&crop=1&from=drop&height=353&id=u0a4c44d8&margin=%5Bobject%20Object%5D&name=image-20210714000101516.png&originHeight=650&originWidth=1067&originalType=binary&ratio=1&rotation=0&showTitle=false&size=197262&status=done&style=none&taskId=ua6c2320c-bef7-41a8-817c-d952e17fc0a&title=&width=580)
  16. <a name="UuIKr"></a>
  17. ## 创建命名空间
  18. 默认情况下,所有servicedatagroup都在同一个namespace,名为public。<br />在Nacos控制台,点击命名空间——新建命名空间。
  19. <a name="V2QXd"></a>
  20. ## 给微服务配置命名空间
  21. 我们把order-service的命名空间改了
  22. ```yaml
  23. spring:
  24. cloud:
  25. nacos:
  26. server-addr: localhost:8848
  27. discovery:
  28. cluster-name: HZ
  29. namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID

重启order-service后,可以在nacos控制台看到划分的namespace
image.png
如果再用order-service去调用user-service,就会报错,应为不在一个namespace里面,相互隔离了,是两个世界的服务了。

临时与非临时实例

Nacos的服务实例分为两种l类型:

  1. 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。
  2. 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

image.png
给一个服务设置为非临时实例

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设置为非临时实例

Nacos与Eureka的区别

image-20210714001728017.png

  • Nacos与eureka的共同点
    • 都支持服务注册和服务拉取
    • 都支持服务提供者心跳方式做健康检测
  • Nacos与Eureka的区别
    • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
    • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
    • 消费者拉取的服务列表,有缓存,每隔30秒向nacos注册中心更新一次
    • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
    • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式