本文主要供小白使用,详述 springcloud
项目在实战环境中如何搭建以及常见问题的解决方法,各微服务组件的具体使用及原理,后续我会逐步补充。本文后续论述均以如下环境为前提:
jdk
: 1.8
spring-boot
: 2.6.0
spring-cloud
: 2021.0.9
一、公共组件搭建
1. parent 项目搭建
1)pom.xml
文件搭建,这里只列举一些常用的依赖,自己补充其他的:
<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>2.6.0</version>
<relativePath/>
</parent>
<groupId>org.example.demo</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- 该项目只作为父项目供其他项目继承,所以这里使用 pom 打包类型 -->
<packaging>pom</packaging>
<name>common</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- json 解析 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.53</version>
</dependency>
<!-- 测试方法 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 自动生成 getter,setter 等方法的插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 引入 springboot 编译插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<!-- 选择性使用,默认只认 yaml、yml、properties 文件,当还需要使用到其他类型的文件时,建议加上 -->
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<!-- profile 定义,在 applitaion.yaml 文件中通过 @profileActive@ 来获取当前激活 profile -->
<profiles>
<profile>
<id>dev</id>
<properties>
<profileActive>dev</profileActive>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profileActive>test</profileActive>
</properties>
</profile>
<profile>
<id>stag</id>
<properties>
<profileActive>stag</profileActive>
</properties>
</profile>
<profile>
<id>release</id>
<properties>
<profileActive>release</profileActive>
</properties>
</profile>
</profiles>
</project>
2)构建完项目后,mvn clean install
到本地仓库即可使用。
2. common 项目搭建
common
项目用来存放其他微服务都会使用到的一些公共类、工具包、配置类、常量类、枚举类、异常处理类等公共资源,也可存放公共依赖配置。
1)pom.xml
公共依赖配置:
<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.example.demo</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>common</name>
<dependencies>
<!-- eureka 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 服务监控组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- web 应用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- feign 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 已踩坑:common 不作为 springboot 项目编译,所以这里忽略,否则打出来的包的公共类无法供其他微服务引用 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. 日志组件搭建
springboot
默认使用 logback
打印日志,配置方式有两种,简单点在 application.yaml
文件配置,复杂点在 logback-spring.xml
文件中配置,生产环境建议使用 logback-spring.xml
。
1)application.yaml
简单配置:
logging:
file:
# 当前打印日志文件位置
name: ./logs/spring.log
pattern:
# 设置控制台打印格式,可使用默认值
console: "${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"
# 设置归档文件打印格式,可使用默认值
file: "${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"
charset:
# 设置 file 字符
file: UTF-8
# 设置 console 字符
console: UTF-8
# 设置日志打印级别,常见的有 root、web、sql,也可自己指定某个类的打印级别
level:
web: trace
root: trace
# 自定义
org.example.test.ServiceA: info
# logback 设置
logback:
# 日志滚动策略
rolling policy:
# 每个文件大小
max-file-size: 2MB
# 所有文件大小
total-size-cap: 10MB
# 最大存储日志数
max-history: 5
# 日志归档文件格式
file-name-pattern: "./logs/spring.%d{yyyy-MM-dd}.%i.log"
2)使用 logback-spring.xml
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan: 若扫描到配置文件发生变化,则重新加载,默认为 true -->
<!-- scanPeriod: 扫描间隔,默认单位毫秒,默认间隔 1 分钟,只有当 scan 为 true 时生效 -->
<configuration scan="true" scanPeriod="10 seconds">
<!-- 变量定义 -->
<!-- 定义 logger 变量,通过 ${} 来获取变量值 -->
<property name="LOG_FILE" value="./logs/spring.log"/>
<property name="LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN" value="${LOG_PATH}/spring.%d{yyyy-MM-dd}.%i.log" />
<!-- 获取 spring 环境变量并重命名,source 表示 spring 变量名,示例为获取 applicaiton.yaml 文件中的变量 logging.file.name -->
<springProperty scop="context" name="file.name" source="logging.file.name" defaultValue="./logs/spring.log"/>
<!-- 日志打印格式-->
<!-- 控制台彩色日志打印格式:${VARIABLE_NAME:-DEFAULT_VALUE}: 获取变量 VARIABLE_NAME,若无值则取 DEFAULT_VALUE
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} :日期格式,{faint} 为颜色
%clr(${LOG_LEVEL_PATTERN:-%5p}) :日志级别,五个字符,不够左侧补空格
%clr(${PID:- }){magenta}:进程 PID
%clr(---){faint}:分隔符,为了美观规整
%clr([%15.15t]){faint}:线程名,长度小于 15 左侧补空格,大于 15 截断尾部长出字符
%clr(%-40.40logger{39}){cyan}:日志名
%-40.40:同线程名规则
%logger{39}:日志名,一般为日志所在类或包名
%clr(:){faint} %m%n:日志内容(%m)+ 换行(%n)
${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}:异常打印
-->
<!-- <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 文件日志格式不支持颜色 -->
<!-- <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 引入默认配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<!-- 自定义日志滚动策略,对应 application.yaml 中的 rolling policy -->
<!-- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!-- <encoder>-->
<!-- <pattern>${FILE_LOG_PATTERN}</pattern>-->
<!-- <charset>${FILE_LOG_CHARSET}</charset>-->
<!-- </encoder>-->
<!-- <file>${log.dir}/spring.log</file>-->
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
<!-- <fileNamePattern>${log.dir}/spring-%d{yyyy-MM-dd}.%i.log</fileNamePattern>-->
<!-- <maxFileSize>100MB</maxFileSize>-->
<!-- <totalSizeCap>10GB</totalSizeCap>-->
<!-- <maxHistory>30</maxHistory>-->
<!-- </rollingPolicy>-->
<!-- </appender>-->
<!-- 异步写,底层使用内存 buffer,可提高性能,生产环境建议配置 -->
<appender name="FILE_ASYNC" class="ch.qos.logback.classic.AsyncAppender" immediateFlush="false" neverBlock="true">
<!-- 0:不丢失日志,10:若队列的 90% 已满,则丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 队列深度,默认值 256 -->
<queueSize>1024</queueSize>
<!-- 队列已满是否阻塞调用者,true 表示不阻塞 -->
<neverBlock>true</neverBlock>
<!-- 指定使用异步写的 appender,只能添加一个 -->
<appender-ref ref="FILE"/>
</appender>
<!-- 若在 maven 文件指定了 profile 集,可为不同环境下的日志配置不同策略 -->
<springProfile name="dev,test,stag">
<!-- 自定义某个类或包的日志策略,additivity 表示日志消息是否传递到 root 等父日志记录器,即 root 是否也打印该日志,false 表示不传递,true 表示传递,默认 true -->
<logger name="org.example.test.TestService" level="warn" additivity="false">
<appender-ref ref="FILE_ASYNC_HTTPTRACE" />
</logger>
<!-- 设置顶层日志记录器的日志级别 -->
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_ASYNC"/>
</root>
</springProfile>
<springProfile name="release">
<root level="info">
<appender-ref ref="FILE_ASYNC"/>
</root>
</springProfile>
</configuration>
3)logbook
使用:logbook
可以记录 http 日志,并可以指定打印的 http 格式。
在项目中引入依赖:
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>2.10.0</version>
</dependency>
在 applition.yaml
文件中配置:
logbook:
# 包括哪些路径
include:
- /**
# 不包括哪些路径
exclude:
- /v1/test/a
# 打印格式,有 curl、http、json、splunk 四个选项
format:
style: curl
# 敏感头,将会打印为 ***,还可设置敏感路径,敏感参数
obfuscate:
headers: Authorization
二、应用组件搭建
正常微服务应用,直接引用上边搭建的公共组件即可。
1)pom.xml
文件配置:
<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.example.demo</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>service-a</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-a</name>
<dependencies>
<dependency>
<groupId>org.example.demo</groupId>
<artifactId>common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2)服务 applitiaon.yaml
配置:
server:
port: 8081
spring:
application:
name: serviceA
eureka:
instance:
hostname: ${spring.cloud.client.ip-address}
instance-id: ${spring.cloud.client.ip-address}:${server.port}
client:
fetch-registry: true
register-with-eureka: true
registry-fetch-interval-seconds: 30
healthcheck:
enabled: true
service-url:
defaultZone: http://localhost:8080/eureka/
logbook:
include:
- /**
exclude:
- /v1/test/a
format:
style: curl
obfuscate:
headers: Authorization
3)启动类配置:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@SpringBootApplication
public class ServiceAApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceAApplication.class, args);
}
}
标签:入门,--,spring,boot,springframework,springcloud,org,cloud,搭建
From: https://www.cnblogs.com/aizen-sousuke/p/18470166