前面我們分別了解了:
在這篇我們來(lái)看看整合springcloud gateway的使用,還是由我們的alibaba-nacos-producer來(lái)提供服務(wù),通過(guò)gateway來(lái)轉(zhuǎn)發(fā)我們的/hello路徑的接口,接下來(lái)看:
什么是gateway?
springcloud gateway是一個(gè)全新的項(xiàng)目,其基于spring5.0 以及springboot2.0和項(xiàng)目Reactor等技術(shù)開(kāi)發(fā)的網(wǎng)關(guān),其主要的目的是為微服務(wù)架構(gòu)提供一種簡(jiǎn)單有效的API路由管理方式.
還有一點(diǎn)springcloud gateway是為了解決springcloud官方對(duì)Zuul停止維護(hù)而出現(xiàn)的替代方案,滿足網(wǎng)關(guān)的基本的功能,如:安全 監(jiān)控以及埋點(diǎn)和限流等.詳細(xì)請(qǐng)看官方文檔Spring Cloud Gateway目前版本最新是2.2.0 RC1,想看的猿友們可以去看看對(duì)應(yīng)版本的文檔.
搭建過(guò)程
首先我們需要?jiǎng)?chuàng)建一個(gè)名為alibaba-nacos-gateway項(xiàng)目,創(chuàng)建過(guò)程跟之前的一樣,接著我們需要引入相應(yīng)的依賴,來(lái)看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>服務(wù)網(wǎng)關(guān)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依賴,其目的是也將它注冊(cè)進(jìn)去,同時(shí)去掉了web相關(guān)的依賴,其主要的原因是:
- springcloud gateway是依賴于webflux
- 傳統(tǒng)的web依賴和webflux是不兼容的,所以我們?nèi)サ袅藈eb相關(guān)的依賴,引入啟動(dòng)項(xiàng)目時(shí)會(huì)報(bào)錯(cuò),我們后面看,接著我們來(lái)看配置文件,其中配置路由有三種方式,我們分別來(lái)看:
通過(guò)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/**
簡(jiǎn)單的來(lái)看下該配置中的屬性,其中:
- id:需要訪問(wèn)的目標(biāo)服務(wù),我們這里還是以alibaba-nacos-producer為提供的服務(wù)
- url: lb:目標(biāo)服務(wù)在注冊(cè)中心的服務(wù)名.
- predicates(斷言):其主要的目的是可以路由到以hello打頭的所有接口方法
最主要的就是這三個(gè)了,接著我們來(lái)看啟動(dòng)類,代碼如下:
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);
}
可以看到的是,同樣我們需要將該服務(wù)注冊(cè)到注冊(cè)中心,接下來(lái)就是見(jiàn)證奇跡的時(shí)候了,分別啟動(dòng)我們的alibaba-nacos-producer和alibaba-nacos-gateway,我們來(lái)看Nacos的管理臺(tái),如下圖:
服務(wù)列表中存在我們剛剛注冊(cè)的服務(wù),接著我們?cè)L問(wèn)http://127.0.0.1:9004/hello,會(huì)看到報(bào)錯(cuò),錯(cuò)誤如下:
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]
頁(yè)面出現(xiàn)這個(gè)問(wèn)題,一臉懵逼,看錯(cuò)誤真不知道該錯(cuò)誤如何解決,按理說(shuō)應(yīng)該沒(méi)毛病,首先是通過(guò)引入的pom文件來(lái)一一排除,升級(jí)了gateway的版本還是不行,同樣升級(jí)了nacos版本為最新的0.9.0和springcloud版本都不行,最后想到了是springboot版本的問(wèn)題,我建項(xiàng)目的springboot版本為最新的2.2.0版本,通過(guò)將版本降到2.2.0以下,解決了問(wèn)題,如圖:
修改之后的springboot版本,代碼如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
重啟我們的服務(wù),繼續(xù)訪問(wèn)剛剛的地址,會(huì)發(fā)現(xiàn)如圖的結(jié)果:
說(shuō)明可以了,如果猿友們?cè)趯W(xué)習(xí)的過(guò)程中,建議springboot版本為2.2.0以下,如果是上述的問(wèn)題,這里在演示我們?cè)诒酒岬降臑楹我蕹魒eb依賴的錯(cuò)誤問(wèn)題:
- 首先我們?cè)赼libaba-nacos-gateway的pom文件中引入web依賴,重啟我們的服務(wù),會(huì)報(bào)以下的錯(cuò)誤,錯(cuò)誤代碼如下:
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
通過(guò)配置context-path的方式
同樣我們可以通過(guò)配置context-path的方式來(lái)配置我們的路由訪問(wèn)我們的服務(wù)提供者,這種配置其主要的目的是為了配置統(tǒng)一的固定訪問(wèn)前綴來(lái)實(shí)現(xiàn)的,我們來(lái)看具體的配置過(guò)程
- 在我們的服務(wù)提供者alibaba-nacos-producer中,配置代碼如下:
server:
port: 8080
servlet:
context-path: /producer
spring:
application:
name: alibaba-nacos-producer
cloud:
nacos:
discovery:
server-addr: localhost:8848
其余不變,我們只需要添加固定訪問(wèn)前綴/producer.接著我們來(lái)看alibaba-nacos-gateway的配置過(guò)程,代碼如下:
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即可,重啟我們的服務(wù)訪問(wèn)http://127.0.0.1:9004/producer/hello,會(huì)看到如下的結(jié)果:
同樣我們也能訪問(wèn)目標(biāo)服務(wù),接著我們來(lái)看第三種方式
通過(guò)跳過(guò)固定前綴的方式
其實(shí)這種方式為了解決方式二的不足之處,方式確實(shí)可以,但不足之處是代碼的侵入性強(qiáng),試想加入我們有很多服務(wù)區(qū)路由的話是不是都要這樣配置,太麻煩了且笨重,第三種的方式剛好這也是springcloud gateway推薦的方式,通過(guò)跳過(guò)固定前綴的方式來(lái)路由目標(biāo)服務(wù),如何配置我們來(lái)看:
- 首先我們不在需要在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呢?因?yàn)槲覀兊那熬Y當(dāng)前的位置就是1,這樣就可以了,我們?cè)L問(wèn)方式二中的那個(gè)地址,會(huì)得到如下結(jié)果:
同樣我們也能得到同樣的結(jié)果,這就是springcloud gateway的簡(jiǎn)單使用,更多配置可以詳看官方文檔,好了,本篇就到這里了...