1. 快速开发

1.1 后台管理系统

根据微服务划分,我们需要一个后台管理系统来操作各个微服务的后台管理功能。如果从头到尾开发一个后台管理系统复杂且耗时,所以推荐使用码云上《人人开源》这个开源项目作为脚手架工程,来快速开发后台管理系统。我们的后台管理系统前后端分离,所以推荐使用renren-fast作为后台管理系统的后端工程,使用renren-fast-vue作为后台管理系统的前端工程。

2. 微服务基础[16-27] - 图1

要使用这个项目,我们首先需要将它们从Git上克隆下来,之后分别来处理工程

2. 微服务基础[16-27] - 图2

1.1.1 renren-fast

首先看renren-fast这个后台项目,删除项目中原有的.git文件,将项目拖到我们的GuLi_Mall工程中,之后将renren-fast加入我们项目的统一管理当中

  1. 在总工程的pom.xml中添加renren-fast

    1. <module>renren-fast</module>
  2. 修改renren-fast项目的配置文件application-dev.yml,修改其中关于数据库的配置

    1. url: jdbc:mysql://192.168.56.10:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    2. username: root
    3. password: root
  3. 新建gulimall_admin数据库,并执行renren-fast项目db文件夹下的mysql.sql文件,进行表格创建

2. 微服务基础[16-27] - 图3

  1. 运行当前项目,使用localhost:8080/renren-fast进行访问

1.1.2 renren-fast-vue

这个前端项目使用了node.js,所以使用之前,要装好这个项目的运行环境:

  1. 首先去官网下载并安装node.js,下载时注意版本最好与视频保持一致;之后打开cmd命令窗口,执行以下命令:

    1. # 配置npm使用淘宝镜像,不配置的去外网下载相关包,速度很慢
    2. npm config set registry http://registry.npm.taobao.org
  2. 配置完成之后,打开VsCode,在控制台终端处,输入npm install

! 出现问题:无法将”npm”项识别为cmdlet、函数、脚本文件或可运行程序的名称,问题描述和解决方案见5-2【问题描述】

! 出现问题:npm ERR! gyp ERR! stack Error: Can’t find Python executable “python”;问题描述和解决方案见5-3【问题描述】

  1. npm install成功之后,看项目中是否已经包含下图文件夹,如果包含下图所示文件夹,在终端输入npm run dev运行当前项目

2. 微服务基础[16-27] - 图4

1.2 逆向工程

我们没有必要着重于简单的增删改查代码,应该把更多的精力放在业务逻辑上,所以我们还需要使用《人人开源》中的renren-generator这个项目为我们每一个微服务生成基本的增删改查代码。

1.2.1 逆向工程搭建

  1. 首先将工程下载下来,之后删除项目中原有的.git文件,将项目拖到我们的GuLi_Mall工程中,将renren-generator加入我们项目的统一管理当中。在总工程的pom.xml中添加renren-generator

    1. <module>renren-generator</module>
  2. 修改renren-generator项目的配置文件application.yml,修改其中关于数据库的配置

    1. url: jdbc:mysql://192.168.56.10:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    2. username: root
    3. password: root
  3. 修改generator.properties文件 ```shell

    主目录

    mainPath=com.yaosy

    包名

    package=com.yaosy.gulimall

    模块名(根据自己要生成的服务修改)

    moduleName=product

    作者

    author=yaosy

    Email

    email=yaosy_8080@163.com

    表前缀(根据自己要生成的服务修改)

    tablePrefix=pms_

  1. 4. main\resources\template\Controller.java.vm模板中的@RequiresPermissions("${moduleName}:${pathName}:list")注解注释掉
  2. > 代码就是根据这个模板生成的,其中这个注解是shiro的,我们不用shiro,用spring,所以将先这个注解注释掉
  3. ```java
  4. // 删除这个包引用
  5. import org.apache.shiro.authz.annotation.RequiresPermissions;
  6. @RequestMapping("/list")
  7. // @RequiresPermissions("${moduleName}:${pathName}:list")
  8. public R list(@RequestParam Map<String, Object> params){
  9. PageUtils page = ${classname}Service.queryPage(params);
  10. return R.ok().put("page", page);
  11. }
  1. 运行当前项目,使用localhost:8080/renren-fast进行访问

1.2.2 整合生成代码

  1. 在前台页面,选择所有表,点击生成代码

2. 微服务基础[16-27] - 图5

  1. 将生成的代码解压之后,把main拷贝到相应的服务中同级目录

  2. 解决服务报错的问题

将生成的代码拷贝到服务中后,代码会有很多报错。我们新建一个Maven工程:gulimall_common,这个工程的作用是管理每一个微服务公共的依赖、Bean、工具类等。

<dependencies>

      <!-- MyBatisPlus 
                    Dao包中的@Mapper注解,Entity包中的@TableName和@TableId注解报错,
                    是因为这些注解是MyBatisPlus中的,我们引入MyBatisPlus的包
        -->
      <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.2.0</version>
      </dependency>

      <!-- Entity包中的@Data注解报错,是因为这个注解是lombok中的,我们引入lombok
                 在实体类上,用@Data注解,省去写get set方法,编译时会自动生成
        -->
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
      </dependency>

      <!-- 解决HttpStatus报错 -->
      <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4.12</version>
      </dependency>

         <!-- 解决StringUtils报错 -->
      <dependency>
          <groupId>commons-lang</groupId>
          <artifactId>commons-lang</artifactId>
          <version>2.6</version>
      </dependency>
</dependencies>

然后在每个微服务工程中引入gulimall_common工程,即可解决这些错误

<dependency>
      <groupId>com.yaosy.gulimall</groupId>
      <artifactId>gulimall_common</artifactId>
      <version>0.0.1-SNAPSHOT</version>
</dependency>

剩下还有Query、PageUtils、R、Constant等类找不到,我们将renren-fast项目中的这些类复制到我们的gulimall-common项目的对应目录中。基本上报错缺少的文件都可以在renren-fast项目中找到,然后复制到我们的gulimall-common即可。

1.2.3 整合MyBatis-Plus

由于我们的项目时使用MyBatis-Plus操作数据库,所以我们需要给我们的微服务工程整合MyBatis-Plus

  1. 导入MyBatis-Plus的依赖,由于后面所有的微服务都需要,所以我们将导入依赖写在gulimall-common中

    <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.2.0</version>
    </dependency>
    
  2. 配置,可以参考MyBatis-Plus的官网文档【MyBatis-Plus官网】

a> 配置数据源

导入数据库的驱动,由于后面所有的微服务可能都要操作数据库,所以我们将驱动写在gulimall-common中

<!-- 根据数据库版本导入驱动 -->
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.17</version>
</dependency>

<!-- 因为使用了servlet-api相关内容,所以导入servlet -->
<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <!-- 因为tomcat中有servlet-api,所以设置为provided,打包不用带servlet-api -->
      <scope>provided</scope>
</dependency>

创建一个application.yml文件,在application.yml配置数据源相关信息

# 配置数据源(注意:yml文件:后必须有一个空格)
spring:
  datasource:
    username: root
    password: root
    url:jdbc: mysql://192.168.56.10:3306/gulimall_pms
    driver-class-name: com.mysql.jdbc.Driver

b> 配置MyBatis-Plus

在启动类上使用@MapperScan,告诉MyBatis-Plus,Mapper接口都在哪

@MapperScan("com.yaosy.gulimall.product.dao")
@SpringBootApplication
public class GulimallProdutApplication {

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

}

在application.yml文件中配置,配置sql映射文件的位置,并设置主键自增。

在Entity类中可以看到@TableId注解,这个注解表示这个字段是一个主键,但是注解没有设置主键自增,点击查看注解可看到IdType type() default IdType.NONE。如果单独设置,我们需要在每一个实体类上设置,很麻烦,所以我们在application.yml文件中统一设置

mybatis-plus:
    -- mysql映射文件的位置
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
        -- 设置主键自增
      id-type: auto

1.2.3 单元测试

上述配置修改完成之后,就可以对当前生成的增删改查功能进行简单的测试。找到gulimall_product工程的启动类GulimallProdutApplicationTests,测试当前项目。方法运行成功之后去对应的表里面查看数据是否已经插入。

@RunWith(SpringRunner.class)
@SpringBootTest
public class GulimallProdutApplicationTests {

    @Autowired
    BrandService brandService;

    @Test
    public void contextLoads() {

        BrandEntity brand = new BrandEntity();
        brand.setName("华为");
        brandService.save(brand);
    }
}

! 出现问题:启动报错:java.lang.NoSuchMethodError,问题描述和解决方案见5-4【问题描述】

测试没有问题之后,根据上述步骤去生成其他几个模块的代码,每次记得修改renren-generator工程application.yml配置文件中对应的数据库;generator.properties配置文件中的moduleName与tablePrefix。另外还要在application.yml中配置每个服务的端口号。

# gulimall_coupon
server:
  port: 7000

# gulimall_member
server:
  port: 8000

# gulimall_order
server:
  port: 9000

# gulimall_produt
server:
  port: 10000

# gulimall_ware
server:
  port: 11000

! 出现问题:在application.yml文件中修改端口号,端口号没生效,还是8080,问题描述和解决方案见5-5【问题描述】

2. 搭建分布式系统的基本环境

在分布式开发中,我们必不可少的就是注册中心、配置中心和API网关。

因为分布式系统中有很多微服务,微服务之间又需要相互调用。所以每当一个微服务上线都应该将自己注册到注册中心。这样做的好处是:假如订单服务调用商品服务,订单服务可以先去注册中心看一下,哪些商品服务已经注册,可以调用。

其次,还需要一个配置中心,主要用来存放微服务的配置文件。假设一个服务分布在多台机器上,当我们需要修改服务的配置,就需要每台机器修改一次,很复杂。如果使用配置中心集中管理服务的配置,需要修改时,我们只需要修改配置中心的配置文件,每个服务实时去配置中心获取并修改自己的配置文件,这样就不用重复修改多次。

而网关则是在前台请求时进行鉴权、过滤、路由等。

2. 微服务基础[16-27] - 图6

SpringClould已经为我们提供了注册中心、配置中心和API网关这几个组件:

Spring Clould Eureka 注册中心
Spring Clould Config 配置中心
Zuul 网关

但是由于SpringCloud提供的组件有几大痛点:

  1. SpringCloud部分组件停止维护和更新,给开发带来不便;
  2. SpringCloud部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
  3. SpringCloud配置复杂,难以上手,部分配置差别难以区分和合理应用

所以我们推荐使用SpringClould Alibaba提供的组件:

  1. 阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用成套的产品搭配完善的可视化界面给开发运维带来极大的便利
  2. 搭建简单,学习曲线低。

结合SpringCloud Alibaba我们最终的技术搭配方案:

SpringCloud Alibaba - Nacos 注册中心(服务发现/注册)
SpringCloud Alibaba- Nacos 配置中心(动态配置管理)
SpringCloud - Ribbon 负载均衡
SpringCloud - Feign 声明式HTTP客户端(调用远程服务)
SpringCloud Alibaba-Sentinel 服务容错(限流、降级、熔断)
SpringCloud- Gateway API网关(webflux,编程模式)
SpringCloud- Sleuth 调用链监控
SptingCloud Alibaba - Seata 原Fescar,即分布式事务解决方案

要使用SpringCloud Alibaba,首先需要引入依赖,我们的每个服务都需要用到SpringCloud Alibaba,所以我们将SpringCloud Alibaba的依赖在gulimall_common的pom.xml中引入,详细使用方式可参照官方文档:【SpringCloud Alibaba官方文档】

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

2.1 使用Nacos作为注册中心

在SpringCloud Alibaba的官发给文档中,有详细的使用教程教我们如何使用Nacos作为注册中心

2. 微服务基础[16-27] - 图7

2.1.1 下载nacos-server

  1. 下载nacos-server:【nacos下载】

2.1.2 启动nacos-server

  1. 解压压缩包,双击bin文件夹中的startup.cmd,启动nacos

  2. 前台访问http://127.0.0.1:8848/nacos

  3. 使用默认的用户名和密码:nacos,登录进管理页面

2.1.3 将微服务注册到Nacos中

  1. 在我们的gulimall_common项目的pom.xml中引入依赖

    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  2. 在服务的application.yml文件中配置Nacos Server 地址 ```xml

    我们当前在本机启动nacos服务,所以IP用127.0.0.1,端口号是8848,也可使用server.port修改端口号

    cloud: nacos: discovery:

     server-addr: 127.0.0.1:8848
    

每一个服务都需要有一个名字,才能把服务注册进去,否则注册不进去

spring: application: name: gulimall_coupon


3. 在服务的启动类上使用 @EnableDiscoveryClient 注解开启服务注册与发现功能
```java
@SpringBootApplication
@EnableDiscoveryClient
public class GulimallCouponApplication {

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

之后在其他服务中重复上述第二步,第三步,将所有微服务注册到Nacos中

2. 微服务基础[16-27] - 图8

2.2 使用Spring Cloud Feign服务之间的远程调用

会员服务和优惠券服务分别部署在不同的机器上,假设会员服务要调用优惠券服务,那么就需要远程调用。调用之前会员服务要先去注册中心中看看优惠券服务在哪些机器上(从注册中心获取到对方服务所在的机器位置),假设优惠券服务部署在3台机器,会员服务需要挑一台机器,给他发送请求。

远程调用我们使用的是Spring Cloud Feign。

2.2.1 引入依赖

要使用Spring Cloud Feign,首先需要在工程中引入Spring Cloud Feign的依赖(我们在创建微服务的时候已经勾选引入了)

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

2.2.2 开启Feign功能

会员服务要远程调用优惠券服务,只需要在启动类上用@EnableFeignClients注解开启远程调用的功能


// basePackages:服务启动自动扫描这个包下标了FeignClients的接口
@EnableFeignClients(basePackages = "com.yaosy.gulimall.member.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallMemberApplication {

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

}

2.2.3 声明远程接口

open-feign是声明式远程调用,所以需要编写一个接口,并且告诉SpringCloud这个接口需要调用远程服务。用@FeignClient注解标明要调用哪一远程个服务(服务名与注册中心保持一致),并且要声明接口的每一个方法都是调用远程服务的哪一个方法

! 出现问题:项目启动报错:service id not legal hostname;问题描述和解决方案见5-6【问题描述】

/**
 * @description: 这是一个声明式的远程调用
 */
@FeignClient("gulimall-coupon")
public interface CouponFeignService {

    /**
     *  如果调用接口中的这个方法,会先去注册中心找远程服务gulimall_coupon的位置
     *  再去调用这个请求调用的方法
     * @return
     */
    @RequestMapping("/coupon/coupon/member/list")
    public R memberCoupons();
}

2.2.4 测试服务调用

  1. 在被调用的gulimall-coupon服务中编写一个被调用的方法

    @RequestMapping("/member/list")
    public R memberCoupons(){
    
     CouponEntity couponEntity = new CouponEntity();
     couponEntity.setCouponName("优惠券");
     return R.ok().put("coupons",Arrays.asList(couponEntity));
    }
    
  2. 在gulimall-member中使用远程接口类CouponFeignService调用gulimall-coupon的服务 ```java @Autowired CouponFeignService couponFeignService;

@RequestMapping(“/copons”) public R test (){

// 本地New的对象MemberEntity
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("张三");

// 调用远程服务返回的对象CouponEntity
R memberCoupons = couponFeignService.memberCoupons();
return R.ok().put("member",memberEntity).put("coupons", memberCoupons.get("coupons"));

}


如果服务掉线,注册中心不再有此服务,那么再调用就会出现异常

![](https://gitee.com/yaosy-seven/note_images/raw/master/img/20220102200636.png#crop=0&crop=0&crop=1&crop=1&height=126&id=J5voI&originHeight=324&originWidth=1289&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=500)

<a name="uih4w"></a>
## 2.3 使用Nacos作为配置中心

在SpringCloud Alibaba的官发给文档中,有详细的使用教程教我们如何使用Nacos作为配置

![](https://gitee.com/yaosy-seven/note_images/raw/master/img/20220102202548.png#crop=0&crop=0&crop=1&crop=1&height=275&id=yzIbB&originHeight=579&originWidth=2108&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=1000)

<a name="nq96X"></a>
### 2.3.1 如何使用Nacos作为配置中心

1. 在我们的gulimall_common项目的pom.xml中引入依赖
```xml
<dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 创建/src/main/resources/bootstrap.properties配置文件(名固定的,SpringBoot的规定),并配置Nacos Config元数据(bootstrap.properties会优先于application.properties读取) ```shell

    指定服务名

    spring.application.name=gulimall-coupon

指定配置中心的地址

spring.cloud.nacos.config.server-addr=127.0.0.1:8848


3. 给配置中心默认添加一个数据集(当前应用名.properties),并给这个文件中添加任意配置

![](https://gitee.com/yaosy-seven/note_images/raw/master/img/20220102220430.png#crop=0&crop=0&crop=1&crop=1&id=hefu6&originHeight=1330&originWidth=1770&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=)

4. 动态获取并刷新配置,前台请求[http://127.0.0.1:7000/coupon/coupon/test](http://127.0.0.1:7000/coupon/coupon/test)看是否获取到配置值
```java
// 在需要动态获取并刷新配置的类上添加这个注解
@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {

       // 用@Valu(${配置项的名})注解获取配置
    @Value("${coupon.user.name}")
    private String name;
    @Value("${coupon.user.age}")
    private String age;

    @RequestMapping("/test")
    public R test(){
        return R.ok().put("name",name).put("age",age);
    }
}

如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置

2.3.2 细节补充

2.3.2.1 命名空间

用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的Group或Data ID的配置。默认新增的所有配置都在public空间。

Namespace的常用场景:

  1. 利用命名空间来做环境隔离:开发、测试、生产

首先在Nacos的命名空间中新建dev、test、prod三个命名空间

2. 微服务基础[16-27] - 图9

然后在application.properties配置文件中配置我们当前微服务使用的命名空间

# 这里必须用命名空间的ID 值
spring.cloud.nacos.config.namespace=36a5ea66-8f10-44f2-ba5c-0dfb6b1109a3
  1. 每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置

2.3.2.2 配置集

所有的配置的集合。一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。

2.3.2.3 配置集ID

类似文件名。Nacos中的某个配置集的ID配置集ID是组织划分配置的维度之一。 Data ID通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID通常采用类Java包(如com.taobao.tc.refund.log.level) 的命名规则保证全局唯一性。此命名规则非强制。

2.3.2.4 配置分组

Nacos中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如Buy或Trade )对配置集进行分组,从而区分Data ID相同的配置集。当在Nacos上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用DEFAULT GROUP。配置分组的常见场景。不同的应用或组件使用了相同的配置类型。比如我们可以指定1111、618、1212不同的配置分组。我们也可以使用配置分组区分环境。

2.3.2.5 同时加载多个配置集

微服务任何配置信息,任何配置文件都可以放在配置中心中。只需要在bootstrap. propertics说明加载配置中心中哪些配置文件即可。@Value, @ConfigurationProperties……等以前SpringBoot任何方法从配置文件中获取值,都能使用。并且配置中心有的配置优先使用配置中心中的。

2.3.2.6 方案示例

我们为我们的每一个微服务创建命名空间,然后使用配置分组进行环境隔离。

  1. 为服务创建命名空间

  2. 将application.yml配置文件中的内容抽离区分成几个文件配置到Nacos中 ```json

    mybatis.yml

    mybatis-plus: mapper-locations: classpath:/mapper/*/.xml global-config: db-config: id-type: auto

datasource.yml

spring: datasource: username: root password: root url: jdbc:mysql://192.168.56.10:3306/gulimall_sms driver-class-name: com.mysql.jdbc.Driver

other.yml

spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 application: name: gulimall-coupon

server: port: 7000


3. 在微服务中只需要保留一个bootstrap.properties,指定我们需要用到的配置即可。
```xml
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

# 配置当前微服务的命名空间:一个微服务对应一个命名空间
spring.cloud.nacos.config.namespace=fd1c2beb-fbe4-49cb-9ea6-e33148426d3c
# 配置当前用到的命名空间中的配置分组
spring.cloud.nacos.config.group=dev

# 由于我们将配置文件拆分成了mybatis.yml、datasource.yml、other.yml三个细化文件,所以这里需要引入三个文件
spring.cloud.nacos.config.ext-config[0].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[0].group=dev
# 配置自动刷新,默认为false,修改配置文件之后不会自动刷新
spring.cloud.nacos.config.ext-config[0].refresh=true

spring.cloud.nacos.config.ext-config[1].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true

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

2.4 网关

网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。

比如:我们给商品服务发送请求,首先我们需要知道商品服务的地址,加入商品服务器有多台服务器,其中一台服务器掉线,如果没有网关,我们需要手动修改,所以需要网关动态地管理,他能从注册中心中实时地感知某个服务,上线还是下线。

另外请求的询问权限等也需要网关。

SpringCloud GateWay作为SpringCloud官方推出的第二代网关框架,取代了Zuul网关。我们当前使用SpringCloud GateWay组件做网关功能。

2.4.1 创建网关模块gulimall_gateway

  1. 使用Spring向导创建一个项目:gulimall_gateway,方式和创建其他微服务一致,引入的时候需要勾选一个Spring Cloud GateWay

2. 微服务基础[16-27] - 图10

  1. 网关服务还是需要依赖common工程,所以在在网关服务的pom.xml中引入gulimall_common的依赖

    <dependency>
       <groupId>com.yaosy.gulimall</groupId>
       <artifactId>gulimall_common</artifactId>
       <version>0.0.1-SNAPSHOT</version>
    </dependency>
    
  2. 网关服务也需要把自己注册到注册中心中,并且需要知道其他服务的地址,所以网关也需要开启服务的注册发现 ```java /**

    • @EnableDiscoveryClient开启服务的注册发现功能
    • exclude:因为我们的common项目中引入了mybatis相关内容,但是我们的网关服务不需要所以exclude **/ @EnableDiscoveryClient @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class GulimallGatewayApplication {

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

}


4. 配置服务注册中心的地址的服务名,网关的端口号我们统一用88
```xml
# 应用名称
spring.application.name=gulimall-gateway

# 注册中心的地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
server.port=88
  1. 引入配置中心,以后将配置文件都配置在配置中心中,新建配置中心的配置文件bootstrap.properties。我们每一个服务都有自己的命名空间,所以去Nacos新建一个gateway的命名空间

  2. 测试网关:我们的网关是http://localhost:88/,测试访问http://localhost:88/url=baidu,可以跳转到百度页面;以下配置可参考官网文档 ```xml

    配置好之后访问:http://localhost:88/hello?url=baidu

    相当于访问的是:http://www.baidu.com/hello

spring: cloud: gateway: routes:

    - id: baidu_rout
      uri: http://www.baidu.com  # 要跳转的地址
      predicates:        # 需要满足的断言规则,可以写数组 -
        - Query=url,baidu    # url=baidu

    - id: qq_rout
        uri: http://www.qq.com
        predicates:
          - Query=url,qq

```