0. 引言

我们上一章讲解了spring cloud tencent的各个组件,本章我们将带大家从零搭建一个基于spring cloud tencent的微服务框架

1. 项目简介

我们需要搭建的微服务框架由如下几部分组成:

模块名描述
gateway网关模块
order-server订单模块

其中我们用订单模块模拟我们的业务服务,如果你自己需要多个微服务按照订单模块创建即可。如果有公用的方法、依赖等还可以抽取到一个单独的common服务模块中,然后通过pom依赖引入

2. 项目搭建

项目搭建之前请确保你已经安装并启动好polaris,安装教程可参考我之前的文章

spring cloud tencent:安装北极星polaris服务

2.1 创建父项目

1、首先我们需要创建一个空的maven项目作为父项目

在这里插入图片描述

2、项目命名为tencent-cloud-study

在这里插入图片描述

3、去除src目录,创建.gitignore文件,设置要忽略上传git的文件,并创建README.md文件,书写项目简介

在这里插入图片描述

4、我们在父项目的pom.xml文件中声明之后要用到的依赖的版本号,以此来实现版本的统一管理。

    <groupId>com.wu</groupId>
    <artifactId>tencent-cloud-study</artifactId>
    <name>tencent-cloud-study</name>
    <version>${revision}</version>
    <packaging>pom</packaging>

    <modules>
        <module>gateway</module>
    </modules>

    <properties>
        <java.version>1.8</java.version>
        <maven.version>3.8.1</maven.version>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <revision>1.0.0</revision>
        <spring.cloud.tencent.version>1.7.0-Hoxton.SR12</spring.cloud.tencent.version>
        <spring.cloud.version>Hoxton.SR12</spring.cloud.version>
        <spring.framework.version>5.2.22.RELEASE</spring.framework.version>
        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
    </properties>

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

            <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>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>${spring.framework.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

spring-cloud-tencent依赖的版本管理可参考官方说明

在这里插入图片描述

2.2 创建网关模块

1、父项目下创建一个springboot的子项目gateway,作为我们的网关模块

在这里插入图片描述

2、后续我们需要在网关模块中连接上服务注册中心,以及使用限流和路由转发。因此我们需要引入对应依赖。

这里网关我们采用的是spring-cloud-gateway,当然也可以使用其他网关,比如zuul,只需要更换依赖和配置文件中的配置项即可

    <parent>
        <artifactId>tencent-cloud-study</artifactId>
        <groupId>com.wu</groupId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>
    <name>gateway</name>

    <dependencies>
        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
        </dependency>

        <dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-router</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

需要注意的是,这里我们通过申明revision变量来实现项目版本的统一申明,如果使用其他的自定义的变量名,在后续子项目中使用时会有报红,但不影响使用,如下图所示

在这里插入图片描述

3、修改配置文件application.yml

server:
  port: 80

# 应用名称
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
          enabled: true
      routes:
        # 路由ID,唯一即可,一般建议服务名
        - id: 商品服务 product-server
        # 如果不单独使用注册中心的话,uri可以用具体的ip地址,比如uri:http://localhost:8081,http://localhost8082
          uri: lb://product-server
        # 路径断言:当请求url以/product-server开头的转发到这个路由的服务地址上
          predicates:
            - Path=/product-server/**
        - id: 订单服务 order-server
          uri: lb://order-server
          predicates:
            - Path=/order-server/**
    polaris:
      # 配置注册中心
      address: grpc://192.168.244.15:8091
      namespace: default

2.3 创建订单模块

1、父项目下新增springboot项目order-server

在这里插入图片描述

2、因为要书写接口,并且要注册要polaris上,所以添加如下依赖

<dependency>
            <groupId>com.tencent.cloud</groupId>
            <artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

3、修改配置文件

server:
  port: 8090

spring:
  application:
    name: order-server
  cloud:
    # 注册中心地址
    polaris:
      address: grpc://192.168.244.15:8091
      namespace: default

4、书写一个接口,用于后续测试

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

    @GetMapping("list")
    public List<OrderData> list(){
        List<OrderData> list = new ArrayList<>();
        OrderData order = new OrderData();
        order.setId(1L);
        order.setNo("2022073100001");
        order.setAddress("上海路101号");
        order.setPrice(new BigDecimal("100.0"));
        list.add(order);
        return list;
    }

}

5、启动gateway,order-server服务,访问http://localhost/order-server/order/list接口

在这里插入图片描述

数据正常返回,说明请求通过gateway转发成功

登陆polaris,在服务列表页面也能看到gateway,order-server已经成功注册上去

在这里插入图片描述

2.4 搭建配置中心

接下来我们来尝试使用polaris实现配置中心的作用。官方示例文档

1、我们尝试将自定义的订单信息order.noorder.address作为配置项,配置到配置中心里。当然我这里没有连接数据库,一般我们是将数据库、redis等连接信息作为配置项配置到配置中心中

2、order-server服务的依赖中添加config依赖

<dependency>
    <groupId>com.tencent.cloud</groupId>
    <artifactId>spring-cloud-starter-tencent-polaris-config</artifactId>
</dependency>

3、修改配置文件,其中spring.cloud.polaris.config.address用来指定配置中心地址,如果你的注册中心和配置中心使用的同一台服务器,则不用再单独申明配置中心地址,否则就需要声明,如下所示(我这里为了给大家演示,尽管使用的是同一个服务器,我还是配置出来)

另外需要注意的是因为服务启动强依赖配置,所以spring cloud config实在bootstrap阶段加载配置文件,因此我们配置中心的配置需要写到bootstrap.yml文件中,于是我们需要单独创建bootstrap.yml文件,配置内容如下

spring:
# 这里服务名需要添加到boostrap.yml中,否则会报错
  application:
    name: order-server
  cloud:
    # 注册中心地址
    polaris:
      address: grpc://192.168.244.15:8091
      namespace: default
      config:
        # 选填,只有在配置中心和注册中心是两个不同的地址时才需要配置
#        address: grpc://192.168.244.15:8093
        # 选填,当配置发布后,动态刷新 Spring 上下文,默认值为 true面
        auto-refresh: true
        groups:
          - name: ${spring.application.name}
            files: [ "application.yaml" ]

application.yml配置文件内容调整为:

server:
  port: 8090

order:
  title: ${wu.title}

3、登陆polaris,进入配置分组页面,点击新建配置分组。我们之后将订单相关的配置文件都添加到这个分组下。

官方推荐的是根据服务名来创建一个配置分组,配置中心会自动到与服务名同名的配置分组下读取配置文件。但如果你的配置文件是放在非服务名的配置分组下,或者配置文件命名是自定义的,就需要单独定义spring.cloud.polaris.config.groups配置

spring:
  cloud:
    polaris:
      config:
        groups:
          - name: ${spring.application.name} # 选填,注入自定义配置的配置分组
           # 注入自定义配置文件列表,当 key 冲突时,排在前面的配置文件优先级高于后面
            files: [ "config/application.properties", "config/bootstrap.yml" ] 

这里命名空间选择的default,实际开发时应该自己创建一个命名空间,用来标识不同的环境、集群等。

有了分组,我们就可以实现同一个服务下创建多个配置文件,用来实现一些自定义的配置文件需求

在这里插入图片描述

polaris会按照如下的配置文件顺序来加载,优先级从上往下逐渐降低

application-${activeProfile}.properties
application-${activeProfile}.yml
application.properties
application.yml
bootstrap-${activeProfile}.properties
bootstrap-${activeProfile}.yml
bootstrap.properties
bootstrap.yml

4、点击进入该分组,点击新增,新增一个配置文件

在这里插入图片描述

输入相关信息

在这里插入图片描述

提交之后,点击该配置文件,点击编辑,输入配置信息,然后点击保存。最后发布即可。

在这里插入图片描述

5、我们将OrderData实体类上添加注解,以此从配置文件中获取配置项,注意这里将no属性名改成了orderNo,博主实测过程中发现polaris中no属性无法正常读取,也算顺便发现了一个bug吧

@Data
@Component
@ConfigurationProperties(prefix = "wu.order")
public class OrderData implements Serializable {

    private Long id;

    private String orderNo;

    private BigDecimal price;

    private String address;
}

6、重写了OrderController,提供了四种调用配置项的方式:

  • 通过@ConfigurationProperties注解从配置类获取
  • 通过@Value直接从polaris的配置文件中配置的配置项获取
  • 通过@Value从本地配置文件中获取,本地配置文件中利用${xxx}从polaris的配置文件中获取
  • 通过Environment直接从polaris的配置文件中配置的配置项获取
@RestController
@RequestMapping("order")
public class OrderController {

    @Value("${wu.order.address}")
    private String address;

    @Value("${order.title}")
    private String title;

    @Autowired
    private Environment environment;

    @Autowired
    private OrderData orderData;

    @GetMapping("list")
    public List<OrderData> list(){
        List<OrderData> list = new ArrayList<>();
        OrderData order = new OrderData();
        order.setId(1L);
        order.setOrderNo("DH111");
        order.setAddress("上海路101号");
        order.setPrice(new BigDecimal("100.0"));
        list.add(order);
        return list;
    }

    @GetMapping("get")
    public OrderData get(){
        return orderData;
    }

    @GetMapping("address")
    public String address(){
        return address;
    }

    @GetMapping("address2")
    public String address2(){
        return environment.getProperty("wu.order.address");
    }

    @GetMapping("title")
    public String title(){
        return title;
    }

}

7、重启order-server服务

8、调用四个接口,测试配置项调用情况

  • get接口
    在这里插入图片描述
  • title接口

在这里插入图片描述

  • address接口

在这里插入图片描述

  • address2接口

在这里插入图片描述

从测试结果来看,成功从配置中心获取到了配置项,下面我们修改一下配置中心中的配置文件,来测试一下动态加载配置项的效果

我们修改wu.order.address的值,并重新发布

在这里插入图片描述

访问http://localhost/order-server/order/get接口,值确实发生改变了,说明动态刷新实现了

在这里插入图片描述

但我们再来看看http://localhost/order-server/order/address接口,其结果值还是没有改变,动态刷新并没有实现

在这里插入图片描述

同理我们看看address2接口,使用Environment却是实现了动态刷新

在这里插入图片描述

从上述结果告诉我们,如果想要实现动态刷新的话,要么使用@ConfigurationProperties注解方式,要么使用Environment来获取。大家不妨配置上数据库,看看能不能实现数据库连接信息的动态刷新吧

总结

那么本期我们针对spring cloud tencent的微服务框架就搭建完成了,当然本期搭建的还是最基础的,只是用到了网关、注册中心、配置中心,下一期我们将来进阶讲解spring cloud tencent其他组件的使用。

感兴趣的小伙伴不妨关注专栏。

本期演示代码可在如下地址下载:

源码地址

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐