本文最后更新于:October 30, 2022 pm
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
目录
导入依赖
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
|
添加配置文件
同样的,也是需要注册到nacos中的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server: port: 8500 spring: datasource: druid: username: root password: root url: jdbc:mysql://ip:3306/home?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8 driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource application: name: gateway-service cloud: nacos: discovery: server-addr: ip:port
|
📢注意:需要排除以下依赖。而且如果引入了MyBatis或者MyBatis-plus,则还需要配置数据库相关的东西!!!
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
如果想实现不导入父模块中的依赖,但是需要父模块中的依赖管理,则可以这样导入父模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<dependencyManagement> <dependencies> <dependency> <groupId>com.tothefor</groupId> <artifactId>InkM</artifactId> <version>0.0.1-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
|
个人总结:
- parent:会让子模块也会有相同的依赖。
- dependencyManagement:只会让子模块具有父模块相同的依赖环境,而不会真正导入依赖。
完整环境配置
pom文件内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| <?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> <groupId>com.tothefor</groupId> <artifactId>gateway</artifactId> <version>0.0.1-SNAPSHOT</version> <name>gateway</name> <description>Demo project for Spring Boot</description>
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>com.tothefor</groupId> <artifactId>InkM</artifactId> <version>0.0.1-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.6.6</version> <configuration> <mainClass>com.tothefor.gateway.GatewayApplication</mainClass> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
</project>
|
配置文件application.yml:(采用这种方式后,就不会从父模块中继承MyBatis之类的依赖了,所以就可以去掉了)
| server: port: 8500 spring: application: name: gateway-service cloud: nacos: discovery: server-addr: ip:80
|
配置路由
在gateway模块中进行配置:
| server: port: 8500 spring: application: name: gateway-service cloud: nacos: discovery: server-addr: nacosIp:80 gateway: routes: - id: adminservice uri: lb://admin-service predicates: - Path=/adminT/admin/**
|
当访问 http://localhost:8500/adminT/admin/c 时,会转发到 http://admin-service/adminT/admin/c 。
然后访问网关:http://localhost:8500/adminT/admin/c,会发现报错了,如下:
| Whitelabel Error Page This application has no configured error view, so you are seeing this as a fallback.
Thu Oct 06 12:48:17 CST 2022 [9eceed8e-1] There was an unexpected error (type=Service Unavailable, status=503).
|
原因:由于springcloud2020弃用了Ribbon,因此Alibaba在2021版本nacos中删除了Ribbon的jar包,因此无法通过lb路由到指定微服务,出现了503情况。添加依赖即可,如下:
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
|
然后再次访问,即可成功。
多个路由配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| server: port: 8500 spring: application: name: gateway-service cloud: nacos: discovery: server-addr: ip:80 gateway: routes: - id: adminservice uri: lb://admin-service predicates: - Path=/adminT/admin/** - id: userservice uri: lb://user-service predicates: - Path=/userT/user/**
|
路由过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| server: port: 8500 spring: application: name: gateway-service cloud: nacos: discovery: server-addr: ip:80 gateway: routes: - id: adminservice uri: lb://admin-service predicates: - Path=/adminT/admin/** filters: - AddRequestHeader=TTF,123qweasdzxc - id: userservice uri: lb://user-service predicates: - Path=/userT/user/**
|
在此加载的请求头信息可以直接在Controller的接口中进行获取:
| @RequestMapping("/gtw") public static void get(HttpServletRequest request){ String ttf = request.getHeader("TTF"); }
|
也可以自定义全局过滤器,使其能够作用于全局。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package com.tothefor.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;
import java.util.List;
@Component public class GatewayTokenFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); List<String> ttf1 = request.getHeaders().get("TTF"); MultiValueMap<String, String> queryParams = request.getQueryParams(); List<String> ttf = queryParams.get("TTF"); return null; } }
|
📢注意:在配置文件中配置的过滤器也具有优先级,从上到下默认从1开始设置。值越小优先级越高。如果自定义全局过滤器和配置文件中单独的过滤器优先级相同时,自定义的全局过滤器优先执行。
给自定义全局过滤器添加优先级:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package com.tothefor.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;
import java.util.List;
@Component public class GatewayTokenFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); List<String> ttf1 = request.getHeaders().get("TTF"); MultiValueMap<String, String> queryParams = request.getQueryParams(); List<String> ttf = queryParams.get("TTF"); if(1>0){ return chain.filter(exchange); }else{ return exchange.getResponse().setComplete(); } }
@Override public int getOrder() { return 0; } }
|
现在自定义全局过滤器的值为0,则会优先于配置文件中的过滤器执行。