Spring Cloud Kubernetes 之实战网关 Gateway

用户头像
Damon
关注
发布于: 2020 年 05 月 15 日
Spring Cloud Kubernetes之实战网关Gateway

微服务化已成为当今主流趋势,但不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:



  •  客户端会多次请求不同的微服务,增加了客户端的复杂性。



  • 存在跨域请求,在一定场景下处理相对复杂。



  • 认证复杂,每个服务都需要独立认证。



  • 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。



  • 某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难 。



  • 网关会解决这些问题,可以将服务跟外网进行隔离起到一定的保护作用,同时服务间局域网通信更加快捷。而且在网关中可以做限流、权限校验,使得服务更加专注自身业务。



优点如下:



  1.  安全,只有网关系统对外进行暴露,微服务可以隐藏在内网,通过防火墙保护

  2. 易于监控,可以在网关收集监控数据并将其推送到外部系统进行分析

  3.  易于认证,可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证

  4.  减少了客户端与各个微服务之间的交互次数

  5.  易于统一鉴权

  6. 可以用来作LB



环境



  • ubuntu16.04



  • docker18.04



  • java1.8 +



  • springboot 2.1.6



创建项目



创建好项目之后,首先引入依赖:

        <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>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-kubernetes-core</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-kubernetes-discovery</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-commons</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

        </dependency>

    </dependencies>



同样,我们需要配置初始化bean,这就涉及到配置文件bootstrap.yaml:

spring:

  application:

    name: demo-gateway

  cloud:

    kubernetes:

      discovery:

        all-namespaces: true

    gateway:

      discovery:

        locator:

          enabled: true

          lowerCaseServiceId: true

      routes: #路由配置:参数为一个List

      - id: consumer-00 #唯一标识

        uri: lb://demo-admin-service-service #转发的地址,写服务名称

        order: -1

        predicates:

        - Path=/cloud-admin/** #判断匹配条件,即地址带有/ribbon/**的请求,会转发至lb:demo-admin-service-service

        filters:

        - StripPrefix=1 #去掉Path前缀,参数为1代表去掉/ribbon

        

      - id: consumer-01

        uri: lb://demo-cas-service

        order: -1

        predicates:

        - Path=/demo-cas/**

        filters:

        - StripPrefix=1

        

      - id: consumer-02

        uri: lb://demo-admin-service

        order: -1

        predicates:

        - Path=/demo-admin/**

        filters:

        - StripPrefix=1

  http:

    encoding:

      charset: UTF-8

      enabled: true

      force: true

  mvc:

    throw-exception-if-no-handler-found: true

  main:

    allow-bean-definition-overriding: true # 当遇到同样名称时,是否允许覆盖注册



接下来就是application.yaml:

server:

  port: 5555

  undertow:

    accesslog:

      enabled: false

      pattern: combined

  servlet:

    session:

      timeout: PT120M

  

logging:

  path: /data/${spring.application.name}/logs

# we enable some of the management endpoints to make it possible to restart the application

management:

  endpoint:

    restart:

      enabled: true

    health:

      enabled: true

    info:

      enabled: true

client:

  http:

    request:

      connectTimeout: 8000

      readTimeout: 30000



启动类:

@SpringBootApplication(scanBasePackages = { "com.gemantic" })

@EnableDiscoveryClient

public class GatewayApp {

public static void main(String[] args) {

        SpringApplication.run(GatewayApp.class, args);

    }

}



增加了注解@EnableDiscoveryClient,为了实现服务的LB。



注意:

在springboot2.x中,需要处理跨域时的问题:1.x中我们用的是Netflix公司的Zuul组件做的网关以及LB,其在处理时无需加跨域处理,只要在各微服务上加注解@CrossOrigin即可解决跨域问题。但在springboot2.x中默认的跨域拦截方式前面说了,改了。而且Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,与其不同,所以在跨域问题上需要注意,这里需要加上跨域的bean,同时,各微服务就不需要注解来解决跨域问题了。



@Bean

public CorsWebFilter corsFilter() {

CorsConfiguration config = new CorsConfiguration();

config.setAllowCredentials(true); // 允许cookies跨域

config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin

config.addAllowedHeader("*");// #允许访问的头信息,*表示全部

config.addAllowedMethod("*");

//config.addExposedHeader("token");

config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

source.registerCorsConfiguration("/**", config);

return new CorsWebFilter(source);

}



ok,到此网关基本工作结束,如果想在网关中加上一些鉴权等逻辑可以自行添加。Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,比如:内置了10种Router等,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。



从上面可以看出Springcloud Gateway 与Netflix公司的Zuul还是有区别的,尤其对于2.x上,改动还是要注意的。



结束福利



开源几个微服务的架构设计项目:

https://github.com/damon008/spring-cloud-oauth2

https://github.com/damon008/spring-cloud-k8s

https://gitee.com/damon_one/spring-cloud-k8s

https://gitee.com/damon_one/spring-cloud-oauth2



欢迎大家 star,多多指教。



关于作者

  笔名:Damon,技术爱好者,长期从事 Java 开发、Spring Cloud 的微服务架构设计,以及结合 docker、k8s 做微服务容器化,自动化部署等一站式项目部署、落地。Go 语言学习,k8s 研究,边缘计算框架 KubeEdge 等。公众号 程序猿 Damon 发起人。个人微信 MrNull008,欢迎來撩。



关注公众号





发布于: 2020 年 05 月 15 日 阅读数: 119
用户头像

Damon

关注

God bless the fighters. 2020.03.11 加入

欢迎关注公众号:程序猿Damon,长期从事Java开发,研究Springcloud的微服务架构设计,Hadoop资源调度,以及结合k8s做微服务容器化,自动化部署等一站式项目部署、落地。学习Go,研究边缘计算KubeEdge等。

评论 (1 条评论)

发布
用户头像
哈哈 写的还不错

2020 年 05 月 19 日 14:59
回复
没有更多了
Spring Cloud Kubernetes之实战网关Gateway