springcloud Alibaba入门系列之springcloud gateway

前面我们分别了解了:

  • 使用Nacos实现服务注册与发现
  • Springcloud Alibaba入门之客户端调用方式

在这篇我们来看看整合springcloud gateway的使用,还是由我们的alibaba-nacos-producer来提供服务,通过gateway来转发我们的/hello路径的接口,接下来看:

什么是gateway?

springcloud gateway是一个全新的项目,其基于spring5.0 以及springboot2.0和项目Reactor等技术开发的网关,其主要的目的是为微服务架构提供一种简单有效的API路由管理方式.

还有一点springcloud gateway是为了解决springcloud官方对Zuul停止维护而出现的替代方案,满足网关的基本的功能,如:安全 监控以及埋点和限流等.详细请看官方文档Spring Cloud Gateway目前版本最新是2.2.0 RC1,想看的猿友们可以去看看对应版本的文档.

搭建过程

首先我们需要创建一个名为alibaba-nacos-gateway项目,创建过程跟之前的一样,接着我们需要引入相应的依赖,来看pom.xml文件,代码如下:


    org.springframework.boot
    spring-boot-starter-parent
    2.2.0.RELEASE
     

com.cacmp
alibaba-nacos-gateway
0.0.1-SNAPSHOT
alibaba-nacos-gateway
服务网关gateWay的使用


    1.8



    
        org.springframework.cloud
        spring-cloud-starter-gateway
    
    
        org.springframework.cloud
        spring-cloud-starter-alibaba-nacos-discovery
    


    
        
            org.springframework.cloud
            spring-cloud-dependencies
            Greenwich.SR3
            pom
            import
        
        
            org.springframework.cloud
            spring-cloud-alibaba-dependencies
            0.9.0.RELEASE
            pom
            import
        
    

在pom文件中,我们引入了nacos-discovery依赖,其目的是也将它注册进去,同时去掉了web相关的依赖,其主要的原因是:

  • springcloud gateway是依赖于webflux
  • 传统的web依赖和webflux是不兼容的,所以我们去掉了web相关的依赖,引入启动项目时会报错,我们后面看,接着我们来看配置文件,其中配置路由有三种方式,我们分别来看:
通过LoadBalancerClient Filter的方式
server:
  port: 9004
spring:
  application:
    name: alibaba-nacos-gateway
cloud:
  nacos:
  discovery:
    server-addr: localhost:8848
gateway:
  routes:
    - id: alibaba-nacos-producer
      uri: lb://alibaba-nacos-producer
      predicates:
        - Path=/hello/**

简单的来看下该配置中的属性,其中:

  • id:需要访问的目标服务,我们这里还是以alibaba-nacos-producer为提供的服务
  • url: lb:目标服务在注册中心的服务名.
  • predicates(断言):其主要的目的是可以路由到以hello打头的所有接口方法

最主要的就是这三个了,接着我们来看启动类,代码如下:

package com.cacmp.alibaba.nacos;

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

/**
 * @author cb
 */
@SpringBootApplication
@EnableDiscoveryClient
public class AlibabaNacosGatewayApplication {

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

可以看到的是,同样我们需要将该服务注册到注册中心,接下来就是见证奇迹的时候了,分别启动我们的alibaba-nacos-producer和alibaba-nacos-gateway,我们来看Nacos的管理台,如下图:

微信截图_20191025223653.png

服务列表中存在我们刚刚注册的服务,接着我们访问http://127.0.0.1:9004/hello,会看到报错,错误如下:

2019-10-25 22:39:09.984  INFO 16124 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: alibaba-nacos-producer.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-10-25 22:39:39.161 ERROR 16124 --- [ctor-http-nio-6] reactor.netty.http.server.HttpServer     : [id: 0xb3f12e9c, L:/0:0:0:0:0:0:0:1:9004 - R:/0:0:0:0:0:0:0:1:52617] 

java.lang.NoSuchMethodError: reactor.netty.http.client.HttpClient.chunkedTransfer(Z)Lreactor/netty/http/client/HttpClient;
at org.springframework.cloud.gateway.filter.NettyRoutingFilter.filter(NettyRoutingFilter.java:125) ~[spring-cloud-gateway-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:138) ~[spring-cloud-gateway-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44) ~[spring-cloud-gateway-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.lambda$filter$0(FilteringWebHandler.java:118) ~[spring-cloud-gateway-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]
springcloud Alibaba入门系列之springcloud gateway_第1张图片
页面.png

页面出现这个问题,一脸懵逼,看错误真不知道该错误如何解决,按理说应该没毛病,首先是通过引入的pom文件来一一排除,升级了gateway的版本还是不行,同样升级了nacos版本为最新的0.9.0和springcloud版本都不行,最后想到了是springboot版本的问题,我建项目的springboot版本为最新的2.2.0版本,通过将版本降到2.2.0以下,解决了问题,如图:

springcloud Alibaba入门系列之springcloud gateway_第2张图片
微信截图_20191022143913.png
springcloud Alibaba入门系列之springcloud gateway_第3张图片
gateway2.png

修改之后的springboot版本,代码如下:

  
    org.springframework.boot
    spring-boot-starter-parent
    2.1.9.RELEASE
     

重启我们的服务,继续访问刚刚的地址,会发现如图的结果:

springcloud Alibaba入门系列之springcloud gateway_第4张图片
微信截图_20191025225343.png

说明可以了,如果猿友们在学习的过程中,建议springboot版本为2.2.0以下,如果是上述的问题,这里在演示我们在本篇提到的为何要剔除掉web依赖的错误问题:

  • 首先我们在alibaba-nacos-gateway的pom文件中引入web依赖,重启我们的服务,会报以下的错误,错误代码如下:
Caused by:   org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.convert.ConversionService' 
  available: expected at least 1 bean which qualifies as autowire candidate.
 Dependency annotations:     {@org.springframework.beans.factory.annotation.Qualifier(value=webFluxConversionService)}
    at         org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1662) ~[spring-beans-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at   org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1221) ~[spring-beans-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at   org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175) ~[spring-beans-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at     org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at         .springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.10.RELEASE.jar:5.1.10.RELEASE]
... 19 common frames omitted
通过配置context-path的方式

同样我们可以通过配置context-path的方式来配置我们的路由访问我们的服务提供者,这种配置其主要的目的是为了配置统一的固定访问前缀来实现的,我们来看具体的配置过程

  • 在我们的服务提供者alibaba-nacos-producer中,配置代码如下:
server:
  port: 8080
servlet:
context-path: /producer
spring:
  application:
name: alibaba-nacos-producer
cloud:
nacos:
  discovery:
    server-addr: localhost:8848

其余不变,我们只需要添加固定访问前缀/producer.接着我们来看alibaba-nacos-gateway的配置过程,代码如下:

server:
  port: 9004
spring:
application:
  name: alibaba-nacos-gateway
cloud:
nacos:
  discovery:
    server-addr: localhost:8848
gateway:
  routes:
    - id: alibaba-nacos-producer
      uri: lb://alibaba-nacos-producer
      predicates:
        - Path=/producer/**

这里只需要将之前的断言处的路径该为固定前缀/producer即可,重启我们的服务访问http://127.0.0.1:9004/producer/hello,会看到如下的结果:

springcloud Alibaba入门系列之springcloud gateway_第5张图片
context.png

同样我们也能访问目标服务,接着我们来看第三种方式

通过跳过固定前缀的方式

其实这种方式为了解决方式二的不足之处,方式确实可以,但不足之处是代码的侵入性强,试想加入我们有很多服务区路由的话是不是都要这样配置,太麻烦了且笨重,第三种的方式刚好这也是springcloud gateway推荐的方式,通过跳过固定前缀的方式来路由目标服务,如何配置我们来看:

  • 首先我们不在需要在alibaba-nacos-producer的context-path的前缀的配置
  • 在我们的alibaba-nacos-gateway的配置,代码如下:
server:
  port: 9004
spring:
  application:
name: alibaba-nacos-gateway
cloud:
nacos:
  discovery:
    server-addr: localhost:8848
gateway:
  routes:
    - id: alibaba-nacos-producer
      uri: lb://alibaba-nacos-producer
      predicates:
        - Path=/producer/**
      filters:
        - StripPrefix=1

为啥StripPrefix的值为1呢?因为我们的前缀当前的位置就是1,这样就可以了,我们访问方式二中的那个地址,会得到如下结果:

方式3.png

同样我们也能得到同样的结果,这就是springcloud gateway的简单使用,更多配置可以详看官方文档,好了,本篇就到这里了...

代码示例

  • Gitee:https://gitee.com/cblove_java/nacos_learning_demo

你可能感兴趣的:(springcloud Alibaba入门系列之springcloud gateway)