在使用微服务架构时,往往我们需要搭建一个网关服务,作为各个微服务的统一入口。Spring gateway作为网关服务的后起之秀,受到各大企业的欢迎。下面介绍下网关服务Spring gateway的搭建。

  1. 引入依赖,这一步比较重要,也需要小心,要不然会因为jar问题导致服务无法正常启动,下面要贴出网关服务pom文件核心代码:

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.2.1.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--  服务注册/发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--  配置中心来做配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework</groupId>-->
<!--            <artifactId>spring-webmvc</artifactId>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>javax.servlet</groupId>-->
<!--            <artifactId>javax.servlet-api</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope><!--provided 打包时不用带上,tomcat已包含-->
        </dependency>


    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

在这一步需要注意的地方有,1,不要引入 spring-webmvc依赖,spring-cloud-starter-gateway集成了webflux,具备web方便的功能了,因此不要引入spring-webmvc;2.要引入servlet-api依赖,不要引入javax.servlet-api依赖;3.注意jdk,springboot,springcloud的版本对应关系,版本对应不上,启动也会报错。

2.跨域问题的统一处理

使用单一服务,跨域服务放在服务内,使用微服务架构后,跨域交由网关统一处理,各个微服务不必再处理了,如果网关配置了跨域,各个微服务还保留跨域,运行时也会报错,下面贴出网关中跨域处理:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfiguration {

    @Bean
    public CorsWebFilter corsWebFilter() {
        UrlBasedCorsConfigurationSource source =  new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.setAllowCredentials(true);

        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsWebFilter(source);
    }
}

3.路由的配置,gateway主要通过配置路由,断言,过滤器进行URL识别和服务分发,以下是gateway三大核心:

Route路由:路由是构建网关的基本模块,它由ID、目标URI、一系列的断言和过滤器组成,如果断言为true则匹配该路由。对应DispatcherHandler分发请求和RoutePredicate-HandlerMapping路由查找
Predicate(断言):参考的是Java8的java.util.function.Predicate。开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。即匹配Predicate成功,才跳转到对应的目标URI
Filter过滤:指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。对应FilteringWebHandler过滤器链,代理服务处理。

配置在网关服务的application.yml文件中,下面贴出示例:

server:
  port: 8088
spring:
  application:
    name: mall-gateway 
  main:
    web-application-type: reactive

  cloud:
    gateway:
      routes:
        - id: mall_web_route
          uri: lb://mall
          predicates:
            - Path=/system/**,/tool/**

        - id: mall_app_route
          uri: lb://mall
          predicates:
            - Path=/api/**

        - id: genarator_web_route
          uri: lb://genarator
          predicates:
            - Path=/tool/**


        - id: mall-bbs_web_route
          uri: lb://mall-bbs
          predicates:
            - Path=/admin/**,/sys/**


        - id: mall-bbs_app_route
          uri: lb://mall-bbs
          predicates:
            - Path=/app/**,/resource/**

      discovery:
        locator:
          enabled: true

这里有一点需要注意的是,不同服务之意path开头不要相同,相同的话,gateway会交由第一个服务进行处理,此时就会出现诸如鉴权失败等问题。举个例子,服务1和服务2拥有独立的后台管理系统,服务1路径以admin开头,服务2也以admin开头,网关中服务1和服务2 path均配置了/admin/**开头,当请求服务2的/admin/**开头的接口时,由于存在同样路径开头的配置,gateway会路由到服务1交由服务1进行处理。此时就得不到预期的结果,需要将其中一个路径更换为不同的地址。

4.配置启动类,注意排除数据源

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

经过以上4个主要步骤就完成Spring gateway微服务的搭建。 

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部