【无限列车1】SpringCloudAlibaba 与 SpringBoot后端架构的搭建

1、版本说明

【SpringCloud 版本说明】https://sca.aliyun.com/zh-cn/docs/2022.0.0.0-RC1/overview/version-explain
在这里插入图片描述

🖊 RC(Release Candidate):发布候选版本(不再加入新功能,侧重改 BUG)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
        <relativePath/>
    </parent>

    <!-- 打包方式 -->
    <packaging>pom</packaging>

    <groupId>com.jagochan</groupId>
    <artifactId>unlimited-train-backend</artifactId>
    <version>1.0.0</version>

    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
        <spring-cloud-alibaba.version>2022.0.0.0-RC1</spring-cloud-alibaba.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <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>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

二、日志相关配置

🖊 新增会员模块(member)

@SpringBootApplication
public class TrainMemberApplication {
    private static final Logger LOG = LoggerFactory.getLogger(TrainMemberApplication.class);

    @SuppressWarnings("all")
    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(TrainMemberApplication.class, args);

        ConfigurableEnvironment env = ioc.getEnvironment();
        // http://www.network-science.de/ascii/
        LOG.info("\n      _                        _                 \n" +
                        "     | |                      | |                \n" +
                        "     | | __ _  __ _  ___   ___| |__   __ _ _ __  \n" +
                        " _   | |/ _` |/ _` |/ _ \\ / __| '_ \\ / _` | '_ \\ \n" +
                        "| |__| | (_| | (_| | (_) | (__| | | | (_| | | | |\n" +
                        " \\____/ \\__,_|\\__, |\\___/ \\___|_| |_|\\__,_|_| |_|\n" +
                        "               __/ |                             \n" +
                        "              |___/  \n" +
                        "会员模块启动成功(*^_^*) \n" +
                        "BaseURL: http://{}:{}{}", env.getProperty("server.address"),
                env.getProperty("server.port"),
                env.getProperty("server.servlet.context-path"));
    }
}

📕 logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 修改一下路径-->
    <property name="PATH" value="./log/member"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %blue(%-50logger{50}:%-4line) %thread %green(%-18X{LOG_ID}) %msg%n</Pattern>-->
            <Pattern>%d{mm:ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %thread %green(%-18X{LOG_ID})
                %msg%n
            </Pattern>
        </encoder>
    </appender>

    <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH}/trace.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${PATH}/trace.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern>
        </layout>
    </appender>

    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${PATH}/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${PATH}/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <layout>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern>
        </layout>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <root level="ERROR">
        <appender-ref ref="ERROR_FILE"/>
    </root>

    <root level="TRACE">
        <appender-ref ref="TRACE_FILE"/>
    </root>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

3、AOP 打印日志

📕 maven 依赖

 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.70</version>
 </dependency>
 <dependency>
     <groupId>cn.hutool</groupId>
     <artifactId>hutool-all</artifactId>
     <version>5.6.0</version>
 </dependency>
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>3.0.0</version>
</dependency>

📕 切面类

@Aspect
@Component
public class LogAspect {
    private final static Logger LOG = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("execution(public * com.jagochan..*Controller.*(..))")
    public void controllerPointcut() {
    }

    @Before("controllerPointcut()")
    public void doBefore(JoinPoint joinPoint) {

        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();

        // 打印请求信息
        LOG.info("------------- 开始 -------------");
        LOG.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        LOG.info("类名方法: {}.{}", signature.getDeclaringTypeName(), name);
        LOG.info("远程地址: {}", request.getRemoteAddr());

        // 打印请求参数
        Object[] args = joinPoint.getArgs();

        // 排除特殊类型的参数,如文件类型
        Object[] arguments = new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof ServletRequest
                    || args[i] instanceof ServletResponse
                    || args[i] instanceof MultipartFile) {
                continue;
            }
            arguments[i] = args[i];
        }
        // 排除字段,敏感字段或太长的字段不显示:身份证、手机号、邮箱、密码等
        String[] excludeProperties = {};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter excludeFilter = filters.addFilter();
        excludeFilter.addExcludes(excludeProperties);
        LOG.info("请求参数: {}", JSONObject.toJSONString(arguments, excludeFilter));
    }

    @Around("controllerPointcut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        // 排除字段,敏感字段或太长的字段不显示:身份证、手机号、邮箱、密码等
        String[] excludeProperties = {};
        PropertyPreFilters filters = new PropertyPreFilters();
        PropertyPreFilters.MySimplePropertyPreFilter excludeFilter = filters.addFilter();
        excludeFilter.addExcludes(excludeProperties);
        LOG.info("返回结果: {}", JSONObject.toJSONString(result, excludeFilter));
        LOG.info("------------- 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);
        return result;
    }

}

4、下载开源前端后台管理系统

# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git

# enter the project directory
cd vue-admin-template

# install dependency
npm install

# develop
npm run dev

5、添加网关模块

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

📕 TrainGatewayApplication.java

spring:
  cloud:
    gateway:
      routes:
        - id: member
          uri: http://127.0.0.1:5200
          predicates:
            - Path=/member/**

📕 添加JVM参数,让请求有日志

-Dreactor.netty.http.server.accessLogEnabled=true

6、集成数据库和mp

(1) 添加驱动和mp依赖

   <!-- MySql驱动 -->
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>8.0.22</version>
   </dependency>
   <!-- MyBatisPlus -->
   <dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.5.3</version>
   </dependency>

(2) 数据库配置

spring:
  application:
    name: train-member
  datasource:
    url: jdbc:mysql://gqok.xyz:3306/unlimited_train?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

(3) 使用MybatisPlus

  • MemberMapper 继承 BaseMapper
  • MemberService 继承 IService
  • MemberServiceImpl 继承 ServiceImpl

在这里插入图片描述

7、加密 yaml 文件中的内容

(1) 依赖

  <dependency>
      <groupId>com.github.ulisesbocchio</groupId>
      <artifactId>jasypt-spring-boot-starter</artifactId>
      <version>2.1.0</version>
  </dependency>

(2) 敏感信息加密

/**
 * 对配置文件中的敏感信息做加密处理
 */
public class JasyptUtil {
    public static void main(String[] args) {
        StandardPBEStringEncryptor stringEncryptor = new StandardPBEStringEncryptor();
        // 设置加密密钥(该密钥用于解密和加密)
        // 项目启动的时候要在JVM参数中配置
        stringEncryptor.setPassword("thePwdIsUsedToEncrypt");
        // 设置加密算法
        stringEncryptor.setAlgorithm("PBEWithMD5AndDES");

        // 对username进行加密处理, 加密后的字符串是密文, 要放到配置文件中
        String username = stringEncryptor.encrypt("username");
        System.out.println("🍀 username = " + username);

        // 对password进行加密处理, 加密后的字符串是密文, 要放到配置文件中
        String pwd = stringEncryptor.encrypt("password");
        System.out.println("🍀 pwd = " + pwd);
    }
}

(3) 把(2)中的加密字符串放到配置文件中

📕 加密字符串需要用 ENC() 包裹
🖊 如:ENC(thisIsASecret)

spring:
  application:
    name: train-member
  datasource:
    url: jurl: jdbc:mysql://happy.xyz:3306/unlimited_train?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: ENC(WWGfxe/CgyS4YnyCIZJvuXHbBn5D2y3XWlTmlKMA0mc=)
    password: ENC(8LARw5u9e9MkXTh/ZoxuFE8bIoUjwVMc/uDoKnriaZo=)
    driver-class-name: com.mysql.cj.jdbc.Driver
    
jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES

🖊 启动项目的时候要加 JVM 参数,配置解密密钥:
-Djasypt.encryptor.password=password

在这里插入图片描述

🖊 添加启动注解:@EnableEncryptableProperties

最近更新

  1. TCP协议是安全的吗?

    2024-04-05 04:12:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-05 04:12:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-05 04:12:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-05 04:12:03       20 阅读

热门阅读

  1. vector

    vector

    2024-04-05 04:12:03      19 阅读
  2. Redis 和 Memcached 之间有什么优点或缺点吗?

    2024-04-05 04:12:03       23 阅读
  3. 【前端开发】教程及案例.docx

    2024-04-05 04:12:03       21 阅读
  4. Go语言中如何正确使用getter和setter

    2024-04-05 04:12:03       18 阅读
  5. LeetCode //C - 981. Time Based Key-Value Store

    2024-04-05 04:12:03       20 阅读
  6. 【无标题】html中使用div标签的坏处

    2024-04-05 04:12:03       16 阅读
  7. 【积累】mysql

    2024-04-05 04:12:03       19 阅读
  8. mysql常见故障

    2024-04-05 04:12:03       24 阅读
  9. 4.2总结

    4.2总结

    2024-04-05 04:12:03      16 阅读
  10. 【leetcode面试经典150题】10.跳跃游戏 II(C++)

    2024-04-05 04:12:03       19 阅读
  11. 搭建本地YUM仓库

    2024-04-05 04:12:03       18 阅读
  12. C# OpenFileDialog

    2024-04-05 04:12:03       19 阅读
  13. 时间复杂度和空间复杂度

    2024-04-05 04:12:03       15 阅读