看到很多帖子,说 SpringCloud 的 eureka 停止维护了,开始采用 SpringCloud Alibaba 的 Nacos 作为注册中心和配置中心,也具有可视化监控界面,非常方便。

配置 SpringCloud Alibaba 的依赖管理器

配置后,SpringCloud Alibaba 的组件依赖就不用规定版本了,都交给依赖管理器统一管理。

注意:版本需要跟 SpringBoot 的版本相互对应,要不会不兼容冲突。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Nacos

Nacos 致力于发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

安装

由于兼容性问题,我安装的是 1.1.3 版本的 nacos,不会出现启动闪退的情况。

注意:启动 Nacos 是要使用 java 环境的,请确定环境变量中添加了 JAVA_HOME, % JAVA_HOME%\bin

安装后启动 startup 程序:

image-20220426211641045

会启动 nacos 服务器,该服务器的是默认在 localhost:8848 启动的:

image-20220426211725554

注意:在 Springboot 项目启动过程中,Nacos 一定要保持在线状态!!

配置 注册中心(nacos-discovery)

注册中心,采用注册发现机制,上线一个微服务,就会到注册中心进行注册,注册中心对所有服务统一进行管理。

依赖配置

将子工程都需要的依赖导入父工程中,然后子工程依赖父工程,子工程就不用一个个配置相同的依赖了,方便很多。

注意,官网的是 boot 在 2.4 以下的依赖,如果是 2.6X 版本,需要排除 ribbon,并且导入 loadbalancer 依赖。

<!--配置nacos注册中心(服务注册发现)-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--loadbalancer-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
    <version>3.1.1</version>
</dependency>

注解配置

微服务中,每启动一个服务,都需要注册到注册中心中统一管理,那么在远程调用的时候,就知道哪些服务在线,方便进行相应的调用。

如何让一个应用注册到 Nacos 呢?其实及其简单,在主程序上加上一个注解 @EnableDiscoveryClient 就可以解决了!

@SpringBootApplication
//开启了应用服务注册发现功能
@EnableDiscoveryClient
@EnableFeignClients(basePackages= "com.gulimall.member.feign")
public class GulimallMemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallMemberApplication.class, args);
    }
}

配置文件

同时需要在应用配置文件 Application.yml 中配置相应的服务名,和 Nacos 服务器地址

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-member  //名字最好与服务模块名一样,方便管理

测试

这样,服务注册发现的配置就差不多配好了,咱们启动相应的服务,并访问 http://localhost:8848/nacos/index.html,就可以进入到 Nacos 主页,登录进去,可以看到相应服务的状态,就可以可视化管理微服务了:

image-20220426212315143

配置中心(nacos-config)

以前,如果要更改服务的某个配置,需要下线服务后修改好再重新打包部署上线,单体服务还好,但如果服务集群,那真的是裂开,有没有一种办法能统一管理一种服务的所有配置,并动态更改服务配置,就非常方便。

nacos-config 组件,就是一个配置中心,可以将一个服务的配置全部托管至配置中心中管理,就不需要再在服务配置文件中做过多冗余配置了。

配置依赖

注意:SpringBoot2.4x 之前的只需要导入 nacos-config 启动器,但是后面的版本还需要导入 BootStrap 依赖XML

<!--nacos配置中心-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>3.1.1</version>
</dependency>

配置文件

需要添加一个 BootStrap.Properties 配置文件,这个文件优先级是高于 Application.properties 的,在其中配置服务名和 Nacos 地址。

spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

传统方式,在 Applicaiton.yml 中添加配置:YML

coupon:
	user:
		name:jh
		age:20

之后通过 @value (“${coupon.user.name}”) 来获取相应的属性值,现在有了配置中心,所有配置都可以转移到配置中心上管理。

启动项目

观察到本地的配置跟可以跟 Nacos 配置中心的名字(Data Id)为 应用名.properties 的配置进行绑定。

SpringCloud分布式组件之玩转Nacos插图4

那么我们在配置中心上添加一个 Data Id 为 应用名.properties 的配置,就可以绑定到相应服务的配置了。

image-20220426222151101
image-20220426222202795

注意:创建的配置一定是 Properties,yml 可能出错噢!!

我们就不用在本地配置文件中编写属性配置了,直接交给配置中心统一管理就行了。

@RefreshScope

动态更新配置注解。

注意:如果配置中心和当前应用配置文件中都配置了相同的属性项。配置中心优先

命名空间

用作配置隔离。(一般每个微服务一个命名空间)

  • 默认为 public 命名空间
  • 可以自定义命名空间

一般,一个微服务就对应一个命名空间,方便对不同的服务配置做统一管理。

配置集

类似于配置文件名,即 Data ID (就是配置的名字加类型)

配置分组

不同配置对应的组别。默认所有的配置集都属于 DEFAULT_GROUP

image-20220427093659310

配置分类

往往将所有配置都写在一个配置文件中太过于复杂,且不易于维护,我们可以将整体配置按不同类型拆分成多个小的配置文件,合起来便是整个配置文件。

如何将本地的配置转移到配置中心呢?

很简单,只用在 bootstrap.properties 中添加相应的配置就行了。

注意:所有配置中心的配置都要写在 bootstrap.properties 中。

# 声明应用名
spring.application.name=gulimall-coupon
# nacos地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

# 使用对应命名空间号下的配置
spring.cloud.nacos.config.namespace=417a06cb-3f8e-4b49-8010-c9b2684c217f
# 选择对应命名空间下对应组的配置
spring.cloud.nacos.config.group=dev

# 扩展配置文件声明
spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
# 确认对应配置文件的组别
spring.cloud.nacos.config.extension-configs[0].group=dev
# 开启自动刷新
spring.cloud.nacos.config.extension-configs[0].refresh=true

spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml
spring.cloud.nacos.config.extension-configs[1].group=dev
spring.cloud.nacos.config.extension-configs[1].refresh=true

spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
spring.cloud.nacos.config.extension-configs[2].group=dev
spring.cloud.nacos.config.extension-configs[2].refresh=true

通常,我们采取每个微服务创建自己的命名空间,使用配置分组来区分环境(dev,test,prod…),同时一个环境的配置又可以通过分类拆分成小的配置文件,方便管理。但是,在开发过程中,为了方便,配置文件还是先写在本地,等部署完善后,再将配置转移至配置中心管理。

远程调用(Feign)

微服务中肯定存在互相调用,那么如何找到相应的服务并调用其中的接口,就要结合注册中心和 Feign 组件来完成。

配置依赖

在构建 boot 项目时勾选上 SpringCloud 的 OpenFeign 模块,就会导入相应依赖:XML

<!--配置SprigCloud-OpenFeign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

编写远程调用接口

不同微服务间通过 Feign 类来进行关联,编写相应的 Feign:JAVA

//@FeignClient声明此类是一个远程调用接口,参数为对应要调用服务的服务名
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
    @RequestMapping("/coupon/coupon/member/list")
    public R memberCoupons();
}

对应的服务接口方法

@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;
    
    @RequestMapping("/member/list")
    public  R memberCoupons()
    {
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setCouponName("满100减10");
        return R.ok().put("coupons", Arrays.asList(couponEntity));
    }
}

只需要把要调用服务的接口方法复制到 Feign 中,代表了想要调用对应服务的接口方法,调用接口的每一个方法都对应调用相应服务的一个接口。

主程序配置

同时,我们需要应用能够扫描到 Feign 并加载,在主程序中加上相应的 @EnableFeignClients 注解:JAVA

@SpringBootApplication
//开启注册发现功能
@EnableDiscoveryClient
//开启远程调用功能,启动应用时,扫描该包下的所有带@FeignClient注解类,这些类就是远程调用的一个个接口。
@EnableFeignClients(basePackages= "com.gulimall.member.feign")
public class GulimallMemberApplication {

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

测试

编写一个 controllerJAVA,启动两个服务,服务必须都上线,要不肯定不能完成相互调用,上线后,并访问相应接口,可以完成调用相应服务的对应接口。

@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    private MemberService memberService;

    @Autowired
    //注入Feign组件
    private CouponFeignService couponFeignService;

    @RequestMapping("/coupons")
    public R test()
    {
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("张三");
        R r = couponFeignService.memberCoupons();
        Object coupons = r.get("coupons");

        return R.ok().put("member",memberEntity).put("coupons",coupons);
    }
}

调用原理

调用远程调用接口的相应方法 –> 先去注册中心中找相应服务名的服务 –> 在匹配当前接口和调用服务的接口,完成匹配 –> 调用成功

总结

所有的实现都需要在启动 Nacos 的前提下,所以务必启动Nacos才能执行以上操作