【开源风云】从若依系列脚手架汲取编程之道(八)

发布于:2024-11-27 ⋅ 阅读:(8) ⋅ 点赞:(0)

📕开源风云系列

  • 🍊本系列将从开源名将若依出发,探究优质开源项目脚手架汲取编程之道。
  • 🍉从不分离版本开写到前后端分离版,再到微服务版本,乃至其中好玩的一系列增强Plus操作
  • 🍈希望你具备如下技术栈
    • 🍎Spring
    • 🍍SpringMVC
    • 🍐Mybatis/Mybatis-plus
    • 🍅Thymeleaf
    • 🥝SpringBoot
    • 🍓Shiro
    • 🍏SpringSecurity
    • 🍌SpringCloud
    • 🍒云服务器相关知识
  • 本篇是微服务版最终篇

在这里插入图片描述

1、数据权限

数据权限指的是在数据库或数据系统中控制用户或角色对数据的访问权限的机制。它通过设置规则、策略或配置来限制用户能够访问、查
询、修改或删除哪些数据。数据权限通常用于确保敏感数据只能被授权的用户或角色访问,同时保护数据的安全性和完整性。

  • 举个最简单的例子:学生只能看到自己的成绩,老师可以看到全部学生的成绩。

若依微服务的数据权限是和角色绑定起来的:

在这里插入图片描述

和角色绑定起来的数据权限一共有五种:

  1. 全部数据权限
  2. 自定义数据权限
  3. 本部门数据权限
  4. 本部门及以下数据权限
  5. 仅本人数据权限

在这里插入图片描述

五种数据权限对应的数字标记的代码如下:

/**
 * 全部数据权限
 */
public static final String DATA_SCOPE_ALL = "1";

/**
 * 自定数据权限
 */
public static final String DATA_SCOPE_CUSTOM = "2";

/**
 * 部门数据权限
 */
public static final String DATA_SCOPE_DEPT = "3";

/**
 * 部门及以下数据权限
 */
public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";

/**
 * 仅本人数据权限
 */
public static final String DATA_SCOPE_SELF = "5";

面向切面编程:数据权限的底层为AOP,在SQL层面的字符串的拼接操作。若依中涉及到数据权限的查询操作其实只有几个:

  1. 查询用户:SysUserServiceImpl
    1. selectUserList、:根据条件分页查询用户列表
    2. selectAllocatedList、:根据条件分页查询已分配用户角色列表
    3. selectUnallocatedList:根据条件分页查询未分配用户角色列表
  2. 查询部门:SysDeptServiceImpl
    1. selectDeptList、:查询部门管理数据
  3. 查询角色:SysRoleServiceImpl
    1. selectRoleList、:根据条件分页查询角色数据

用到数据权限的操作只有上面5种方法。真正起作用的注解其实是:@DataScope,比如:@DataScope(deptAlias = "d", userAlias = "u"),这个 d 和 u 就是SQL层面的别名,拼接字符串就会拼接d.xxu.xx

1.1、全部数据权限

  1. 首先我们把普通角色的数据权限改为全部数据权限

数据权限是在Service层控制的,请求访问是先进Controller,Controller层有@RequiresPermissions注解检验是否有接口权限,只有通过Controller层才能来到Service层!

在这里插入图片描述

  1. 我们来debug切面DataScopeAspect
    1. 数据权限过滤关键字:首先clearDataScope对传入的SQL参数清理,防止SQL注入。参数非空且属于BaseEntity(Entity基类),才会取参数,并将参数变成空字符串。
    2. 真正进行切面处理,获得loginUser对象,loginUser.getSysUser()进而获得当前登录的用户信息。
    3. 取出接口的权限permission,执行核心方法dataScopeFilter

在这里插入图片描述

[!note]

这里看一下loginUser和loginUser.getSysUser的区别。

在这里插入图片描述

  1. debug核心方法dataScopeFilter
    1. 新建StringBuilder用于SQL拼接,新建ArrayList用于将数据权限dataScope的值存储。
    2. 遍历当前用户的角色,因为当前用户可能有两三个角色,所以for循环取出角色的数据权限
    3. 由于我们目前是全部数据权限,所以dataScope是1,将1添加到ArrayList
    4. 再次判断用户是否有接口权限,有了接口权限,才能谈数据权限。
    5. 发现是全部数据权限,则清空拼接的字符串,直接返回。全部数据权限直接查就好,不需要拼接字符串。
    6. 全部数据权限也就是不设置权限。

在这里插入图片描述

1.2、本部门数据权限

  1. 首先我们把普通角色的数据权限改为本部门数据权限

对于ry用户来说,属于测试部门,测试部门以下没有其他子部门了,所以本部门数据权限和本部门及其以下数据权限对于ry用户来说是一样的。

在这里插入图片描述

在这里插入图片描述

很好理解,本部门权限就拼接SQL

or d.dept_id = 自己的部门id

之后会将 or 转为 and 即可。

1.3、仅本人数据权限

仅本人数据权限,拼接的sql为

or u.user_id = 自己的user_id

1.4、自定义数据权限

也是在拼接SQL,只是逻辑比上面的多一点而已。

2、操作日志

操作日志在分离版本有过debug,这里只介绍下使用方式:

如果要使用操作日志,只需要在Controller的方法上面加个注解:

@Log(title="xxx",businessType = BusinessType.UPDATE)

businessType 是记录业务类型,业务类型一共有下面这么多:

public enum BusinessType
{
    /**
     * 其它
     */
    OTHER,

    /**
     * 新增
     */
    INSERT,

    /**
     * 修改
     */
    UPDATE,

    /**
     * 删除
     */
    DELETE,

    /**
     * 授权
     */
    GRANT,

    /**
     * 导出
     */
    EXPORT,

    /**
     * 导入
     */
    IMPORT,

    /**
     * 强退
     */
    FORCE,

    /**
     * 生成代码
     */
    GENCODE,

    /**
     * 清空数据
     */
    CLEAN,
}

3、monitor-admin

服务监控:监视当前系统应用状态、内存、线程、堆栈、日志等等相关信息,主要目的在服务出现问题或者快要出现问题时能够准确快速地发现以减小影响范围。

  • 为什么要使用服务监控?

服务监控在微服务改造过程中的重要性不言而喻,没有强大的监控能力,改造成微服务架构后,就无法掌控各个不同服务的情况,在遇到调用失败时,如果不能快速发现系统的问题,对于业务来说就是一场灾难。

  • spring boot actuator 服务监控接口

actuator是监控系统健康情况的工具

  • spring boot admin 服务监控管理

Spring Boot Admin是一个针对spring-bootactuator接口进行UI美化封装的监控工具。他可以:在列表中浏览所有被监控spring-boot项目的基本信息,详细的Health信息、内存信息、JVM信息、垃圾回收信息、各种配置信息(比如数据源、缓存列表和命中率)等,还可以直接修改logger的level。

推荐使用:官方文档

nacos其中在application.yml里面配置暴露所有监控端点:

management:
  endpoints:
    web:
      exposure:
        include: '*'
  • management 表示配置SpringBootActuator相关的管理功能。
  • endpoints 表示配置管理端点
  • web 表示配置Web端点
  • exposure 表示配置端点的暴露策略
  • include:'*' 表示将所有端点都暴露出来,即允许外部访问所有的管理端点

在这里插入图片描述

这段配置的作用是允许所有的管理端点都对外部暴露,这样可以让监控工具或者管理系统访问这些端点获取系统的运行状态、健康检查、配置信息等。需要注意的是,对于一些敏感的端点,比如/actuator/env/actuator/configprops等,如果暴露出来可能会导致安全风险,因此在生产环境中建议根据实际需求仔细配置端点的暴露策略。

3.1、启动monitor

  1. 修改ruoyi-visual模块下的ruoyi-monitor的 bootstrap.yml 中注册中心和配置中心的IP
# Tomcat
server:
  port: 9100

# Spring
spring: 
  application:
    # 应用名称
    name: ruoyi-monitor
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 49.232.28.14
      config:
        # 配置中心地址
        server-addr: 49.232.28.14
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
  1. 启动ruoyi-visual-monitor模块
  2. 访问localhost:9100,账号 ruoyi、密码123456

在这里插入图片描述

3.2、实时日志

Spring Boot Admin提供了基于Web页面的方式实时查看服务输出的本地日志,前提是服务中配置了logging.file.name

  1. 在 ruoyi-modules-system 的 bootstrap.yml 添加
logging:
  file:
    name: logs/${spring.application.name}/info.log
  1. 重启 ruoyi-modules-system 模块

在这里插入图片描述

4、Sentinel熔断降级

Sentinel 是阿里巴巴开源的一个分布式系统的流量控制组件,它提供了多种流量控制策略来保护系统免受突发大量请求的影响。

官方文档

  • 服务熔断一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施。
  • 服务降级是在服务器压力陡增的情况下,利用有限资源,根据当前业务情况,关闭某些服务接口或者页面,以此释放服务器资源以保证核心任务的正常运行。

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。

  1. 修改nacos中的application-dev.yml
spring:
 cloud:
  sentinel:
   #取消控制台懒加载
   eager: true
   transport:
    #控制台地址
    dashboard: 127.0.0.1:8718
  1. https://github.com/alibaba/Sentinel/releases下载sentinel-dashboard-$version.jar

  2. 在cmd执行运行这个jar包

java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar D:\HappyCode\IDEA\RuoYi-Cloud-master\RuoYi-Cloud-master\sentinel\sentinel-dashboard-1.8.8.jar

在这里插入图片描述

注意将jar包放进sentinel目录下,我上图没放,或者将执行命令的绝对路径更换你自己的

  1. 访问localhost:8718,用户名和密码都是 sentinel

  2. 随便在若依管理系统访问一个api,比如用户管理

在这里插入图片描述

  1. 给这个api加上流控策略

在这里插入图片描述

在这里插入图片描述

以下是对各个字段的解释:

  • 资源名:定义了要进行流量控制的操作或资源名称。
  • 针对来源:选择默认值意味着该规则适用于所有来源的请求。
  • 阀值类型:可以选择 QPS(每秒查询率)或者并发线程数作为限制标准。
  • 单机阈值:设置单个服务器允许的最大 QPS 或并发线程数。
  • 是否集群:如果选中,则表示需要在多个节点上应用此规则。
  • 流控模式:可以选择直接、关联或链路三种模式。直接模式针对指定资源直接执行流控;关联模式可以基于其他资源进行流控;链路模式则会根据调用链路中的某个特定环节来进行整体的流量控制。
  • 流控效果:可以选择快速失败、Warm Up 或排队等待。快速失败即当达到阈值时立即拒绝新请求;WarmUp 表示先让一部分请求通过以逐渐适应负载变化,然后再完全开放;排队等待则是将超过阈值的请求放入队列中等待处理。

在这个例子中,已经预设了一个简单的流量控制规则:

  • 资源名为 “/user/getInfo”。
  • 针对来源是 “default”。
  • 使用 QPS 作为阀值类型,并设置了单机阈值为 1。
  • 没有启用集群模式。
  • 流控模式选择了直接模式。
  • 流控效果为快速失败。

然后就可以对接口进行压测了:在 Apifox 中开展 API 性能测试的全面指南

5、新建微服务

新建ruoyi-kuang微服务,然后写一个接口,先让服务经过gateway做转发,然后转发到ruoyi-kuang微服务,然后ruoyi-kuang去调用用户管理获得全部的用户,然后打印到控制台上。

  1. ruoyi-mpdules父项目下新建子模块ruoyi-kuang,重命名模块,引入依赖,修改 build

在这里插入图片描述

  1. 重命名模块,变得和若依的一样,同时修改artifactId为重命名的ruoyi-modules-kuang

在这里插入图片描述

  1. 添加依赖
<dependencies>
    <!--SpringCloud Alibaba Nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!--SpringCloud Alibaba Nacos Config-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <!--SpringCloud Alibaba Sentinel-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

    <!--SpringBoot Actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>


    <!--Swagger UI-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>${swagger.fox.version}</version>
    </dependency>

    <!--RuoYi Common Swagger-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-common-swagger</artifactId>
    </dependency>


    <!--RuoYi Common Security-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-common-security</artifactId>
    </dependency>

    <!--RuoYi Common DataSource-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-common-datasource</artifactId>
    </dependency>

    <!--RuoYi Api System-->
    <dependency>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-api-system</artifactId>
    </dependency>

    <!--Mysql Connector-->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
    </dependency>
</dependencies>
  1. 添加build
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  1. 新建bootstrap.yml
# Tomcat
server:
  port: 9902


# Spring
spring:
  application:
    # 应用名称
    name: ruoyi-kuang
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 49.232.28.14:8848
      config:
        # 配置中心地址
        server-addr: 49.232.28.14:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

  1. resources目录下新建banner.txt
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
Augenestern_Kuang!
  1. resources目录下新建logvack.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 日志存放路径 -->
	<property name="log.path" value="logs/ruoyi-kuang" />
   <!-- 日志输出格式 -->
	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />

    <!-- 控制台输出 -->
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>${log.pattern}</pattern>
		</encoder>
	</appender>

    <!-- 系统日志输出 -->
	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
	    <file>${log.path}/info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
			<!-- 日志最大的历史 60天 -->
			<maxHistory>60</maxHistory>
		</rollingPolicy>
		<encoder>
			<pattern>${log.pattern}</pattern>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
	</appender>

    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
	    <file>${log.path}/error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
			<!-- 日志最大的历史 60天 -->
			<maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
			<!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
			<!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- kuang日志级别控制  -->
	<logger name="com.ruoyi" level="debug" />
	<!-- Spring日志级别控制  -->
	<logger name="org.springframework" level="warn" />

	<root level="info">
		<appender-ref ref="console" />
	</root>
	
	<!--系统操作日志-->
    <root level="info">
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>
</configuration>

日志也就是改个名字以及日志级别为debug

  1. 在nacos中新建配置文件ruoyi-kuang-dev.yml,并填充一个 kuang: 小狂神 用于测试配置中心是否生效
kuang: 小狂神

# spring配置
spring:
  redis:
    host: 49.232.28.14
    port: 6379
    password: First123.
    database: 10
  datasource:
    # druid 服务监控的账号和密码
    druid:
      stat-view-servlet:
        enabled: true
        loginUsername: admin
        loginPassword: 123456
    # 动态数据源   
    dynamic:
      druid:
        # 初始创建的连接数
        initial-size: 5
        # 最小空闲连接数
        min-idle: 5
        # 最大活动连接数
        maxActive: 20
        # 获取连接的最大等待时间,单位毫秒
        maxWait: 60000
        # 建立连接的超时时间,单位毫秒
        connectTimeout: 30000
        # 读取数据的超时时间,单位毫秒
        socketTimeout: 60000
        # 连接空闲检查的时间间隔,单位毫秒
        timeBetweenEvictionRunsMillis: 60000
        # 连接空闲多久后可被驱逐,单位毫秒
        minEvictableIdleTimeMillis: 300000
        # 用于验证连接有效性的SQL语句
        validationQuery: SELECT 1 FROM DUAL
        # 当连接空闲时进行验证
        testWhileIdle: true
        # 当从连接池获取连接时进行验证
        testOnBorrow: false
        # 当连接返回连接池时进行验证
        testOnReturn: false
        # 是否缓存PreparedStatement
        poolPreparedStatements: true
        # 每个连接缓存的PreparedStatement数量
        maxPoolPreparedStatementPerConnectionSize: 20
        # Druid提供的过滤器,例如统计和日志记录
        filters: stat,slf4j
        # Druid的连接属性,包括合并SQL和慢SQL的阈值
        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
      datasource:
          # 主库数据源
          master:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://49.232.28.14:3306/kuangstudy_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
            username: kuangstudy_cloud
            password: 123456
          # 从库数据源
          # slave:
            # username: 
            # password: 
            # url: 
            # driver-class-name: 

# mybatis配置
mybatis:
    # 搜索指定包别名
    typeAliasesPackage: com.ruoyi.kuang
    # 配置mapper的扫描,找到所有的mapper.xml映射文件
    mapperLocations: classpath:mapper/**/*.xml

# swagger配置
swagger:
  title: 系统模块接口文档
  license: Powered By ruoyi
  licenseUrl: https://ruoyi.vip

在这里插入图片描述

  1. 写启动类RuoYiKuangApplication.java
@SpringBootApplication
@RefreshScope
@RestController
public class RuoYiKuangApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuoYiKuangApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  Kuang模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }

    @Value("${kuang}")
    private String kuang;

    @GetMapping("/test")
    public void test(){
        System.out.println(kuang);
    }
}

  1. 访问:localhost:9902/test,可以读取到配置中心的值

在这里插入图片描述

5.1、修改请求头拦截器

在若依的请求头拦截器HeaderInterceptor.java中,没有将token设置进请求头,微服务之间的调用又需要token作验证,所以需要改造一下。

  1. HeaderInterceptor.java中加入如下代码,目的是将token放入当前线程的Threadlocal中
SecurityContextHolder.setToken(ServletUtils.getHeader(request, SecurityConstants.Token));

在这里插入图片描述

  1. SecurityContextHolder.java中补充setToken和getToken的方法
public static void setToken(String token) {
    set(SecurityConstants.Token,token);
}

public static String getToken() {
    return get(SecurityConstants.Token);
}
  1. 还有在SecuirtyConstants.java中补充常量
/**
 * token
 */
public static final String Token = "Authorization";
  1. 在启动类上加上注解,打开openfeign
@EnableRyFeignClients
  1. RemoteUserService.java假客户端加入如下代码,在调用/user/list接口时,我们在请求头中多个头信息
/**
 * 新增用户管理的接口
 * @param userId
 * @param userName
 * @param userKey
 * @param token
 * @return
 */
@GetMapping("/user/list")
public TableDataInfo getUserList(@RequestHeader(SecurityConstants.DETAILS_USER_ID) Long userId,
                                 @RequestHeader(SecurityConstants.DETAILS_USERNAME) String userName,
                                 @RequestHeader(SecurityConstants.USER_KEY) String userKey,
                                 @RequestHeader(SecurityConstants.Token) String token

);
  1. RemoteUserFallbackFactory.java中实现上述方法
@Override
        public TableDataInfo getUserList(Long userId, String userName, String userKey, String token) {
            TableDataInfo info = new TableDataInfo();
            info.setMsg("调用用户管理失败:" + throwable.getMessage());
            return info;
        }

在这里插入图片描述

  1. 添加控制器KuangController
@RestController
public class KuangController {

    @Autowired
    private RemoteUserService remoteUserService;

    @GetMapping("/getUserList")
    public void test(){
        TableDataInfo userList = remoteUserService.getUserList(
                SecurityContextHolder.getUserId(),
                SecurityContextHolder.getUserName(),
                SecurityContextHolder.getUserKey(),
                SecurityContextHolder.getToken()
                );

        List<LinkedHashMap<String,Object>> rows = (List<LinkedHashMap<String,Object>>) userList.getRows();
        for (LinkedHashMap<String,Object> row : rows){
            System.out.println("row = " + row);
        }


    }
}
  1. 在nacos中ruoyi-gateway-dev.yml加一条路由
# kuang模块
- id: ruoyi-kuang
  uri: lb://ruoyi-kuang
  predicates:
    - Path=/kuang/**
  filters:
    - StripPrefix=1
  1. 重新启动启动类,先登录,之后再访问localhost:8080/kuang/getUserList

6、定时任务

  1. 修改定时任务的yml,修改注册中心和配置中心的信息
# Tomcat
server:
  port: 9203

# Spring
spring: 
  application:
    # 应用名称
    name: ruoyi-job
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 49.232.28.14:8848
      config:
        # 配置中心地址
        server-addr: 49.232.28.14:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

  1. nacos中修改ruoyi-job-dev.yml
# spring配置
spring:
  redis:
    host: 49.232.28.14
    port: 6379
    password: First123.
    database: 10
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://49.232.28.14:3306/kuangstudy_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: kuangstudy_cloud
    password: 123456

# mybatis配置
mybatis:
    # 搜索指定包别名
    typeAliasesPackage: com.ruoyi.job.domain
    # 配置mapper的扫描,找到所有的mapper.xml映射文件
    mapperLocations: classpath:mapper/**/*.xml

# swagger配置
swagger:
  title: 定时任务接口文档
  license: Powered By ruoyi
  licenseUrl: https://ruoyi.vip

  1. 启动RuoYiJobApplication.java启动类

7、生成代码

  1. 修改bootstrap.yml
# Tomcat
server:
  port: 9202

# Spring
spring: 
  application:
    # 应用名称
    name: ruoyi-gen
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 49.232.28.14:8848
      config:
        # 配置中心地址
        server-addr: 49.232.28.14:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
  1. 修改naocs中的ruoyi-gen-dev.yml
# spring配置
spring:
  redis:
    host: 49.232.28.14
    port: 6379
    password: First123.
    database: 10
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://49.232.28.14:3306/kuangstudy_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: kuangstudy_cloud
    password: 123456

# mybatis配置
mybatis:
    # 搜索指定包别名
    typeAliasesPackage: com.ruoyi.gen.domain
    # 配置mapper的扫描,找到所有的mapper.xml映射文件
    mapperLocations: classpath:mapper/**/*.xml

# swagger配置
swagger:
  title: 代码生成接口文档
  license: Powered By ruoyi
  licenseUrl: https://ruoyi.vip

# 代码生成
gen:
  # 作者
  author: ruoyi
  # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
  packageName: com.ruoyi.system
  # 自动去除表前缀,默认是false
  autoRemovePre: false
  # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
  tablePrefix: sys_

  1. 启动启动类即可。

8、文件上传下载

  1. 修改bootstrap.yml
# Tomcat
server:
  port: 9300

# Spring
spring: 
  application:
    # 应用名称
    name: ruoyi-file
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 49.232.28.14:8848
      config:
        # 配置中心地址
        server-addr: 49.232.28.14:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

  1. naocs中的ruoyi-file-dev.yml不用修改,我们用的是本地文件上传
# 本地文件上传    
file:
    domain: http://127.0.0.1:9300
    path: D:/ruoyi/uploadPath
    prefix: /statics

# FastDFS配置
fdfs:
  domain: http://8.129.231.12
  soTimeout: 3000
  connectTimeout: 2000
  trackerList: 8.129.231.12:22122

# Minio配置
minio:
  url: http://8.129.231.12:9000
  accessKey: minioadmin
  secretKey: minioadmin
  bucketName: test
  1. 启动启动类即可