0


nacos原理和实战问题解决方案

nacos原理和集群搭建实战,在开始之前、我们先要知道nacos的官网并熟悉其基本特性

官网介绍

一、原理:

1、多种注册中心对比

2、nacos作为注册中心的核心功能

2.1、服务注册:

Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。

2.2、服务心跳:

在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。

2.3、服务同步:

Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。

2.4、服务发现:

服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存服务健康检查:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)

3、2.0版本以后的重大改变:

采用grpc通信,并且多占用两个端口号,默认是8848、9848、9849三个端口,因此在服务器端配置入方向规则时三个端口均要添加,否则客户端启动报错,即连不上nacos。

4、修改客户端服务状态报错:

解决方案:

4.1、先停掉nacos服务端
4.2、到nacos安装目录下,找到data->protocal
4.3、把protocal整个文件夹删了,然后重启nacos就行了

如图:

5、微服务集成必须首先关注版本问题:

版本说明

举例:

5.1、父工程

   <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.8.RELEASE</spring-cloud-alibaba.version>
    </properties>

<dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

5.2、子工程:直接引用jar就行,不需要版本了,因为父工程已经引入了。

        <!-- nacos服务注册与发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

6、启动报错:JDK版本问题

日志:

Error: Could not find or load main class 
Caused by: java.lang.ClassNotFoundException: 

修改为1.8版本或者修改nacos的配置。

版本参考

7、nacos相关配置参考:

配置参考

客户端配置示例:

spring:
  application:
    name: man-user  #微服务名称

  #配置nacos注册中心地址
  cloud:
    nacos:
      discovery:
        #server-addr: 127.0.0.1:8848
        #namespace: 9cb9463e-81fc-4837-9f13-db061fe91952
        server-addr: 116.204.80.152:8848
        namespace: 2aa2111a-3470-4f69-9994-e9d288e20a62
        #cluster-name: SH
        group: wanghuainan
        #cluster-name: BJ
        #group: tulingshop
        #ephemeral: false

8、服务隔离:

Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP。

8.1、Namespace 隔离设计

命名空间(Namespace)用于进行租户(用户)粒度的隔离,Namespace 的常用场景之一是不同环境的隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

8.2、 group服务分组

不同的服务可以归类到同一分组,group也可以起到服务隔离的作用。yml中可以通过spring.cloud.nacos.discovery.group参数配置

9、临时实例和持久化实例

在定义上区分临时实例和持久化 实例的关键是健康检查的方式。临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。临时实例需要能够自动摘除不健康实例,而且无需持久化存储实例。持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳, 所以不能自动摘除下线的实例。

    在大中型的公司里,这两种类型的服务往往都有。些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。而上层的业务服务,例如 微服务或者 Dubbo 服务,服务的 Provider 端支持添加汇报心跳的逻辑,此时就可以使用动态服务的注册方式。

     Nacos 1.x 中持久化及非 持久化的属性是作为实例的?个元数据进行存储和识别。
      Nacos 2.x 中继续沿用了持久化及非持久化的设定,但是有了一些调整。在 Nacos2.0 中将是否持久化的数据抽象至服务级别, 且不再允许一个服务同时存在持久化实例和非持久化实例,实例的持久化属性继承自服务的持久化属性。
# 持久化实例
spring.cloud.nacos.discovery.ephemeral: false

10、服务调用:

底层是ribbon做服务调用:

10.1、启动客户端

10.2、成功注册到nacos

10.3、 客户端调用配置

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author nadao
 */
@Configuration
public class RestConfig {
    
    @Bean
    @LoadBalanced  // 微服务名替换为具体的ip:port
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

10.4、请求端业务代码展示


@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/findOrderByUserId/{id}")
    public R  findOrderByUserId(@PathVariable("id") Integer id) {
        log.info("根据userId:"+id+"查询订单信息");
        // restTemplate调用,url写死
        //String url = "http://localhost:8020/order/findOrderByUserId/"+id;
        // ribbon实现,restTemplate需要添加@LoadBalanced注解
        // mall-order  ip:port
        String url = "http://mall-order/order/findOrderByUserId/"+id;

        R result = restTemplate.getForObject(url,R.class);
        return result;
    }
}

10.5、接收端业务代码


@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 根据用户id查询订单信息
     * @param userId
     * @return
     */
    @RequestMapping("/findOrderByUserId/{userId}")
    public R findOrderByUserId(@PathVariable("userId") Integer userId) {

        //模拟异常
        if(userId == 5){
            throw new IllegalArgumentException("非法参数异常");
        }
        //模拟超时
        if(userId == 6){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        log.info("根据userId:"+userId+"查询订单信息");
        List<OrderEntity> orderEntities = orderService.listByUserId(userId);
        return R.ok().put("orders", orderEntities);
    }
}

二、集群搭建

1、官网参考

搭建参考

2、奇数台服务器资源

到此,原理和集群搭建分享完毕,下篇我们分析nacos的高级特性,敬请期待!

标签: spring cloud

本文转载自: https://blog.csdn.net/nandao158/article/details/128632529
版权归原作者 nandao158 所有, 如有侵权,请联系我们删除。

“nacos原理和实战问题解决方案”的评论:

还没有评论