前面我们分别了解了:
在这篇我们来看看整合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文件,代码如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cacmp</groupId>
<artifactId>alibaba-nacos-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>alibaba-nacos-gateway</name>
<description>服务网关gateWay的使用</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.9.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在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的管理台,如下图:
服务列表中存在我们刚刚注册的服务,接着我们访问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]
页面出现这个问题,一脸懵逼,看错误真不知道该错误如何解决,按理说应该没毛病,首先是通过引入的pom文件来一一排除,升级了gateway的版本还是不行,同样升级了nacos版本为最新的0.9.0和springcloud版本都不行,最后想到了是springboot版本的问题,我建项目的springboot版本为最新的2.2.0版本,通过将版本降到2.2.0以下,解决了问题,如图:
修改之后的springboot版本,代码如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
重启我们的服务,继续访问刚刚的地址,会发现如图的结果:
说明可以了,如果猿友们在学习的过程中,建议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 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,这样就可以了,我们访问方式二中的那个地址,会得到如下结果:
同样我们也能得到同样的结果,这就是springcloud gateway的简单使用,更多配置可以详看官方文档,好了,本篇就到这里了...