[microservices] the Gateway backend program of Gateway microservices is the only way

Posted by Ekate on Sat, 15 Jan 2022 15:28:50 +0100

preface

introduce

The previous article has completed the call between services, but how can we implement the interface of external calling services.
First of all, we can call it by directly calling the public network ip + port. This method is certainly feasible, but it must be unsafe to expose the ip and port directly. In case someone hacked your server, This is a little uncomfortable (the victim who has been cleaned up the database data said that I am a student's server. What are you doing.

At this time, we introduce a term - reverse agent
Generally speaking, when you call the interface of a service, you will not directly access the real address of the interface, but send a request to the proxy server. The proxy server forwards the request to other services. After the service processing is completed, the result is returned to the proxy server, and then the proxy server forwards the result to you
In this process, the user does not know that he is calling the proxy server. If the user thinks he is calling the address of the real service, this process becomes the reverse proxy. See this for details Let's briefly talk about the forward agent and reverse agent I understand. It's pure vernacular

GateWay effect

The Gateway actually acts as a reverse proxy. It can also be considered that the Gateway is the entrance to all services. If the hardware supports it, I think the relatively simple architecture is shown in the figure below

In fact, you can set several more layers of nginx for one layer of agent, so that you can handle more concurrency.

Reverse Gateway implementation

pom.xml

The following are the dependencies to be introduced

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>test</artifactId>
        <groupId>com.xiaow</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!--	<dependencies>-->
    <!-- Configure dependencies -->
    <dependencies>
        <dependency>
            <groupId>com.xiaow</groupId>
            <artifactId>common</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.xiaow</groupId>
            <artifactId>common</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>


        <!--fastjson rely on-->
        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>fastjson</artifactId>

            <version>1.2.73</version>

        </dependency>



    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.xiaow.test.Provider8001</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

configuration file

It is mainly about the configuration of routes

routes explanation

 routes:
        - id: consumer #Set the routing ID (it can be written freely in theory)
          uri: lb://consumer # set the URL of the route LB: / / Nacos service registration name
          filters:
            - StripPrefix=1
          predicates:
            - Path=/one/** #Path matching rule

Configure as above
id is just the id for configuring a route. This id can be written casually, but it cannot be repeated.
uri: lb:consumer consumer corresponds to the registered service name in Nacos
Path is a matching path
For example, if the interface call of the consumer service is / get, the path through the gateway call is / one/get

All profiles

stay server:
  port: 8050 #Service port

spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: http://192.168.30.1:8848/
    gateway:
      discovery:
        locator:
          enabled: true #Using service discovery routing
      routes:
        - id: consumer #Set the routing ID (it can be written freely in theory)
          uri: lb://consumer # set the URL of the route LB: / / Nacos service registration name
          filters:
            - StripPrefix=1
          predicates:
            - Path=/one/** #Path matching rule
        - id: provider
          uri: lb://provider
          filters:
            - StripPrefix=1
          predicates:
            - Path=/two/** #Path matching rule
        - id: account
          uri: lb://account
          filters:
            - StripPrefix=1
          predicates:
            - Path=/account/** #Path matching rule


management:
  endpoints:
    web:
      exposure:
        include: "*"

Handling cross domain

package com.xiaow.gateway.config;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

import java.util.stream.Collectors;

@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }
    @Bean
    @ConditionalOnMissingBean
    public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
        return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
    }

}

Startup class

package com.xiaow.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Gateway8050 {
    public static void main(String[] args) {
        SpringApplication.run(Gateway8050.class,args);
    }
}

summary

Or review

Topics: Java Back-end Microservices gateway