Summary of SpringCloud study notes (5)

1. zuul and Gateway


Netflix has developed zuul.

Zuul has now stopped updating, and zuul2 was to be released before, and the development of zuul2 has been delayed.

Zuul has been doing the effect of gateway.

Gateway is the second-generation microservice gateway developed by SpringCloud, replacing zuul.

2. Introduction to Gateway


Location of Gateway:
insert image description here


The bottom layer of the SpringCloud Gateway gateway uses the netty communication framework:
insert image description here


What is webflux?

  • The name of the WebFlux module is spring-webflux, and the Flux in the name comes from the class Flux in Reactor. Spring webflux has a new non-blocking functional Reactive web framework for building asynchronous, non-blocking, event-driven services that scale very well.

Project Architecture Diagram:

  • Requests generally want to pass through nginx load balancing, and then enter the gateway cluster.
    insert image description here

3. Core Concept + Architecture Flow of Gateway


The three core concepts of gateway gateway:insert image description here

Gateway gateway architecture diagram:

  • The core logic is: 路由转发 + 执行过滤器链.
    insert image description here

Official architecture diagram:
insert image description here

4. Gateway's build Gateway server + test


Step 1: Create a project and configure dependencies.

<!--引入gateway依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!--添加eureka-client客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Step 2: Modify the application.yml file, add routing ID, routing address, and assertion.

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          predicates:
            - Path=/payment/get/** # 断言。 路径相匹配的进行路由。

        - id: payment_routh2 # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          predicates:
            - Path=/payment/lb/** # 断言。 路径相匹配的进行路由。


eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      # 表示是否将自己注册进EurekaServer默认为true
      register-with-eureka: true
      # 是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
      fetch-registry: true
      # 入驻地址是哪个
      defaultZone: http://eureka7001.com:7001/eureka # 单机

Precautions:

  • Gateway gateway does not introduce springboot web and actuator dependencies.

Step 3: Start the project and test it.
insert image description here

5. Two configuration methods of gateway routing


The first one: as demonstrated above, configured in the configuration file yml.

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          predicates:
            - Path=/payment/get/** # 断言。 路径相匹配的进行路由。

        - id: payment_routh2 # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          predicates:
            - Path=/payment/lb/** # 断言。 路径相匹配的进行路由。

The second: code injection routeLocator bean.

  • The case visits Baidu's address.
package com.itholmes.springcloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GateWayConfig {
    
    

    //使用注入bean的方式来修改网关的路由
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
    
    
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

        // 这里映射百度的地址 , 目录为https://news.baidu.com/guonei
        //这样访问http://localhost:9527/guonei 就会 访问到 https://news.baidu.com/guonei的信息
        routes.route("path_route_itholmes",
                r -> r.path("/guonei")
                .uri("https://news.baidu.com/guonei"));

        return routes.build();
    }
}

6. Configure dynamic routing for Gateway


The routes we configured above are all hard-coded. By default, Gateway will create a dynamic route with the name of the microservice on the registry according to the service list registered in the registry for forwarding, so as to realize the function of dynamic routing.

  • First enable the function of dynamically creating routes from the registry, and use the microservice name for routing.
  • uri is configured as the microservice name corresponding to the registry.
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          # 开启从注册中心动态创建路由的功能,利用微服务名进行路由。
          enabled: true
      routes:
        - id: payment_routh # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          # uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/get/** # 断言。 路径相匹配的进行路由。

        - id: payment_routh2 # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          # uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/lb/** # 断言。 路径相匹配的进行路由。


eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      # 表示是否将自己注册进EurekaServer默认为true
      register-with-eureka: true
      # 是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
      fetch-registry: true
      # 入驻地址是哪个
      defaultZone: http://eureka7001.com:7001/eureka # 单机

7. Gateway's Predicate classification


There are many kinds of Predicate assertions, just like adding where conditions, to determine whether the route meets the conditions:
insert image description here


For route predicates of three time ranges, route requests that match the time range:

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          # 开启从注册中心动态创建路由的功能,利用微服务名进行路由。
          enabled: true
      routes:
        - id: payment_routh2 # 路由ID。 没有固定规则但要求唯一,建议配合服务名。
          # uri: http://localhost:8001 # 路由地址。 匹配后提供服务的路由地址。
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/lb/** # 断言。 路径相匹配的进行路由。
            - After=2022-07-01T09:42:44.070+08:00[Asia/Shanghai] # 在这个时间之后的请求,才能正常通过路由。
            - before=2022-07-01T09:42:44.070+08:00[Asia/Shanghai] # 在这个时间之前的请求,才能正常通过路由。
            - Between=2022-07-01T09:42:44.070+08:00[Asia/Shanghai],2022-07-01T09:42:44.070+08:00[Asia/Shanghai] # 在这个时间之间,才能正常通过路由。

Cookie Route Predicate parameters:

predicates:
  - Path=/payment/lb/** # 断言。 路径相匹配的进行路由。
  - Cookie=username,zzyy # cookie,key是username,value是zzyy

insert image description here
With curl, you can test the effect of requests with and without cookies:
insert image description here


Header Route Predicate parameters:

  • The meaning of the figure below: There must be an X-Request-Id request header in the request, and the value must conform to \d+ (regular, number).
    insert image description here

Ditto:
insert image description here
insert image description here
insert image description here
insert image description here


Query Route Predicate:
insert image description here

8. Gateway's Filter(GatewayFilter)


This refers to the instance of GatewayFilter in the Spring framework. Using the filter, the request can be modified before or after the request is routed.

The life cycle of Spring Cloud Gateway's filter:

  • pre and post. Front, rear.

Types of filters of Spring Cloud Gateway:

  • Two kinds: GatewayFilter and GlobalFilter.

There are many different types of filters for GatewayFilter and GlobalFilter.


Custom global GatewayFilter filter:

  • Two main interfaces: GloalFilter, Ordered.
  • ordered is to determine the priority order, which filter is executed first.
  • Through exchange acquisition, request and response, a series of operations are modified.
package com.itholmes.springcloud.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    
    

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    

        log.info("*******come in MyLogGateWayFilter: "+new Date());
        //exchange.getRequest()
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");

        if (uname == null){
    
    
            log.info("*********用户名为null,非法用户!");
            //exchange.getResponse() , HttpStatus.NOT_ACCEPTABLE是不可用请求。
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            Mono<Void> voidMono = exchange.getResponse().setComplete();
            return voidMono;
        }
        //放行,去下一个过滤链
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
    
    
        //order就是顺序,一般是数字越小,优先级越高。
        return 0;
    }
}

9. Distributed Configuration Center of Spring Cloud Config (Introduction)


insert image description here

Multiple microservices need the necessary configuration information to run, so it is essential to have a centralized and dynamic configuration management facility (meaning that application.yml can be configured uniformly).


Official explanation:
insert image description here

SpringCloud Config is divided into two parts: server and client.

insert image description here


Several functions of Spring cloud config:
insert image description here


SpringCloud Config uses Git by default to store configuration files (there are other ways of SVN, local files), and it is recommended to use Git.

10. SpringCloud Config configuration control center construction (server)


That is to build the following server:
insert image description here


Step 1: Create a new Repository repository named springcloud-config on Github. Get the git address. And clone the warehouse clone.

insert image description here

Step 2: Create a project and add dependencies.

<!--springcloud config配置中心的依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

<!--添加eureka-client客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Step 3: Modify the application.yml file.

  • Configure the git related operations of config.
server:
  port: 3344
spring:
  application:
    name: cloud-config-center # 微服务名称
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/lixiaogou/sprincloud-config.git #GitHub上面的git仓库名字
          search-paths: #搜索目录
            - springcloud-config
      label: master #读取分支

# 服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

Step 4: Add a startup class, add @EnableConfigServer //Enable the config service.

package com.itholmes.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer //开启config服务
public class ConfigCenterMain3344 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(ConfigCenterMain3344.class,args);
    }
}

The corresponding formula is as follows:
insert image description here
Official formula:

  • The third one is recommended.
    insert image description here

11. SpringCloud Config configuration control center configuration and testing (client)


SpringCloud Config has a client and a server.

Step 1: Create a project and add SpringCloud Config client dependencies.

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

Step 2: Create the bootstrap.yml configuration file.

  • What is the bootstrap.yml configuration file?
    insert image description here
server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    # SpringCloud Config 客户端配置
    config:
      label: master # 分支名称
      name: config # 配置文件名称
      profile: dev # 读取后缀名称
      # 上述三个综合: master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 # 配置中心地址

# 服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka
  • In fact, the config client is to find the config server first, and the corresponding information is as follows:
    insert image description here

Step 3: Test the interface, http://localhost:3355/configInfo.

package com.itholmes.springcloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {
    
    

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
    
    
        return configInfo;
    }

}

The biggest problem is the dynamic refresh problem of distributed configuration:

  • It means that when we modify the information on git, the config server will immediately respond to the corresponding modified data, but the config client has no response (unless the client system is restarted)!

12. How does the configuration center of Spring Cloud Config solve the problem of dynamic refresh?


Step 1: Add actuator monitoring dependencies.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Step 2: Expose monitoring endpoints.

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    # SpringCloud Config 客户端配置
    config:
      label: master # 分支名称
      name: config # 配置文件名称
      profile: dev # 读取后缀名称
      # 上述三个综合: master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 # 配置中心地址

# 服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

# 暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

Step 3: Add the @RefreshScope annotation to the controller layer.

  • Adding this annotation has the ability to refresh.
package com.itholmes.springcloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RefreshScope
public class ConfigClientController {
    
    

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
    
    
        return configInfo;
    }

}

Note: The above content cannot be dynamically refreshed in the configuration, and the operation and maintenance personnel must send a Post request to refresh 3355!

Step 4: The operation and maintenance personnel send a Post request to refresh 3355.

  • Execute the curl -X POST “http://localhost:3355/actuator/refresh” command to refresh.

Such a configuration is the pros and cons:

  • Multiple servers need to send each request, which is very troublesome.
  • Then there are 100 machines, and I want to change a few of them, which is also very troublesome to achieve.

Guess you like

Origin blog.csdn.net/IT_Holmes/article/details/125537099