网站首页 > 技术教程 正文
什么是网关?
随着微服务架构的普及,单体应用被拆分成多个服务,需要一个统一的访问入口。
搭建网关
两种方法:
- github上拉一个
- springcloud为用户准备好了网关的依赖,我们只需要在自己的springboot工程中引入网关依赖,就拥有了网关。
网关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>启动类 Application.java
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}配置文件 application.yml
server:
port: 10000
spring:
application:
name: my-gateway
cloud:
gateway:
httpclient:
pool:
max-idle-time: 2000
discovery:
locator:
enabled: true
lowerCaseServiceId: true
filters:
- StripPrefix=1
eureka:
client:
registry-fetch-interval-seconds: 10
fetch-registry: true
registry-with-eureka: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
lease-expiration-duration-in-seconds: 10
lease-renewal-interval-in-seconds: 3
prefer-ip-address: true
metadata-map:
version: release这样一个spring cloud gateway就创建好了。
网关设计
下图为网关内部架构设计,可以看到网关由一个netty-server,一个netty-client,多个route组成。
网关的核心:
● Route(路由):网关配置的基本组成模块,和Zuul网关的路由配置模块类似。一个Route模块由一个ID、一个目标URI、一组断言和一组过滤器组成。如果断言为真,则路由匹配,目标URI会被访问。
● Predicate(断言):Predicate来自Java 8的接口,它可以用来匹配来自HTTP请求的任何内容,例如headers或参数。接口包含多种默认方法,并将Predicate组合成复杂的逻辑(与、或、非),可以用于接口参数校验、路由转发判断等。
● Filter(过滤器):和Zuul的过滤器在概念上类似,可以使用Filter拦截和修改请求,实现对上游的响应,进行二次处理,实现横切与应用无关的功能,如安全、访问超时设置、限流等功能。
网关配置route的方式有两种,一个是配置文件,另一个是通过代码实现。
下面用一个静态路由做例子,
配置文件:
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:9011/
predicates:
- Path= /eureka-client2/**
filters:
- StripPrefix=1代码:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("my_route", r -> r.path("/eureka-client2/**")
.filters(f -> f.stripPrefix(1))
.uri("http://localhost:9011/"))
.build();
}分别实现并展示,结果相同。
工作原理
自定义filter
网关自身提供了多个filter,可以通过配置文件进行装配,上面用到的- StripPrefix=1就是filter。
StripPrefixGatewayFilterFactory.java
public class StripPrefixGatewayFilterFactory
extends AbstractGatewayFilterFactory<StripPrefixGatewayFilterFactory.Config> {
...
@Override
public GatewayFilter apply(Config config) { // apply方法写filter逻辑
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
addOriginalRequestUrl(exchange, request.getURI());
String path = request.getURI().getRawPath();
String newPath = "/"
+ Arrays.stream(StringUtils.tokenizeToStringArray(path, "/"))
.skip(config.parts).collect(Collectors.joining("/"));
newPath += (newPath.length() > 1 && path.endsWith("/") ? "/" : "");
ServerHttpRequest newRequest = request.mutate().path(newPath).build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR,
newRequest.getURI());
return chain.filter(exchange.mutate().request(newRequest).build());
}
@Override
public String toString() {
return filterToStringCreator(StripPrefixGatewayFilterFactory.this)
.append("parts", config.getParts()).toString();
}
};
}
...
}通过工厂模式实现的过滤器是需要在配置文件中手动装配的,这种过滤器可以根据自己的需要在不同的routes上自由装配。
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:9011/
predicates:
- Path= /eureka-client2/**
filters:
- StripPrefix=1还有一种实现过滤器的方式是实现GlobalFilter接口,这个方式不需要添加配置,所有routes都生效。
拿网关自带的filter举例子,RouteToRequestUrlFilter.java
public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
...
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
if (route == null) {
return chain.filter(exchange);
}
log.trace("RouteToRequestUrlFilter start");
URI uri = exchange.getRequest().getURI();
boolean encoded = containsEncodedParts(uri);
URI routeUri = route.getUri();
if (hasAnotherScheme(routeUri)) {
// this is a special url, save scheme to special attribute
// replace routeUri with schemeSpecificPart
exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR,
routeUri.getScheme());
routeUri = URI.create(routeUri.getSchemeSpecificPart());
}
if ("lb".equalsIgnoreCase(routeUri.getScheme()) && routeUri.getHost() == null) {
// Load balanced URIs should always have a host. If the host is null it is
// most
// likely because the host name was invalid (for example included an
// underscore)
throw new IllegalStateException("Invalid host: " + routeUri.toString());
}
URI mergedUrl = UriComponentsBuilder.fromUri(uri)
// .uri(routeUri)
.scheme(routeUri.getScheme()).host(routeUri.getHost())
.port(routeUri.getPort()).build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);
return chain.filter(exchange);
}
...
}我们可以通过断点,查看一条route有哪些filter,GatewayFilterChain对象里包含了filter信息。
- 上一篇: 如何动态刷新配置?
- 下一篇: SpringCloud:Feign的原理是什么?
猜你喜欢
- 2025-01-20 SpringCloud:Feign的原理是什么?
- 2025-01-20 如何动态刷新配置?
- 2025-01-20 SpringCloud之Nacos
欢迎 你 发表评论:
- 10-23Excel计算工龄和年份之差_excel算工龄的公式year
- 10-23Excel YEARFRAC函数:时间的"年份比例尺"详解
- 10-23最常用的10个Excel函数,中文解读,动图演示,易学易用
- 10-23EXCEL中如何计算截止到今日(两个时间中)的时间
- 10-2390%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
- 10-23计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
- 10-23Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
- 10-23怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
- 最近发表
-
- Excel计算工龄和年份之差_excel算工龄的公式year
- Excel YEARFRAC函数:时间的"年份比例尺"详解
- 最常用的10个Excel函数,中文解读,动图演示,易学易用
- EXCEL中如何计算截止到今日(两个时间中)的时间
- 90%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
- 计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
- Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
- 怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
- Excel日期函数之DATEDIF函数_excel函数datedif在哪里
- Excel函数-DATEDIF求司龄_exceldatedif函数计算年龄
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)

本文暂时没有评论,来添加一个吧(●'◡'●)