LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

Hexo

Linux 上的实用小技巧

linux 2022/10/12

Linux 上的实用小技巧


vim

  当使用在使用vim的时候是不是遇到了这种状况呢?

  • 在使用鼠标想选择文本复制的时候会自动的进入visual模式
    ```text
    #解决办法

sudo vim /usr/share/vim/vim81/defaults.vim

#注释一下代码 使用”注释
if has(‘mouse’)
set mouse=a
endif

---
阅读全文

Gateway

Spring Cloud Gateway简介

工作方式

  • Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
  1. The After Route Predicate Factory

The After route predicate factory takes one parameter, a datetime (which is a java ZonedDateTime). This predicate matches requests that happen after the specified datetime. The following example configures an after route predicate:

  spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver).

  1. The Before Route Predicate Factory

The Before route predicate factory takes one parameter, a datetime (which is a java ZonedDateTime). This predicate matches requests that happen before the specified datetime. The following example configures a before route predicate:

  spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

This route matches any request made before Jan 20, 2017 17:42 Mountain Time (Denver).

  1. The Between Route Predicate Factory

The Between route predicate factory takes two parameters, datetime1 and datetime2 which are java ZonedDateTime objects. This predicate matches requests that happen after datetime1 and before datetime2. The datetime2 parameter must be after datetime1. The following example configures a between route predicate:

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). This could be useful for maintenance windows.

  1. The Cookie Route Predicate Factory

The Cookie route predicate factory takes two parameters, the cookie name and a regexp (which is a Java regular expression). This predicate matches cookies that have the given name and whose values match the regular expression. The following example configures a cookie route predicate factory:

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

This route matches requests that have a cookie named chocolate whose value matches the ch.p regular expression.

  1. The Header Route Predicate Factory

The Header route predicate factory takes two parameters, the header name and a regexp (which is a Java regular expression). This predicate matches with a header that has the given name whose value matches the regular expression. The following example configures a header route predicate:

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

This route matches if the request has a header named X-Request-Id whose value matches the \d+ regular expression (that is, it has a value of one or more digits).

  1. The Host Route Predicate Factory
    The Host route predicate factory takes one parameter: a list of host name patterns. The pattern is an Ant-style pattern with . as the separator. This predicates matches the Host header that matches the pattern. The following example configures a host route predicate:
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

URI template variables (such as {sub}.myhost.org) are supported as well.

This route matches if the request has a Host header with a value of www.somehost.org or beta.somehost.org or www.anotherhost.org.

This predicate extracts the URI template variables (such as sub, defined in the preceding example) as a map of names and values and places it in the ServerWebExchange.getAttributes() with a key defined in ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE. Those values are then available for use by GatewayFilter factories

7.The Method Route Predicate Factory

The Method Route Predicate Factory takes a methods argument which is one or more parameters: the HTTP methods to match. The following example configures a method route predicate:

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

This route matches if the request method was a GET or a POST.

  1. The Path Route Predicate Factory
    The Path Route Predicate Factory takes two parameters: a list of Spring PathMatcher patterns and an optional flag called matchTrailingSlash (defaults to true). The following example configures a path route predicate:
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

This route matches if the request path was, for example: /red/1 or /red/1/ or /red/blue or /blue/green.

If matchTrailingSlash is set to false, then request path /red/1/ will not be matched.

This predicate extracts the URI template variables (such as segment, defined in the preceding example) as a map of names and values and places it in the ServerWebExchange.getAttributes() with a key defined in ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE. Those values are then available for use by GatewayFilter factories

A utility method (called get) is available to make access to these variables easier. The following example shows how to use the get method:

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

String segment = uriVariables.get("segment");
  1. The Query Route Predicate Factory

The Query route predicate factory takes two parameters: a required param and an optional regexp (which is a Java regular expression). The following example configures a query route predicate:

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green

The preceding route matches if the request contained a green query parameter.

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.

The preceding route matches if the request contained a red query parameter whose value matched the gree. regexp, so green and greet would match.

  1. The RemoteAddr Route Predicate Factory

The RemoteAddr route predicate factory takes a list (min size 1) of sources, which are CIDR-notation (IPv4 or IPv6) strings, such as 192.168.0.1/16 (where 192.168.0.1 is an IP address and 16 is a subnet mask). The following example configures a RemoteAddr route predicate:

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

This route matches if the remote address of the request was, for example, 192.168.1.10.

  1. The Weight Route Predicate Factory

The Weight route predicate factory takes two arguments: group and weight (an int). The weights are calculated per group. The following example configures a weight route predicate:

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

This route would forward ~80% of traffic to weighthigh.org and ~20% of traffic to weighlow.org

11.1 Modifying the Way Remote Addresses Are Resolved
y default, the RemoteAddr route predicate factory uses the remote address from the incoming request. This may not match the actual client IP address if Spring Cloud Gateway sits behind a proxy layer.

You can customize the way that the remote address is resolved by setting a custom RemoteAddressResolver. Spring Cloud Gateway comes with one non-default remote address resolver that is based off of the X-Forwarded-For header, XForwardedRemoteAddressResolver.

XForwardedRemoteAddressResolver has two static constructor methods, which take different approaches to security:

  • XForwardedRemoteAddressResolver::trustAll returns a RemoteAddressResolver that always takes the first IP address found in the X-Forwarded-For header. This approach is vulnerable to spoofing, as a malicious client could set an initial value for the X-Forwarded-For, which would be accepted by the resolver.

  • XForwardedRemoteAddressResolver::maxTrustedIndex takes an index that correlates to the number of trusted infrastructure running in front of Spring Cloud Gateway. If Spring Cloud Gateway is, for example only accessible through HAProxy, then a value of 1 should be used. If two hops of trusted infrastructure are required before Spring Cloud Gateway is accessible, then a value of 2 should be used.

Consider the following header value:

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

The following maxTrustedIndex values yield the following remote addresses:

maxTrustedIndex result
[Integer.MIN_VALUE,0] (invalid, IllegalArgumentException during initialization)
1 0.0.0.3
2 0.0.0.2
3 0.0.0.1
[4, Integer.MAX_VALUE] 0.0.0.1

The following example shows how to achieve the same configuration with Java:

RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("https://downstream1")
.route("proxied-route",
    r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
        .uri("https://downstream2")
)
  • Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
  • Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。

工作流程

img.png

上手

Spring Cloud Gateway 是使用 netty+webflux 实现因此不需要再引入 web 模块。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://www.ityouknow.com
        predicates:
        - Path=/spring-cloud

各字段含义如下:

  • id:我们自定义的路由 ID,保持唯一
  • uri:目标服务地址
  • predicates:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。
  • filters:过滤规则,本示例暂时没用。

上面这段配置的意思是,配置了一个 id 为 neo_route 的路由规则,当访问地址 http://localhost:8080/spring-cloud时会自动转发到地址:http://www.ityouknow.com/spring-cloud。配置完成启动项目即可在浏览器访问进行测试,当我们访问地址http://localhost:8080/spring-cloud 时会展示页面展示如下:

证明页面转发成功。

转发功能同样可以通过代码来实现,我们可以在启动类 GateWayApplication 中添加方法 customRouteLocator() 来定制转发规则。

@SpringBootApplication
public class GateWayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("path_route", r -> r.path("/about")
                        .uri("http://ityouknow.com"))
                .build();
    }

}

上面配置了一个 id 为 path_route 的路由,当访问地址http://localhost:8080/about时会自动转发到地址:http://www.ityouknow.com/about和上面的转发效果一样,只是这里转发的是以项目地址/about格式的请求地址。

上面两个示例中 uri 都是指向了我的个人网站,在实际项目使用中可以将 uri 指向对外提供服务的项目地址,统一对外输出接口。

以上便是 Spring Cloud Gateway 最简单的两个请求示例,Spring Cloud Gateway 还有更多实用的功能接下来我们一一介绍。

路由规则

Spring Cloud Gateway 的功能很强大,我们仅仅通过 Predicates 的设计就可以看出来,前面我们只是使用了 predicates 进行了简单的条件匹配,其实 Spring Cloud Gataway 帮我们内置了很多 Predicates 功能。

Spring Cloud Gateway 是通过 Spring WebFlux 的 HandlerMapping 做为底层支持来匹配到转发路由,Spring Cloud Gateway 内置了很多 Predicates 工厂,这些 Predicates 工厂通过不同的 HTTP 请求参数来匹配,多个 Predicates 工厂可以组合使用。

Predicate 介绍

Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。

在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件匹配到对应的路由。网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现。应的 Route 进行处理,接下来我们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。

说白了 Predicate 就是为了实现一组匹配规则,方便让请求过来找到对应的 Route 进行处理,接下来我们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。

通过时间匹配

Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。比如我们现在设置只有在2019年1月1日才会转发到我的网站,在这之前不进行转发,我就可以这样配置:

spring:
  cloud:
    gateway:
      routes:
       - id: time_route
        uri: http://ityouknow.com
        predicates:
         - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]

Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai。

After Route Predicate 是指在这个时间之后的请求都转发到目标地址。上面的示例是指,请求时间在 2018年1月20日6点6分6秒之后的所有请求都转发到地址http://ityouknow.com。+08:00是指时间和UTC时间相差八个小时,时间地区为Asia/Shanghai。

添加完路由规则之后,访问地址http://localhost:8080会自动转发到http://ityouknow.com。

Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发。我们把上面路由规则中的 After 改为 Before,如下:

spring:
  cloud:
    gateway:
      routes:
       - id: after_route
        uri: http://ityouknow.com
        predicates:
         - Before=2018-01-20T06:06:06+08:00[Asia/Shanghai]

就表示在这个时间之前可以进行路由,在这时间之后停止路由,修改完之后重启项目再次访问地址http://localhost:8080,页面会报 404 没有找到地址。

除过在时间之前或者之后外,Gateway 还支持限制路由请求在某一个时间段范围内,可以使用 Between Route Predicate 来实现。

spring:
  cloud:
    gateway:
      routes:
       - id: after_route
        uri: http://ityouknow.com
        predicates:
         - Between=2018-01-20T06:06:06+08:00[Asia/Shanghai], 2019-01-20T06:06:06+08:00[Asia/Shanghai]

这样设置就意味着在这个时间段内可以匹配到此路由,超过这个时间段范围则不会进行匹配。通过时间匹配路由的功能很酷,可以用在限时抢购的一些场景中。

Cookie Route Predicate 可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

spring:
  cloud:
    gateway:
      routes:
           - id: cookie_route
              uri: http://ityouknow.com
              predicates:
              - Cookie=ityouknow, kee.e

使用 curl 测试,命令行输入:

curl http://localhost:8080 --cookie "ityouknow=kee.e"

则会返回页面代码,如果去掉–cookie “ityouknow=kee.e”,后台汇报 404 错误。

通过 Header 属性匹配

Header Route Predicate 和 Cookie Route Predicate 一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: http://ityouknow.com
        predicates:
        - Header=X-Request-Id, \d+

使用 curl 测试,命令行输入:

curl http://localhost:8080  -H "X-Request-Id:666666" 

则返回页面代码证明匹配成功。将参数-H “X-Request-Id:666666”改为-H “X-Request-Id:neo”再次执行时返回404证明没有匹配。

通过 Host 匹配

Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://ityouknow.com
        predicates:
        - Host=**.ityouknow.com

使用 curl 测试,命令行输入:

curl http://localhost:8080  -H "Host: www.ityouknow.com" 
curl http://localhost:8080  -H "Host: md.ityouknow.com" 

经测试以上两种 host 均可匹配到 host_route 路由,去掉 host 参数则会报 404 错误。

通过请求方式匹配

可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由。

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: http://ityouknow.com
        predicates:
        - Method=GET

使用 curl 测试,命令行输入:

# curl 默认是以 GET 的方式去请求
curl http://localhost:8080

测试返回页面代码,证明匹配到路由,我们再以 POST 的方式请求测试。

# curl 默认是以 GET 的方式去请求
curl -X POST http://localhost:8080

返回 404 没有找到,证明没有匹配上路由

通过请求路径匹配

Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://ityouknow.com
        predicates:
        - Path=/foo/{segment}

如果请求路径符合要求,则此路由将匹配,例如:/foo/1 或者 /foo/bar。

使用 curl 测试,命令行输入:

curl http://localhost:8080/foo/1
curl http://localhost:8080/foo/xx
curl http://localhost:8080/boo/xx

经过测试第一和第二条命令可以正常获取到页面返回值,最后一个命令报404,证明路由是通过指定路由来匹配。

通过请求参数匹配

Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://ityouknow.com
        predicates:
        - Query=smile

这样配置,只要请求中包含 smile 属性的参数即可匹配路由。

使用 curl 测试,命令行输入:

curl localhost:8080?smile=x&id=2

经过测试发现只要请求汇总带有 smile 参数即会匹配路由,不带 smile 参数则不会匹配。

还可以将 Query 的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由。

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://ityouknow.com
        predicates:
        - Query=keep, pu.

这样只要当请求中包含 keep 属性并且参数值是以 pu 开头的长度为三位的字符串才会进行匹配和路由。

使用 curl 测试,命令行输入:

curl localhost:8080?keep=pub

测试可以返回页面代码,将 keep 的属性值改为 pubx 再次访问就会报 404,证明路由需要匹配正则表达式才会进行路由。

##通过请求 ip 地址进行匹配
Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://ityouknow.com
        predicates:
        - RemoteAddr=192.168.1.1/24

可以将此地址设置为本机的 ip 地址进行测试。

curl localhost:8080

果请求的远程地址是 192.168.1.10,则此路由将匹配。

组合使用

上面为了演示各个 Predicate 的使用,我们是单个单个进行配置测试,其实可以将各种 Predicate 组合起来一起使用。

例如:

spring:
  cloud:
    gateway:
      routes:
       - id: host_foo_path_headers_to_httpbin
        uri: http://ityouknow.com
        predicates:
        - Host=**.foo.org
        - Path=/headers
        - Method=GET
        - Header=X-Request-Id, \d+
        - Query=foo, ba.
        - Query=baz
        - Cookie=chocolate, ch.p
        - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]

各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。

一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发

阅读全文

Es优化

  1. es的所有内容都可以通过官网文档查看
    网址: https://www.elastic.co/guide/en/elasticsearch/reference/7.x/query-cache.html

  2. es默认查询只会展示前1W条数据
    在官方文档中有描述

    By default, the cache holds a maximum of 10000 queries in up to 10% of the total heap space. To determine if a query is eligible for caching, Elasticsearch maintains a query history to track occurrences.

最多缓存 1w 条查询结果,最多占总堆空间的 10%

…. to be continued

https://www.elastic.co/guide/en/elasticsearch/reference/7.x/query-cache.html

阅读全文

关于搭建Hexo 并部署再Cloudflare Pages上

构建 2021/7/29
  1. 安装Hexo到本地
  2. 关联cloudflare pages 和 github 的账号
  3. 再cloudflare pages 页面上配置 构建项中填写hexo generate
  4. 完成收工!
阅读全文
1
avatar
John Doe
奉献还是索取,会心痛,但还是一往直前
img_show