前言
初门级别搭建SpringCloud 微服务项目
整理网关、认证、redis、其它服务。
一.父工程搭建
项目创建省略
1.1 版本
Springboot 2.2.5 版本
Springcloud版本 Hoxton.SR8
1.2 父工程名
xxx-springcloud-parent
1.3 父工程引入 pom 依赖包
<!-- 可以集中定义依赖资源的版本信息 -->
<properties>
<spring-boot-version>2.2.5.RELEASE</spring-boot-version>
<spring-cloud-version>Hoxton.SR8</spring-cloud-version>
<lombok-version>1.18.16</lombok-version>
<commons-lang-version>3.11</commons-lang-version>
<mybatis-starter-version>2.1.3</mybatis-starter-version>
<mysql-version>8.0.22</mysql-version>
<swagger-starter-version>2.1.5-RELEASE</swagger-starter-version>
<hutool-version>5.4.7</hutool-version>
<guava-version>20.0</guava-version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 集中定义依赖,不引入 -->
<dependencyManagement>
<dependencies>
<!-- spring boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok-version}</version>
</dependency>
<!-- common-lang3 依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang-version}</version>
</dependency>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-starter-version}</version>
</dependency>
<!-- swagger 依赖 -->
<dependency>
<groupId>com.battcn</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>${swagger-starter-version}</version>
</dependency>
<!-- mysql 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-version}</version>
</dependency>
<!-- hutool 依赖 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool-version}</version>
</dependency>
<!-- guava 依赖 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 集中定义项目所需插件 -->
<build>
<pluginManagement>
<plugins>
<!-- spring boot maven 项目打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
1.4 父工程搭建完毕
image.png
二、公共服务搭建
右键父工程依次创建
image.png
公共服务主要存放公共资源,例如工具类,实体类等。
2.1 服务命名:xxx-commons
image.png
2.2 公共服务引入依赖
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- swagger -->
<dependency>
<groupId>com.battcn</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</dependency>
<!-- security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
</dependencies>
三、注册中心服务
3.1 服务名:xxx-register
3.2 引入依赖包
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.3 application.yml
server:
port: 8761
spring:
application:
name: xxx-register
# Eureka Server
eureka:
# instance:
# hostname: localhost #当前实例的主机名称
# prefer-ip-address: true
client:
register-with-eureka: false #false代表不向注册中心注册自己(因为本身就是注册中心),默认是true,如果不设为false,启动会报找不到注册中心的错误
fetch-registry: false #注册中心用于维护服务实例,无需检索服务,故设为false
service-url:
defaultZone: http://localhost:8761/eureka/ # 服务注册地址
3.4 启动类:Application
@EnableEurekaServer //启动一个服务注册中心提供给其它应用进行注册
@SpringBootApplication
public class XXRegistryApplication {
public static void main(String[] args) {
SpringApplication.run(XXRegistryApplication.class, args);
}
}
四、客户服务
主要用于一个客户服务模块
服务名称:customer-server
4.1 依赖包
<dependencies>
<!-- eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- spring data redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- commons 公共项目 -->
<dependency>
<groupId>com.mi</groupId>
<artifactId>commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 自定义的元数据依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
4.2. application.yml
server:
port: 8081 # 端口
spring:
application:
name: customer-server # 应用名
# 数据库
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://127.0.0.1:3306/xxx?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
# Redis
redis:
port: 6379
host: localhost
timeout: 3000s
password: 123456
# swagger
swagger:
base-package: com.mi.xxx
title: API接口文档
## Oauth2 客户端信息
oauth2:
client:
client-id: appId
secret: 123456
grant_type: password
scope: api
#
## oauth2 服务地址 配合服务注册中心
service:
name:
xxx-oauth-server: http://xxx-oauth2-server/
# 配置 Eureka Server 注册中心
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# Mybatis
mybatis:
configuration:
map-underscore-to-camel-case: true # 开启驼峰映射
logging:
pattern:
console: '%d{HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n'
4.2 启动类Application
@MapperScan("com.mi.xxx.mapper") // mapper扫描包下
@EnableDiscoveryClient #服务注册到注册中心上去
@SpringBootApplication
public class XXXApplication {
public static void main(String[] args) {
SpringApplication.run(xxxApplication.class, args);
}
}
五、认证中心服务
5.1 服务名:customer-oauth2-server
5.2 引入依赖包
<dependencies>
<!-- eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- spring web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring data redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- spring cloud security -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<!-- spring cloud oauth2 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- commons 公共项目 -->
<dependency>
<groupId>com.mi</groupId>
<artifactId>commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 自定义的元数据依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
5.3 application.yml
server:
port: 8082 # 端口
spring:
application:
name: customer-oauth2-server # 应用名
# 数据库
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://127.0.0.1:3306/xx?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
# Redis
redis:
port: 6379
host: localhost
timeout: 3000s
database: 1
password: 123456
# swagger
swagger:
base-package: com.mi.oauth
title: API接口文档
#
# Oauth2
client:
oauth2:
client-id: appId # 客户端标识 ID
secret: 123456 # 客户端安全码
# 授权类型
grant_types:
- password
- refresh_token
# token 有效时间,单位秒
token-validity-time: 259200 #3600
refresh-token-validity-time: 259200 #3600
# 客户端访问范围
scopes:
- api
- all
# 配置 Eureka Server 注册中心
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# Mybatis
mybatis:
configuration:
map-underscore-to-camel-case: true # 开启驼峰映射
# 指标监控健康检查
management:
endpoints:
web:
exposure:
include: "*" # 暴露的端点
logging:
pattern:
console: '%d{HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n'
5.4 启动类
@MapperScan("com.mi.oauth.mapper")
@EnableDiscoveryClient
@SpringBootApplication
public class CustomerOauth2ServerApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerOauth2ServerApplication .class, args);
}
}
六、网关服务
6.1 服务名:customer-gateway
6.2 引入依赖包
<dependencies>
<!-- spring cloud gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- commons 公共项目 -->
<dependency>
<groupId>com.mi</groupId>
<artifactId>commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 和 webflux 冲突 -->
<exclusions>
<exclusion>
<groupId>com.battcn</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 自定义的元数据依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
6.3 application.yml
server:
port: 80
spring:
application:
name: customer-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启配置 通过名称去找
lower-case-service-id: true #将服务器转为小写
routes: #路由规则
- id: customer-server
uri: lb://customer-server #负责均衡 lb:服务名实例
predicates: #断言规则 通过路径访问这个实例
- Path=/customer/**
filters:
- StripPrefix=1 # StripPrefix参数表示在将请求发送到下游之前从请求中剥离的路径个数:例如: = 1 的话就是/customer/ = 2 /customer/xxx/**
- id: customer-oauth2-server
uri: lb://customer-oauth2-server
predicates:
- Path=/auth/**
filters:
- StripPrefix=1
secure:
ignore:
urls: # 配置白名单路径
- /actuator/**
- /auth/oauth/**
- /customer/**
# 配置 Eureka Server 注册中心
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://localhost:8761/eureka/
logging:
pattern:
console: '%d{HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n'
6.4. 启动类
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
6.5 配置白名单实体类
@Data
@Component
@ConfigurationProperties(prefix = "secure.ignore")
public class IgnoreUrlsConfig {
private List<String> urls;
}
6.6 过滤 filter
@Component
public class AuthGlobalFilter implements GlobalFilter,Ordered {
@Resource
private IgnoreUrlsConfig ignoreUrlsConfig;
/**
* 身份校验处理
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 【判断当前的请求是否在白名单中
AntPathMatcher pathMatcher = new AntPathMatcher();
boolean flag = false;
String path = exchange.getRequest().getURI().getPath();
for (String url : ignoreUrlsConfig.getUrls()){
if (pathMatcher.match(url,path)){
flag = true;
break;
}
}
// 白名单放行
if (flag){
return chain.filter(exchange);
}
// 获取access_token
String access_token = exchange.getRequest().getQueryParams().getFirst("access_token");
// 判断access_token 是否为空
if (StringUtils.isBlank(access_token)){
return handleException.writeError(exchange,"请登录");
}
// 校验 token 是否有效
String checkTokenUrl = "http://customer-oauth2-server/oauth/check_token?token=".concat(access_token);
try {
// 发起远程请求来验证token
ResponseEntity<String> entity = restTemplate.getForEntity(checkTokenUrl, String.class);
// token 无效的业务逻辑处理
if (entity.getStatusCode() != HttpStatus.OK){
return handleException.writeError(exchange,
"Token was not recognised ,token :".concat(access_token));
}
if (StringUtils.isBlank(entity.getBody())){
return handleException.writeError(exchange,
"This token is invalid:".concat(access_token));
}
}catch (Exception e){
}
// 放行
return chain.filter(exchange);
}
/**
* 网关过滤器的排序,数字越小优先级约高
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
7.访问路径
由于配置了网关服务,端口为80
直接访问 http://localhost/地址
8.结束语
主要是通过学习网上视频和百度查找资料整理而来
9.有什么不懂可留言下方,小白相互学习讨论,欧了~