Nacos学习

Nacos出现的原因?

因为Spring Cloud Netfiix项目进入了暂时维护模式,Spring Cloud原生注册中心Eureka不再更新了

Nacos能做啥?

  • 服务限流降级:默认支持servlet,Feign,RestTemplate,Dubbo和RocketMQ限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级Metrics监控
  • 服务注册与发现:适配Spring Cloud服务注册与发现标准,默认集成了Ribbon的支持,可方便的实现负载均衡
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新
  • 消息驱动能力:基于Spring Cloud Stream (内部用RocketMQ)为微服务应用构建消息驱动能力
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务,支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级,精准、高可靠、高可用的定时(基于Cron表达式)任务调度服务,同时提供分布式的任务执行模型,如网格任务,网格任务支持海量子任务均匀分配到所有Worker

Nacos是什么?

四个字母分别为:Naming(服务注册) 和 Configuration(配置中心) 的前两个字母,后面的s 是 Service

可以说Nacos = Eureka + Config + Bus,可以代替Eureka作为注册中心,可以代替Config作为配置中心,同时也支持配置修改后的热加载

比较

image-20200414165716292

Nacos作为注册中心实战

服务提供者注册到Nacos

yml文件

server:
  port: 9002
spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
management:
  endpoints:
    web:
      exposure:
        include: '*'

pom文件

 <dependencies>
        <!-- 添加Nacos相关依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>

启动类上要加入 @EnableDiscoveryClient 注解

@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

业务类

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

    @GetMapping("/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id) {
        return "nacos registry ,serverPore:"+serverPort+"\t id:"+id;
    }
}

启动服务,此时Nacos中的服务列表中就会出现你的服务

image-20201014160107872

可以启动一个服务的多个实例

image-20201014160355680

image-20201014160418276

启动这两个服务,可以看到此时的实例数为2

image-20201014160513968

服务消费者注册到Nacos

pom文件和启动类注解与上相同就不多说了,下面是配置文件和业务代码

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

# 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-provider
@RestController
public class OrderNacosController {
    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String serverURL;

    @GetMapping(value = "/consumer/payment/nacos/{id}")
    public String paymentInfo(@PathVariable("id")Long id){
        return restTemplate.getForObject(serverURL+"/payment/nacos/" + id, String.class);
    }
}

增加配置类

因为nacos集成了Ribbon,因此需要配置RestTemplate,同时通过注解 @LoadBalanced实现负载均衡,默认是轮询的方式

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemple() {
        return new RestTemplate();
    }
}

此时测试访问 http://localhost:83/consumer/payment/nacos/13

得到结果

image-20201014160855307
image-20201014160910529
由上图可知,访问了不同的服务,实现了负载均衡

Nacos作为服务配置中心演示

pom文件与上相同,因为需要先加载配置文件,所以需要添加bootstrap.yml文件(优先于application.yml加载),否则就会找不到配置文件,启动不了项目

spring:
  profiles:
    active: test # 开发环境
       #active: test # 测试环境
       #active: prod #生成环境

server:
  port: 3377
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # 注册中心
      config:
        server-addr: localhost:8848 # 配置中心
        file-extension: yaml # 这里指定的文件格式需要和nacos上新建的配置文件后缀相同,否则读不到
        group: TEST_GROUP
        namespace: test

  #${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}

业务代码

@RestController
@RefreshScope // 热加载的关键代码
public class ConfigClientController {
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo(){
        return configInfo;
    }
}

image-20200415201834108

我们的nacos-config-client-dev.yml和上图的文件匹配规则相对应

Nacos作为配置中心 - 分类配置

从上面的配置中心 + 动态刷新 , 就相当于 有了 SpringCloud Config + Spring Cloud Bus的功能

作为后起之秀的Nacos,还具备分类配置的功能

问题

用于解决多环境多项目管理

在实际开发中,通常一个系统会准备

  • dev开发环境
  • test测试环境
  • prod生产环境

如何保证指定环境启动时,服务能正确读取到Nacos上相应环境的配置文件呢?

同时,一个大型分布式微服务系统会有很多微服务子项目,每个微服务子项目又都会有相应的开发环境,测试环境,预发环境,正式环境,那怎么对这些微服务配置进行管理呢?

image-20200415203545643

image-20200415203611077

Namespace + Group + Data ID 三者关系

最外层的namespace是可以用于区分部署环境的

image-20200415203750816

默认情况:

Namespace=public,Group=DEFAULT_GROUP,默认Cluster是DEFAULT

Nacos默认的命名空间是public,Namespace主要用来实现环境隔离

比如说我们现在有三个环境:开发,测试,生产环境,我们就可以建立三个Namespace,不同的Namespace之间是隔离的。

Group默认是DEFAULT_GROUP,Group可以把不同微服务划分到同一个分组里面去

Service就是微服务,一个Service可以包含多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。比如说为了容灾,将Service微服务分别部署在了杭州机房,这时就可以给杭州机房的Service微服务起一个集群名称(HZ),给广州机房的Service微服务起一个集群名称,还可以尽量让同一个机房的微服务相互调用,以提升性能,最后Instance,就是微服务的实例。

下面是应用实例,划分了三个命名空间,dev,prod,test

image-20201014162423080

在dev中添加一个配置文件

image-20201014162652326

注意文件后缀要为yaml,否则会不匹配,导致服务启动的时候报错

image-20201014162726937

最后,在bootstrap.yml中修改group和namespace就可以进行不同配置文件的切换

比如上面的配置文件指定的是Test环境下的,那么启动服务,访问 http://localhost:3377/config/info
image-20201014162942614

修改group和namespace为dev,并且修改application.yml文件中的指定环境为dev,然后重启项目,继续访问

image-20201014163401148

posted @ 2020-10-20 13:23  kxhzzz  阅读(251)  评论(0)    收藏  举报