环境搭建

创建父工程 RuoYi-Cloud

使用 idea 创建 maven 结构的父工程,其 gav坐标为

  1. <groupId>com.ruoyi</groupId>
  2. <artifactId>ruoyi</artifactId>
  3. <version>1.0.0</version>

删除src目录

父工程一般都不需要写代码,因此 src 目录可以删除。

父工程 pom.xml 文件

主要做了哪些事情?
①、pom 表明这是一个父工程
②、全局定义了 SpringBoot、SpringCloud、以及SpringCloud Alibaba的版本号
③、覆盖了 alibaba-nacos 自带的nacos-client 版本号(1.4.1),将它改为了2.0.3。因为我们 nacos 服务器选择的也是 2.0.3 版本

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.ruoyi</groupId>
  7. <artifactId>ruoyi</artifactId>
  8. <version>1.0.0</version>
  9. <packaging>pom</packaging>
  10. <properties>
  11. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  12. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  13. <java.version>1.8</java.version>
  14. <spring-boot.version>2.5.3</spring-boot.version>
  15. <spring-cloud.version>2020.0.3</spring-cloud.version>
  16. <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
  17. <alibaba.nacos.version>2.0.3</alibaba.nacos.version>
  18. </properties>
  19. <dependencies>
  20. <!-- bootstrap 启动器 -->
  21. <dependency>
  22. <groupId>org.springframework.cloud</groupId>
  23. <artifactId>spring-cloud-starter-bootstrap</artifactId>
  24. </dependency>
  25. </dependencies>
  26. <dependencyManagement>
  27. <dependencies>
  28. <!-- SpringBoot 依赖配置 -->
  29. <dependency>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-dependencies</artifactId>
  32. <version>${spring-boot.version}</version>
  33. <type>pom</type>
  34. <scope>import</scope>
  35. </dependency>
  36. <!-- SpringCloud 微服务 -->
  37. <dependency>
  38. <groupId>org.springframework.cloud</groupId>
  39. <artifactId>spring-cloud-dependencies</artifactId>
  40. <version>${spring-cloud.version}</version>
  41. <type>pom</type>
  42. <scope>import</scope>
  43. </dependency>
  44. <!-- SpringCloud Alibaba 微服务 -->
  45. <dependency>
  46. <groupId>com.alibaba.cloud</groupId>
  47. <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  48. <version>${spring-cloud-alibaba.version}</version>
  49. <type>pom</type>
  50. <scope>import</scope>
  51. </dependency>
  52. <!-- Alibaba Nacos 配置 -->
  53. <dependency>
  54. <groupId>com.alibaba.nacos</groupId>
  55. <artifactId>nacos-client</artifactId>
  56. <version>${alibaba.nacos.version}</version>
  57. </dependency>
  58. </dependencies>
  59. </dependencyManagement>
  60. </project>

创建网关模块 ruoyi-gateway

在父工程下创建网关模块(ruoyi-gateway),其 gav 坐标为:

  1. <parent>
  2. <artifactId>ruoyi</artifactId>
  3. <groupId>com.ruoyi</groupId>
  4. <version>1.0.0</version>
  5. </parent>
  6. <modelVersion>4.0.0</modelVersion>
  7. <artifactId>ruoyi-gateway</artifactId>

注意了,ruoyi-gateway 作为 ruoyi 的子模块,因此在 父工程中会多出

  1. <modules>
  2. <module>ruoyi-gateway</module>
  3. </modules>

ruoyi-gateway 模块的 pom.xml 文件

做了哪些事情?
①、作为网关需要引入 spring-cloud-starter-gateway 依赖
②、我们需要把网关程序注册到 nacos, 因此需要引入 spring-cloud-starter-alibaba-nacos-discovery
③、我们需要实现动态配置功能,因此将 nacos作为配置中心,网关程序启动时需要读取 在nacos中的配置,
因此引入 spring-cloud-starter-alibaba-nacos-config 依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <groupId>com.ruoyi</groupId>
  7. <artifactId>ruoyi</artifactId>
  8. <version>1.0.0</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>ruoyi-gateway</artifactId>
  12. <dependencies>
  13. <!-- SpringCloud Gateway -->
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-starter-gateway</artifactId>
  17. </dependency>
  18. <!-- SpringCloud Alibaba Nacos -->
  19. <dependency>
  20. <groupId>com.alibaba.cloud</groupId>
  21. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  22. </dependency>
  23. <!-- SpringCloud Alibaba Nacos Config -->
  24. <dependency>
  25. <groupId>com.alibaba.cloud</groupId>
  26. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  27. </dependency>
  28. </dependencies>
  29. </project>

创建 bootstrap.yml 文件

做了哪些事情?
①、凡是微服务都必须定义的2个东西。“端口号” 和 “应用名”
②、服务注册的地址,即告诉网关程序服务往哪里注册
③、配置中心地址,即告诉网关程序去哪里获取配置信息

  1. server:
  2. port: 8080
  3. spring:
  4. application:
  5. name: ruoyi-gateway
  6. profiles:
  7. active: dev
  8. cloud:
  9. nacos:
  10. discovery:
  11. # 服务注册地址
  12. server-addr: 127.0.0.1:8848
  13. config:
  14. # 配置中心地址
  15. server-addr: 127.0.0.1:8848
  16. # 配置文件格式
  17. file-extension: yml
  18. # 共享配置
  19. shared-configs:
  20. - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

配置中心

打开 nacos 服务 -> 登陆到nacos控制台 -> 在配置管理中新建配置 ruoyi-gateway-dev.yml
现在我们还没有用到配置,所以该文件可以空着内容不写。

main方法

注意了,在较新版本 @EnableDiscoveryClient 注解不写也同样能完成微服务注册

  1. package com.ruoyi.gateway;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  5. import org.springframework.cloud.client.SpringCloudApplication;
  6. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  7. @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
  8. //@EnableDiscoveryClient 这个注解可以不需要写了
  9. public class RuoYiGatewayApplication {
  10. public static void main(String[] args) {
  11. SpringApplication.run(RuoYiGatewayApplication.class, args);
  12. }
  13. }

网关程序注册到nacos

运行 RuoYiGatewayApplication 的main 方法
image.png

创建认证中心模块 ruoyi-auth

在父工程下创建网关模块(ruoyi-auth),其 gav 坐标为:

  1. <parent>
  2. <artifactId>ruoyi</artifactId>
  3. <groupId>com.ruoyi</groupId>
  4. <version>1.0.0</version>
  5. </parent>
  6. <modelVersion>4.0.0</modelVersion>
  7. <artifactId>ruoyi-auth</artifactId>

ruoyi-auth 模块的 pom.xml 文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>ruoyi</artifactId>
  7. <groupId>com.ruoyi</groupId>
  8. <version>1.0.0</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>ruoyi-auth</artifactId>
  12. <dependencies>
  13. <!-- SpringBoot Web -->
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-web</artifactId>
  17. </dependency>
  18. </dependencies>
  19. </project>

创建 bootstrap.yml 文件

主要做了哪些事情?
①、定义了端口和应用名

  1. server:
  2. port: 9200
  3. spring:
  4. application:
  5. name: ruoyi-auth
  6. profiles:
  7. # 环境配置
  8. active: dev

主启动类

  1. package com.ruoyi.auth;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class RuoYiAuthApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(RuoYiAuthApplication.class, args);
  8. }
  9. }

编写测试Controller - HelloController

  1. package com.ruoyi.auth.controller;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. @RestController
  6. public class HelloController {
  7. @Value("${spring.application.name}")
  8. private String appName;
  9. @Value("${server.port}")
  10. private String port;
  11. @RequestMapping("/auth/hello")
  12. public String hello() {
  13. return appName + " 项目,端口号:" + port;
  14. }
  15. }

测试

运行 RuoYiAuthApplication 类的 main 方法。
image.png

网关转发

网关作为整个微服务的入口,一般都有如下几个用途!
①、请求转发。 即路由功能
微服务项目一般都是前后端分离的,那么前端发过来的请求不是请求到具体的微服务上,而是统一的经过 网关程序进行转发。这样做可以屏蔽到具体微服务地址
②、过滤
所有的请求都会经过网关,因此我们可以使用过滤功能,对请求进行加工和处理

简单的转发

在 ruoyi-gateway-dev.yml 配置文件中,配置转发规则。
如下表示如果发送 http://localhost:8080/auth/hello 请求,网关中的路径断言规则中 /auth/** 匹配到了,所以会
将请求转发到 http://localhost:9200

  1. spring:
  2. cloud:
  3. gateway:
  4. discovery:
  5. routes:
  6. - id: ruoyi-auth
  7. uri: http://localhost:9200
  8. predicates:
  9. - Path=/auth/**

转发路径去掉前缀

比如 http://localhost:8080/auth/hello 会转发时需要去掉 /auth 前缀。怎么弄?
①、修改 @RequestMapping(“/auth/hello”) 为 @RequestMapping(“/hello”)
②、在 ruoyi-gateway-dev.yml 文件中添加过滤器 StripPrefix 。

  1. spring:
  2. cloud:
  3. gateway:
  4. discovery:
  5. routes:
  6. - id: ruoyi-auth
  7. uri: http://localhost:9200
  8. predicates:
  9. - Path=/auth/**
  10. filters:
  11. - StripPrefix=1 # 去掉前缀

③、重启 网关和认证中心的程序,然后发送 http://localhost:8080/auth/hello 请求,观察效果是否和直接访问
http://localhost:9200/hello 效果一样?

网关的负载均衡转发

之前我们在路由转发的时候,路径都是写死的。例如:uri: http://localhost:9200 ,这样无法转发到多台微服务上

将认证中心模块(ruoyi-auth)注册到 nacos。

①、ruoyi-auth 模块引入依赖

  1. <!-- SpringCloud Alibaba Nacos -->
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  5. </dependency>

②、编写 bootstrap.yml 配置,使其注册到 nacos

  1. server:
  2. port: 9200
  3. spring:
  4. application:
  5. name: ruoyi-auth
  6. profiles:
  7. # 环境配置
  8. active: dev
  9. cloud:
  10. nacos:
  11. discovery:
  12. # 服务注册地址
  13. server-addr: 127.0.0.1:8848

网关模块 ruoyi-gateway

①、引入依赖, 如果跳过这一步,在最后运行网关程序的时候,会报出 type=Service Unavailable, status=503 错误

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  4. </dependency>

②、修改 ruoyi-gateway 在nacos中的配置,添加上负载均衡功能

  1. spring:
  2. cloud:
  3. gateway:
  4. discovery:
  5. locator:
  6. lowerCaseServiceId: true
  7. enabled: true
  8. routes:
  9. - id: ruoyi-auth
  10. #uri: http://localhost:9200
  11. #uri: lb://ruoyi-auth
  12. predicates:
  13. - Path=/auth/**
  14. filters:
  15. - StripPrefix=1 # 去掉前缀

测试

重启网关和认证中心程序
image.png
image.png