发布时间:2022-08-19 12:13
1. 引入依赖
主项目
1.8
UTF-8
UTF-8
2.3.2.RELEASE
Hoxton.SR9
2.2.6.RELEASE
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
1.18.16
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba.version}
pom
import
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
子项目1
junit
junit
4.12
test
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
5.1.38
com.baomidou
mybatis-plus-boot-starter
3.4.2
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
io.springfox
springfox-swagger2
2.9.2
io.springfox
springfox-swagger-ui
2.9.2
子项目2网关
junit
junit
4.12
org.springframework.cloud
spring-cloud-starter-gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
2.编写yml配置文件
子项目1
server:
port: 9001
spring:
application:
name: stockmodule
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.64.135:3306/mydemo?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true
username: root
password: 3090_Cmok
cloud:
nacos:
discovery:
server-addr: 192.168.64.135:8848
username: nacos
password: nacos
namespace: public
子项目2 网关
server:
port: 9002
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: stockservices
uri: lb://stockmodule
predicates:
- Path=/xxx/**
# - After=2022-07-01T16:59:59.259+08:00[Asia/Shanghai]
# - Header=token,\d+
- Method=GET
- Query=tt,12
filters:
- StripPrefix=1
- AddRequestHeader=token,123456
nacos:
discovery:
server-addr: 192.168.64.135:8848
username: nacos
password: nacos
namespace: public
集成Nacos
现在在配置文件中写死了转发路径的地址, 前面我们已经分析过地址写死带来的问题, 接下来我们从注册中心获取此地址。
1. 引入依赖
编写yml配置文件
简写: 去掉关于路由的配置,自动寻找服务
编写子项目1 (domian mapper service controller)
#domain
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ApiModel("商品库存类")
public class Stocks {
@ApiModelProperty("库存编号")
private Integer id;
@ApiModelProperty("商品编号")
private Integer shopid;
@ApiModelProperty("当前编号")
private Integer storenum;
}
#mapper接口
@Mapper
public interface StockMapper extends BaseMapper {
}
#service接口
public interface StockServic {
public List findStock();
}
#service实现类
@Service
public class StockServicImpl extends ServiceImpl implements StockServic {
@Override
public List findStock() {
return this.list();
}
}
#controller层
@RestController
@RequestMapping("/stock-serv")
@Api(value = "库存服务API")
//public class StockCtrl {
// @Resource
// private StockServic stockServic;
@RequestHeader("token")String token
//
// @ApiOperation(value = "查询所有的商品当前库存",httpMethod = "GET")
// @ApiImplicitParams({
// @ApiImplicitParam(name = "id",value = "用户id",required = true,dataType = "int",paramType ="query")
// })
// @RequestMapping(value = "/findall")
// public List findAll(@RequestParam("id") int id){
System.out.println("获取头部信息token:============》"+token);
// return stockServic.findStock();
// }
//}
public class StockCtrl {
@Resource
private StockServic stockServic;
// @RequestHeader("token")String token
@RequestMapping(value = "/findall")
public List findAll(){
// System.out.println("获取头部信息token:============》"+token);
return stockServic.findStock();
}
}
swagger配置
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
//配置接口页面上的信息
public ApiInfo apiInfo(){
return new ApiInfoBuilder().title("网关项目接口测试")
.description("测试接口说明")
.version("v1.0")
.termsOfServiceUrl("http://www.baidu.com")
.contact("程序员")
.build();
}
}
3)测试
这时候,就发现只要按照网关地址/
http://localhost:9001/stock-serv/findall
#配置网关浏览地址
http://localhost:9002/xxx/stock-serv/findall
Spring Cloud Gateway
作用: 当请求gateway的时候, 使用断言对请求进行匹配, 如果匹配成功就路由转发, 如果匹配失败就返回404 类型:内置,自定义
SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配。具体如下:
此类型的断言根据时间做判断,主要有三个:
AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内ZonedDateTime.now()
RemoteAddrRoutePredicateFactory:接收一个IP地址段,判断请求主机地址是否在地址段中
CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
1 |
‐Cookie |
=chocolate, ch. |
HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配。
HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。
MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。
1 |
‐Method |
=GET |
PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。
WeightRoutePredicateFactory:接收一个[组名,权重], 然后对于同一个组内的路由按照权重转发
2.2.5 自定义路由断言工厂
自定义路由断言工厂需要继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。在 apply 方法中可以通过exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。
1、 必须spring组件 bean
注意: 命名需要以 RoutePredicateFactory 结尾
1@Component
2@Slf4j
3public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory {
4
5public CheckAuthRoutePredicateFactory() {
6super(Config.class);
7 }
8
9@Override
10public Predicate apply(Config config) {
11return new GatewayPredicate() {
12
13@Override
14public boolean test(ServerWebExchange serverWebExchange) {
15log.info("调用CheckAuthRoutePredicateFactory" + config.getName());
16if(config.getName().equals("xushu")){
17return true;
18 }
19 return false;
20 }
21 };
22 }
23
24 /**
25* 快捷配置
26* @return
27 */
28@Override
29public List shortcutFieldOrder() {
30return Collections.singletonList("name");
31 }
32
33 public static class Config {
34
35 private String name;
36
37public String getName() {
38return name;
39 }
40
41public void setName(String name) {
42this.name = name;
43 }
44 }
45 }
yml中配置
|
||
12 |
‐ CheckAuth |
=xushu |
Gateway 内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等
Spring Cloud Gateway
过滤器工厂 |
作用 |
参数 |
AddRequestHeader |
为原始请求添加Header |
Header的名称及值 |
AddRequestParameter |
为原始请求添加请求参数 |
参数名称及值 |
AddResponseHeader |
为原始响应添加Header |
Header的名称及值 |
DedupeResponseHeader |
剔除响应头中重复的值 |
需要去重的Header名称及去重策略 |
Hystrix |
为路由引入Hystrix的断路器保护 |
HystrixCommand 的名称 |
FallbackHeaders |
为fallbackUri的请求头中添加具体的异常信息 |
Header的名称 |
PrefixPath |
为原始请求路径添加前缀 |
前缀路径 |
PreserveHostHeader |
为请求添加一个preserveHostHeader=true 的 属 性,路由过滤器会检查该属性以决定是否要发送原始的Host |
无 |
RequestRateLimiter |
用于对请求限流,限流算法为令牌桶 |
keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus |
RedirectTo |
将原始请求重定向到指定的URL |
http状态码及重定向的url |
RemoveHopByHopHeadersFilter |
为原始请求删除IETF组织规定的一系列Header |
默认就会启用,可以通过配置指定仅删除哪些Header |
RemoveRequestHeader |
为原始请求删除某个Header |
Header名称 |
RemoveResponseHeader |
为原始响应删除某个Header |
Header名称 |
RewritePath |
重写原始的请求路径 |
原始路径正则表达式以及重写后路径的正则表达式 |
RewriteResponseHeader |
重写原始响应中的某个Header |
Header名称,值的正 则表达式,重写后的值 |
SaveSession |
在转发请求之前,强制执行WebSession::save 操作 |
无 |
secureHeaders |
为原始响应添加一系列起安全作用的响应头 |
无,支持修改这些安全响应头的值 |
SetPath |
修改原始的请求路径 |
修改后的路径 |
SetResponseHeader |
修改原始响应中某个Header的值 |
Header名称,修改后的值 |
SetStatus |
修改原始响应的状态码 |
HTTP 状态码,可以是数字,也可以是字符串 |
StripPrefix |
用于截断原始请求的路径 |
使用数字表示要截断的路径的数量 |
Retry |
针对不同的响应进行重试 |
retries、statuses、methods、series |
设置允许接收最大请求包的大 小。如果请求包大小超过设置的值,则返回 413 Payload Too |
请求包大小,单位为字节,默认值为5M |
RequestSize |
Large |
|
在转发请求之前修改原始请求体内容 |
修改后的请求体内容 |
|
ModifyRequestBody |
||
ModifyResponseBody |
修改原始响应体的内容 |
修改后的响应体内容 |
测试http://localhost:8888/order/testgateway
测试http://localhost:8888/order/testgateway3
mall-order中需要配置
|
|||
3 context |
‐path: |
/mall |
‐order |
测试:http://localhost:8888/order/findOrderByUserId/1 ====》 http://localhost:8020/mallorder/order/findOrderByUserId/1
测试:http://localhost:8888/order/findOrderByUserId/1
继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。
配置自定义的过滤器工厂
测试
全局过滤器(Global Filters)配置
局部过滤器和全局过滤器区别:
局部:局部针对某个路由, 需要在路由中进行配置全局:针对所有路由请求, 一旦定义就会投入使用
GlobalFilter 接口和 GatewayFilter 有一样的接口定义,只不过, GlobalFilter 会作用于所有路由。
LoadBalancerClientFilter 会查看exchange的属性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值(一个URI),如果该值的scheme是 lb,比如:lb://myservice ,它将会使用Spring Cloud的LoadBalancerClient 来将 myservice 解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的内容。
其实就是用来整合负载均衡器Ribbon的
|
|
8 |
‐ Path=/order/** |
Reactor Netty 访问日志
要启用 Reactor Netty 访问日志,请设置Dreactor.netty.http.server.accessLogEnabled=true.
它必须是 Java 系统属性,而不是 Spring Boot 属性。
您可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建一个 Logback 配置:
例 67.logback.xml
通过yml配置的方式
Spring Cloud Gateway
通过java配置的方式
网关作为内部系统外的一层屏障, 对内起到一定的保护作用, 限流便是其中之一. 网关层的限流可以简单地针对不同路由进行限流, 也可针对业务的接口进行限流,或者根据接口的特征分组限流。网关限流 · alibaba/Sentinel Wiki · GitHub
1. 添加依赖
2.添加配置
Sentinel 1.6.3 引入了网关流控控制台的支持,用户可以直接在 Sentinel 控制台上查看 API Gateway 实时的 route 和自定义 API 分组监控,管理网关规则和 API 分组配置。
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流: route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
自定义异常方式: 1.通过yml
1 spring:cloud.sentinel.scg.fallback.mode |
= response |
||
2 spring.cloud.sentinel.scg.fallback.response |
‐body |
= '{"code":403,"mes":"限流了"}' |
2.通过GatewayCallbackManager
2.6.1 代码实现方式:(了解)
用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则GatewayConfiguration中添加
为了保证 Gateway 的高可用性,可以同时启动多个 Gateway 实例进行负载,在 Gateway 的上游使用 Nginx 或者 F5 进行负载转发以达到高可用。