Million words Spring Cloud Gateway2.0, future-oriented technology, to find out?

Original: little sister the taste (micro-channel public number ID: xjjdog), please share, reproduced Please keep the source.

This article from the knowledge of the topology talk, talk about the function api gateway, and spring cloud gateway to use. Article is very long, you can look through the directory.

一、知识拓扑 (使用和原理)
二、网关的作用
三、Predicate,路由匹配
四、Filter,过滤器编写
五、自定义过滤器
六、常见问题
复制代码

Why do so many people feel spring cloud gateway hard to use? Because it is behind by webfluxinvolving reactive programming, rather than the traditional procedural programming.

We sort out the technology behind it is not difficult to find the root cause of this obscure, it comes from the Reactor Project , and spring projects to keep pace, "future" reactive programming framework.

Last code, both long and lambda same. The idea behind this, is the product of a non-blocking mode and observer hybridization, the learning curve is relatively steep .

First, knowledge of the topology

spring cloud gateway involves many relatively new knowledge and ideas, but only for use, the slope is not great.

1.1 Related

We can imagine a necessary element in the route: Web requests by a number of matching conditions, to locate real service node. And before and after the forwarding process, some fine control .

Which, predicate is our match condition; and filter, it can be understood as an all-powerful interceptor. With these two elements, combined with the target uri, you can achieve a specific routing of.

Since the spring cloud gateway is based springboot, so yml used for routing. yml usually deep level, which resulted in profile looks very messy. It can also use java code (or kotlin) be written routing, functional programming style bias, it is necessary to first understand the wording of the lambda expression.

Most of the time spring cloud gateway services as a gateway http, http packets can be carried out for some fine-grained control, so it needs to have more understanding of the http protocol, in order to ease in use.

1.2 Principle related

In terms of principle, but more complex. Because of the lag, the existing practice of the majority of the components have not yet caught up "ahead of" concept "responsive" This gave birth to a bunch of obscure components (mainly dedicated much function) . Fortunately, using a spring cloud gateway does not require direct contact with these api.

The most important is the encapsulation of webflux framework. webflux is set spring mvc alternative solutions, responsive applications can write, can look the relationship between FIG. Its underlying using netty, so non-blocking operation is asynchronous.

Xiazou, webflux package is run on a project reactor, the fundamental characteristics are provided by the latter. This thing and vert.x like to use the initial contact will feel particularly strange.

reactor is to carry forward observer mode, so there are concepts of Publisher, the most important realization is that Flux and Mono. The so-called webflux, named in this.

reactor Reference: url.cn/5B7f5iY

The transition from traditional development mode to development mode of the reactor, there is a certain cost. If you have time to look at the principle behind the use of the spring cloud gateway, or good.

Second, the role of the gateway

You can see from the name, it is a network of checkpoints, no matter how complex back-end, this external level performance is the same.

More importantly, hidden behind some general points of the transaction, it can be abstracted for processing. The gateway can, thought of something similar to the customs, your visa data preparation, security, scheduling, etc., can be unified for processing.

api gateway is accompanied by a rise of the concept of micro-services architecture model, of course, not limited to micro-services. We can see the location of the gateway from the figure.

Let us look at the specific role of the following gateway.

2.1 Reverse Proxy

This is all gateways, including the basic functions of nginx. In addition to shape the services gateway is a very important additional benefits, is the back-end service details were shielded.

At the same time will reverse proxy with load balancing features, including traffic with weight distribution.

2.2 Authentication

Is the certification authority, which is often said that the privilege system. Since the authentication service has a very high similarity can abstract processing layers in the gateway.

Such as unified access https protocol, distributed session of the deal, the new login authentication channel access.

2.3 Flow Control

If flow control in distributed to each service to do, is a disaster, the gateway is the most suitable place.

Flow control usually have a variety of strategies, shielding the back-end service. Request abnormal request load capacity and beyond, will be quickly intercepted outside, providing essential support for the stability of the system.

There are stand-alone control the flow restrictor and restrictor distributed in two ways, which controls some of the more sophisticated, spring cloud gateway are provided.

2.4 fuse

The main difference between the fuse and flow control, and that the former period of time, the service "not available", while the latter only the probability of failure.

In addition to calling involves fusing between services, in fusing the gateway layer, it will be greater scope, the need for accurate grading service.

Gradation control 2.5

The ultimate function of a gateway, is gray implement the service release. For example, often said that the AB test, is a kind of gray-scale publishing.

Gradation control will be fine, for example, a class of users, a physical area, some of the specific request path control gradation, specific modules, and other aspects of random percentage.

With the overall architecture is a gradation of results, but the entrance is the gateway coordination, or through the request header parameter specific flag is added, it may be divided for each request, determines whether the gradation falls.

2.6 log monitoring

Gateway is the most suitable place for log monitoring. By fine analysis of access logs, you can get a lot of valuable data, thereby providing a basis for decision making to optimize the back-end services.

For example, a "business" access trends, operational data, QPS peak year, the chain and so on.

Three, Predicate, route matches

spring cloud gateway's configuration has a Fluent API and yml two ways, both very messed up.

Predicate is asserted meaning in English. Here we can be seen as matching conditions, it can be matched according to http or http header parameters.

3.1 Time match

At some point in time before or after the match. For example, let route takes effect within a certain period.

Configuration file looks like this:

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2020-10-20T17:42:47.789-07:00[America/Denver]
复制代码

among them. idIt is the only name can not be repeated this route, uri specified routing address after the match, while the predicates of After, that is, our time matcher.

1. After

Or translated into code that way.

builder.routes().route(
r -> r.after(LocalDateTime.of(2020, 10, 17, 42, 47).atZone(ZoneId.of("America/Denver")))
    .uri("https://example.org")
);
复制代码

Since the code is similar to the majority, the following pages, we only interception of the most important segments.

2. Before

After the above is a point in time, before writing, as follows:

Before=2017-01-20T17:42:47.789-07:00[America/Denver]

r.before(LocalDateTime.of(2020, 10, 17, 42, 47).atZone(ZoneId.of("America/Denver")))
复制代码

Between 3 as well as within a certain time period

Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

r.between(
LocalDateTime.of(2020, 10, 17, 42, 47).atZone(ZoneId.of("America/Denver")),
LocalDateTime.of(2027, 10, 17, 42, 47).atZone(ZoneId.of("America/Denver"))
)
复制代码

3.2 Http information

We simply look at the information a http request, wherein, General Information and Request Headers in, can be matched controls. For commonly used information Cookie, Host, etc., but also for a special optimization. Among these, the most common, is the path, cookie, host, query and so on.

Path

path is the most important match mode, you can use multiple path ,separated.

Path=/foo/{segment},/bar/{segment}
r.path("/foo/{segment}","/bar/{segment}")
复制代码

Note that we use braces {segment} up around this value, can be taken out by the code.

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);

String segment = uriVariables.get("segment");
复制代码

Header header information

Header=X-Request-Id, \d+
r.header("Header=X-Request-Id", "\\d+")
复制代码

Cookie-like, here refers to the match http header area, a lot of gray-scale information, or trace information, I like to put here.

Cookie [header]

Cookie=chocolate, ch.p
r.cookie("chocolate","ch.p")
复制代码

http message, if there is a name called chocolatethe Cookie, whether it is positive ch.pmatch.

Host Information [header] Although information is also host header information in, but because it is so common, so there is a special matcher.

Host=**.somehost.org,**.anotherhost.org
r.host("Host=**.somehost.org","**.anotherhost.org")
复制代码

Note that this matched string is Ant-style, less verbose, not java in regular expressions. Using a plurality of host ,separated.

Request Method

Method=GET
r.method("GET")
复制代码

Note that I did not find the code in case conversion of the source code, so remember to keep the route in uppercase. In addition to CONNECT, are supported.

Query

This refers to a string parameter is a question mark behind the url.

Query=baz
r.query("baz")

Query=foo, ba.
r.query("foo","ba.")
复制代码

Too simple, I do not need to do too much introduced.

RemoteAddr

 RemoteAddr=192.168.1.1/24
 r->r.remoteAddr("192.168.1.1/24")
复制代码

3.3 Weight

Weight configuration information, a little 2b. For example, we have two servers behind, spring cloud gateway it did two routes, which link the hub is called Weighta group.

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2
复制代码

The same code is as follows.

builder.routes()
.route("weight_high",r -> r.weight("group1", 8).uri("https://weighthigh.org"))
.route("weight_low",r -> r.weight("group1", 2).uri("https://weightlow.org"));
复制代码

If the service has 100 nodes, as well as a bunch of filter, configured to repeat 100 times? I have to say very fuck.

Fourth, write Filter, filter

Match, to be able to locate routing proxy. Now, we have entered into our internal routing. The role of the above-mentioned routes, most of the functionality that is configured here.

Used zuul gateway may know, in the custom route, there will be pre and post two annotations control routing behavior before and after the agent. spring cloud gatewa have the same effect.

4.1 modify information

crud not exist SSM, routing configuration as well. You might be true before routing to back-end services, or other information on the http header modification; or after the agent to the appropriate link, and then make some changes.

As we understand it, the so-called request corresponds to the pre, and the response corresponds to the post.

AddRequestHeader=X-Request-Foo, Bar
AddRequestParameter=foo, bar
AddResponseHeader=X-Response-Foo, Bar

RemoveRequestHeader=X-Request-Foo
RemoveResponseHeader=X-Response-Foo
RemoveRequestParameter=foo

SetRequestHeader=X-Request-Foo, Bar
SetResponseHeader=X-Response-Foo, Bar

SetStatus=401
复制代码

4.2 Request Body modification

The pain on the eggs of some reason or the webflux caused on some of the wording more personalized.

.filters(f -> f.modifyRequestBody(String.class, String.class, MediaType.APPLICATION_JSON_VALUE,
    (exchange, s) -> {
            return Mono.just(s.toUpperCase());
})
复制代码

The above code, the contents of requestBody, all turned into uppercase.

Similar, response corresponds modifyResponseBody, similar wording. Specific reference may ModifyRequestBodyGatewayFilterFactory code. If there is no contact with the theoretical part of the above mentioned, it is quite difficult to read in.

4.3 Redirection

RedirectTo=302, https://acme.org

.filters(f -> f.redirect(302,"https://acme.org"))
复制代码

Direct redirection. This is relatively simple, do not do too much introduction.

4.4 minus the prefix.

Focus.

StripPrefix=2

.filters(f->f.stripPrefix(2))
复制代码

StripPrefix can accept a non-negative integer, for removing a corresponding prefix. For example, external access path is /a/b/c/dthen turned to the back-end service path, that is /c/d, remove the /a/bprefix.

This embodiment is a special path rewritten, for uri in common to lb://rewrite micro service route protocol.

4.5 rewrite path

RewritePath path and is nginx rewrite something very similar.

RewritePath=/foo(?<segment>/?.*), $\{segment}

f.rewritePath("/foo(?<segment>/?.*)", "${segment}")
复制代码

The official description says, because of yml profile. It should $be written $\the way, but the java code does not need to do so. Due to the use of internal or java regular, and spend a concept group, the code can be really dirty.

4.6 fuse configuration

The default integrated circuit breaker is still hystrix.

Hystrix=myCommandName

.filters(f -> f.hystrix(c->c.setName("myCommandName")))
复制代码

In addition, there is a parameter called the fuse fallbackUri, but unfortunately, only supports forward way. such as:

fallbackUri: forward:/myfallback
复制代码

4.7 retry configuration

For some of the very high stability of the service, an unavoidable question is retried. More retry parameters, a typical configuration is as follows:

- name: Retry
    args:
        retries: 3
        statuses: BAD_GATEWAY
        backoff:
            firstBackoff: 10ms
            maxBackoff: 50ms
            factor: 2
            basedOnPreviousValue: false
复制代码

Which, backoff specifies the retry interval and strategy, we will follow the formula firstBackoff * (factor ^ n)be growing.

Fuse to ensure the security of the service, to ensure the robustness retry services, pay attention to the screening usage scenarios.

4.8 limiting

Built-in flow restrictor, if triggered, would return "HTTP 429 - Too Many Requests" error.

Parameters of the flow restrictor is called KeyResolver realization, where there is the concept we mentioned above Mono. So if you want to extend the current limiter, then you need to know webflux that set of things.

public interface KeyResolver {
    Mono<String> resolve(ServerWebExchange exchange);
}
复制代码

At the same time, based on the principle of the distributed token bucket redis limiting. As the underlying using a "spring-boot-starter-data-redis-reactive", so to have the characteristics of the application "responsive" to support WebFlux (Reactor) back pressure (Backpressure). For the configuration of which is around some, such as official this configuration.

- name: RequestRateLimiter
    args:
        key-resolver: '#{@ipKeyResolver}'
        redis-rate-limiter.replenishRate: 10
        redis-rate-limiter.burstCapacity: 20
复制代码

We need to set a name called ipKeyResolverthe bean.

Limiting dimension of many, the need to develop self-management background. Due to space reasons, we do not discuss.

V. custom filter

spring cloud gateway filters, filters with a global and local filter points, corresponding to the interface GatewayFilterand GlobalFilter.

If the built-in filters can not meet the demand, custom filters can be resolved through. By implementing GatewayFilterand Orderedinterfaces can be more flexible control.

Reference may be built filter implementation. A later article, we will describe the specific code to achieve this in more detail.

Sixth, Frequently Asked Questions

lb: // What does that mean?

lb: // serviceName load balancing uri spring cloud gateway automatically created for us in the micro-server and in some special cases, you can write directly. For example, in eureka registered in the name of pay-rpc, at this time the wording is:

lb://pay-rpc
复制代码

How to modify the http content? Such method?

Note ServerWebExchange this thing. Using its exchange.mutate () function, you can enter editing mode. For example, to turn into a GET POST method:

ServerHttpRequest request = exchange.getRequest();
if (request.getMethod() == HttpMethod.GET) {
    exchange = exchange.mutate().request(request.mutate().method(HttpMethod.POST).build()).build();
}
复制代码

How to dynamically update routing? Mainly through the actuator management interface, ensure that the content on the intranet.

GET /actuator/gateway/routes 路由列表
GET  /actuator/gateway/routes/{id} 获取某个路由信息
GET /actuator/gateway/globalfilters 全局过滤器
GET /actuator/gateway/routefilters filter列表
POST /actuator/gateway/refresh 刷新路由
POST /gateway/routes/{id_route_to_create} 创建路由
DELETE /gateway/routes/{id_route_to_delete}  删除某个路由
复制代码

How do some statistical data

This feature is very simple, we only need to implement a global filter, you can add any statistics. There are commonly two ways: by analyzing the log; polymerization analyzed by the application.

Neither of these is difficult, mainly because of the function of planning rather than code.

I have more advanced features, such as decryption of data requirements, what to do?

This is necessary to realize their filters up.

 Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
复制代码

By ServerWebExchange, any parameter can be controlled to add the entire request process, modify, delete, overwrite the like. Before and after the proxy method, you can

exchange.getAttributes().put();
exchange.getAttribute()
复制代码

These two functions, parameter passing

Therefore, even if the official does not write any filter mentioned above, we can still use this basic interface's turn to play.

End

Micro-channel public number really is not suitable to write some tutorials like the article, so this is still a summary of the voice of experience.

With the exit of dystocia and zuul2 zuul1 of birth of SCG has become the best choice. Spring team is very interesting, as the direct use of webflux backend technology (change afraid?), It makes a lot of people bitterly pain: have to learn new technology.

This article does not test the performance of SCG, this team has a lot to validate the results are good.

But now the spring cloud gateway, still many problems. Fortunately, this problem is to use a problem, not a functional problem. It has built a lot of Predicate and Filter, but often does not solve the problem, the user needs to create their own filter. Well, most of my filter are all self-created.

In addition Tucao about configuration Fluent API and yml, really ugly one b, need to develop a management background. There are those things complicated java canonical, are people crazy - Look at those deep claw marks on the wall, it is my masterpiece.

About the Author: little sister the taste (xjjdog), does not allow the public a number of detours programmer. Focus infrastructure and Linux. Decade architecture, day ten billion flow, and you explore the world of high concurrency, give you a different taste. My personal micro-channel xjjdog0, welcome to add friends, further exchanges.

Guess you like

Origin juejin.im/post/5da98cbcf265da5b560e06e4