Nacos

一、Nacos简介      

      Nacos 是阿里巴巴的开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

Nacos 和Eureka一样,但是更强大。

常见的注册中心:

  1. Eureka(原生,2.0遇到性能瓶颈,停止维护)

  2. Zookeeper(支持,专业的独立产品。例如:dubbo)

  3. Consul(原生,GO语言开发)

  4. Nacos

二、配置中心

配置中心作用:可以将application.yml 中的内容配置到nacos,如果需要修改配置文件,不需要打开jar包,在jar包中修改,直接在nacos管理界面修改即可。

2.1新建配置文件

在nacos管理界面-配置中心-配置列表,点击右侧加号(如图)

 Data ID 的完整规则格式如下:
prefix-spring.profiles.active.file-extension

  • prefix 是所在模块的模块名,即配置文件中 spring.application.name 的值

  • spring.profiles.active 可以不填

  • file-exetension 为配置内容的数据格式,可以填yml或 properties

在下面的"配置内容"中,粘贴配置,我把代码里的application.yaml 删除,所有配置都放到nacos中,如果项目可以正常启动,且端口、数据库链接都是"配置内容"中的,说明成功读取了nacos配置中心的配置。

 2.2 引入依赖
        <!--        读取nacos配置依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
2.3在和application.yml平级的位置 新建 bootstrap.properties

这个文件的作用是指向配置文件,告诉程序读取哪里的配置文件、读取哪个配置文件 

#配置中心地址
spring.cloud.nacos.config.server-addr=localhost:8848

# 开启动态刷新配置,否则配置文件修改,工程无法感知
spring.cloud.nacos.config.ext-config[0].refresh=true

# 上一步设置的DataId
spring.cloud.nacos.config.ext-config[0].data-id=service-sta.properties
2.4验证

启动程序,不报错,且端口号是"配置内容"中的配置信息,证明使用了nacos中的配置。

2.5 动态配置

就是在"配置内容"中进行了修改,可以立刻通知到程序,如果不这么设置,需要将程序重启,才能读到新的配置。

2.5.0 具体做法

在bootstrap.properties 中,添加一行

# 开启动态刷新配置,否则配置文件修改,工程无法感知
spring.cloud.nacos.config.ext-config[0].refresh=true
2.5.1 验证

 在nacos管理界面点击 "编辑"(如图),随便修改一个配置项后点击"发布"

 程序中有如下输出,代表动态修改完成。

部分修改,比如数据库端口号、程序端口号等,无法立即生效,需要重启程序。

2.6 不同环境下的配置文件

在程序中,会有开发、测试和生产三个不同的环境,通常要写三个配置文件

application-dev.properties application-test.properties  application-prod.properties

使用nacos配置时,"命名空间" 提供了这样的功能,一个"命名空间"看作是一个环境,有一套配置文件。 

新建"命名空间",分别起名 dev test prod 

 克隆配置(每个"命名空间" 都有一套 yml 或propertis ,粘贴内容比较麻烦,可以写好一个后,将内容 直接克隆到其他"命名空间",再在其他"命名空间"中做修改):

 在boostrap.properties配置文件中,需要加一个配置项,设置使用的namespace编号

# 配置使用哪个环境的配置文件(namespace代表对应的环境及配置文件)
spring.cloud.nacos.config.namespace=ff2af6b8-2b3e-4d16-bc7d-f16947593c07

 三、注册中心

服务实例启动时,将自身信息(如服务名称、地址、端口等)注册到Nacos注册中心。

通过注册中心可以1.对微服务的各个模块进行管理、2.配合feign 实现模块间互相调用。

3.1 将单个项目注册到注册中心

3.1.1 pom文件中引入依赖 并指定版本
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>

    <artifactId>project_test</artifactId>
    <version>0.0.1</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <packaging>jar</packaging>
    <dependencies>
        <!--hystrix依赖,主要是用  @HystrixCommand -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <!--服务注册-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        <!--服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <!--打包规则,打包时将resource文件夹打包进去-->
        <resources>

            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.1.RELEASE</version>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
3.1.2 启动类添加服务发现注解@EnableDiscoveryClient
@EnableFeignClients
@EnableDiscoveryClient
@ComponentScan("com.example")
@SpringBootApplication
public class SpringCloudTest2Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudTest2Application.class, args);
    }

}
3.1.3 application.properties中指明 nacos地址
spring.cloud.nacos.discovery.server-addr=localhost:8848

3.2 将子模块注册到nacos

可以在父模块的<dependencyManagement> 中声明 spring-cloud-dependencies 的版本,子模块的spring-cloud-starter-openfeign等依赖就可以不用写版本了,做到版本的统一管理。(<dependencyManagement> 专门用于管理子模块的版本,比如里面放了个依赖a,子模块不会自动引入依赖a,而是当子模块引入依赖b,且b是a的子包时,可以不用写b的版本号)

spring-cloud-dependencies的子包是spring-cloud-starter-openfeign,父模块的<dependencyManagement>中声明 spring-cloud-dependencies 的版本了,子模块中引用spring-cloud-starter-openfeign,就可以不用写版本编号。

其他的比如主类注解、application.properties的配置,和单模块一致。

父模块:

    <dependencyManagement>
        <dependencies>
            <!--Spring Cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


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

子模块:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringCloudTest</artifactId>
        <groupId>com.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>

    <artifactId>model_test</artifactId>
    <version>0.0.1</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <packaging>jar</packaging>
    <dependencies>
        <!--hystrix依赖,主要是用  @HystrixCommand -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <!--服务注册-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>
        <!--服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <!--打包规则,打包时将resource文件夹打包进去-->
        <resources>

            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.1.RELEASE</version>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

四、结合Feign实现 远程调用

即一个注册到naocs的模块,调用另一个注册到nacos模块中的接口

4.1添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--服务调用-->

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
4.2 具体代码
4.2.1 调用方

 4.2.1.1  主类需要添加@EnableFeignClients 注解

  这个注解会告诉 Spring Cloud 扫描代码,查找 @FeignClient 注解的接口

@EnableFeignClients
@EnableDiscoveryClient
@ComponentScan("com.example")
@SpringBootApplication
public class SpringCloudTest2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudTest2Application.class, args);
    }

}

 4.2.1.2 编写Client类,通过调用这个类中的方法,可以访问到project-test模块的接口

@Component

// 被调用模块的名称
@FeignClient("project-test")
public interface UserClient {

// 被调用模块的接口地址
    @GetMapping("/project/interface")
    Integer callProjectModle();
}

4.2.1.3 具体调用

@RestController
public class OriginCallController {
    @Autowired
    UserClient userClient;

    @GetMapping("/orgincall")
    public Integer registerCount(){
      return   userClient.callProjectModle();
    }
}
4.2.2 被调用方

 被调用方正常写接口就行,不需要额外配置

@RestController
public class EduClient {

    @GetMapping("/project/interface")
    public R recordMsmLog(){
    return R.ok();    
}
}
4.3 feign的熔断器

当被调用方出错时,比如被调用方服务停止了、被调用方接口因并发访问次数过多,响应时间太长时,可以直接调用异常处理方法,至少给客户响应一个基本信息,而不是一个500报错或一直等待。

4.3.1.yml中开启熔断器

#nacos 注册中心地址
spring.cloud.nacos.discovery.server-addr=123.249.80.154:8848
# 开启feign熔断器
feign.hystrix.enabled=true

4.3.2.添加异常处理类,集成 Client接口

注意:这个类中的方法不能再抛异常,否则会报错:"[Request processing failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: EduClient#recordMsmLog(MsmLogVO) timed-out and fallback failed.] with root cause"

/**
 * <p>
 *  熔断器,当远程调用失败时被调用,至少给用户错误的提示信息,而不是简单的 500错误
 * </p>
 * @author hs1235-zhangyuankun
 * @date 2024/1/28 20:03
 */
@Component
public class EduClientFallCallback implements EduClient {

    @Override
    public R recordMsmLog(@RequestBody MsmLogVO msmLogVO) {
        return R.error(ErrorEnum.MSM_RECORD_ERROR);
    }
}

4.3.3Client接口中增加fallBack 

@FeignClient(name = "service-edu",fallback = EduClientFallCallback.class)
@Component
public interface EduClient {

    /**
     * 远程调用,登记短信的发送情况
     * @return
     */
    @GetMapping("/eduservice/base/base-msm-log/save")
    R recordMsmLog(@RequestBody MsmLogVO msmLogVO);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值