第2章 使用Maven搭建SpringCloud项目
Maven两大核心功能:
依赖管理(Jar包管理)
构建项目(项目打包)
使用Eureka搭建注册中心
使用spring initializr创建spring cloud项目
SpringCloud和Maven简介
SpringBoot和SpringCloud:SpringBoot是单应用开发框架,SpringCloud是管理多个SpringBoot应用的微服务框架
GENERATE下载就可以了
下载完成后是个压缩包,解压后,打开idea,点击filer>open就可以导入项目了
项目初始化,要把代码管理优先做后,不管是学习还是工作,养成阶段性提交代码的习惯。代码管理选择git
一个项目里不是所有的文件都需要提交到git,比如.iml这个是idea本地项目文件,比如maven的target文件夹。所以用.gitignore帮我们自动排除
1.增加eureka子模块作为注册服务端
2.将单maven项目改造成maven父子项目
pom.xml(course)
<?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 https://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.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.course</groupId>
<artifactId>course</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>course</name>
<description>Demo project for Spring Boot</description>
<modules>
<module>eureka</module>
</modules>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
pom.xml(eureka)
<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>com.course</groupId>
<artifactId>course</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>eureka</artifactId>
<packaging>jar</packaging>
<name>eureka</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
搭建业务模块-system
1.解决注册中心服务启动失败的问题
1.解决注册中心服务启动失败的问题
支持application.properties或application.yml文件,默认会读取resources目录下或resources/config目录下,后续会有读/config目录的示例
spring.application.name=eureka
server.port=8761
eureka.client.fetch-registry=false
eureka.client.register-with-eureka=false
springboot默认集成slf4j框架,它定义了一些日志接口,规范日志输出,真正的实现是logback或log4j,我们代码中写的都是slf4j的代码
2.优化启动日志显示
启动日志可以按需扩展,甚至可以打印一些有趣的字符图
package com.course;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
/**
* Hello world!
*
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
private static final Logger logger = LoggerFactory.getLogger(EurekaApplication.class);
// public static void main(String[] args) {
// SpringApplication.run(EurekaApplication.class, args);
// }
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EurekaApplication.class);
Environment env = app.run(args).getEnvironment();
logger.info("启动成功!!");
logger.info("Eureka地址: \thttp://127.0.0.1:{}", env.getProperty("server.port"));
}
}
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 修改一下路径-->
<property name="PATH" value="/log/imooc/course/eureka"></property>
<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) %msg%n</Pattern>-->
<Pattern>%d{ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %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(%-8X{UUID}) %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(%-8X{UUID}) %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>
小建议:养成阶段性提交代码的习惯,可以是完成一个小功能。并且每天下班前提交本地代码,前提是不能编译报错或影响已有的功能
2.新建Maven子项目system
maven父子模块的配置: 在子模块中使用parent标签指向父模块,在父模块中使用module标签引入子模块
将system配置成最简单的SpringBoot项目
package com.course.system;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
@SpringBootApplication
public class SystemApplication {
private static final Logger logger = LoggerFactory.getLogger(SystemApplication.class);
public static void main(String[] args) {
SpringApplication app = new SpringApplication(SystemApplication.class);
Environment env = app.run(args).getEnvironment();
logger.info("启动成功!!");
logger.info("System地址: \thttp://127.0.0.1:{}", env.getProperty("server.port"));
}
}
spring.application.name=system
server.port=9001
<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>com.course</groupId>
<artifactId>course</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>system</artifactId>
<packaging>jar</packaging>
<dependencies>
<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-web</artifactId>
</dependency>
</dependencies>
</project>
3.将system注册到注册中心
第1步:增加eureka-client依赖
第2步:增加配置,指向注册中心的地址
第3步:增加@EnableEurekaClient
搭建路由模块-gateway
SpringCloug的网关组件可以用gateway或zuul,最早使用的是zuul,后面spring自己出了gateway
网关主要功能:
限流(流量控制);
重试(请求失败时重试,慎用);
跨域(前后端不在同一个域);
路由(转发请求);
鉴权(登录校验,签名校验)等...
新建Maven子项目gateway
步骤和system模块一样改一些参数
新增gateway子模块,增加gateway依赖,并注册到注册中心
spring.application.name=gateway
server.port=9000
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
#路由转发
spring.cloud.gateway.routes[0].id=system
spring.cloud.gateway.routes[0].uri=http://127.0.0.1:9001
spring.cloud.gateway.routes[0].predicates[0].name=Path
spring.cloud.gateway.routes[0].predicates[0].args[0]=/system/**
<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>com.course</groupId>
<artifactId>course</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>gateway</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>
路由转发
路由转发:将外部请求转发到实际的业务模块进行处理。
1.在gateway增加system路由转发配置,调试成功
我们做的所有的改动都需要重启应用才能生效,后续我们介绍热部署,不再需要手动重启,从而提高开发效率