0. 引言
上次我们讲到使用zookeeper作为注册中心搭建dubbo微服务框架,但是我们还缺少一个服务总入口,也就是我们的网关服务。所以今天我们的目标就是给dubbo框架搭建一个网关。dubbo框架体系一般是结合nginx来作为网关的,但有时我们需要在网关拓展集成更多的功能,nginx可能无法满足,这是就可以结合springcloud gateway来实现
如果还不了解网关是什么的,可以先阅读我之前的博客
dubbo+zookeeper+springcloud gateway是否可行?
因为很多企业在使用dubbo框架时都默认用zk来作为注册中心,很多小伙伴在集成网关时可能就想在dubbo+zk的基础上,集成gateway是否可行。
但实际上dubbo与gateway在使用zk时会出现冲突,从而导致使用报错,所以一般我们更加建议dubbo+zk+nginx,dubbo+nacos+gateway的组合方案
1. 集成gateway网关
1.1 实操步骤
因为之前我们已经讲解过spring cloud gateway组件的基本使用了,所以这次我们直接上手搭建网关
同时此次实操基于上次搭建的项目dubbo_wu_demo
进行,参考:
dubbo整合nacos实现服务注册中心、配置中心(二)
1、首先我们需要创建一个springboot项目gateway
2、引入依赖
因为要引入springcloud gateway,所以我们现在根pom.xml里添加spring-cloud-dependencies
的版本声明,这样引入gateway时就不用单独申明版本了
<properties>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
在gateway项目pom中添加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
注意这里不需要再引入spring-web
依赖了,否则会因为冲突导致启动报错,spring-cloud-starter-gateway
依赖中已经包含了spring-boot-starter-webflux
,可以用于web容器启动
3、修改配置文件
server:
port: 9090
spring:
cloud:
nacos:
discovery:
username: nacos
password: nacos
server-addr: localhost:8848
# 命名空间ID,默认为public命名空间,省略不写,命名空间ID在nacos-命名空间页面可以看到
namespace:
gateway:
discovery:
locator:
enabled: true # 启用从服务发现中获取路由,默认按照服务名转发
4、gateway启动类添加上@EnableDiscoveryClient
注释
5、因为服务都是基于springcloud的形式进行转发的,所以需要在之前创建user-server-nacos和order-server-nacos项目中添加上nacos discovery的配置,在项目资源目录下添加配置文件bootstrap.yaml
,内容如下:
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
# 命名空间ID,默认为public命名空间,省略不写,命名空间ID在nacos-命名空间页面可以看到
namespace:
username: nacos
password: nacos
# 文件名 如果没有配置则默认为服务名,即spring.appliction.name
prefix: order-server-nacos
#指定文件后缀,默认properties
file-extension: yaml
discovery:
username: nacos
password: nacos
server-addr: localhost:8848
# 如果是public就不用填写了
namespace:
6、为了方便测试,我们在order-server-nacos和user-server-nacos服务中都添加一个测试接口
@Value("${server.port}")
private Integer port;
@Value("${spring.application.name}")
private String serverName;
@GetMapping("test")
public String test(){
return "调用服务" + serverName + ",端口:"+port;
}
6、启动3个项目,通过gateway转发order-server-nacos, 即访问http://localhost:9090/order-server-nacos/test
,如下图,可以看到正常转发了
1.2 dubbo提供者注册到nacos出现两个实例的问题
但是在转发http://localhost:9090/user-server-nacos/test
时出现了报错IllegalArgumentException: invalid version format: UNSUPPORTED
然后二次访问又正常了
该问题的原因是因为user-server-nacos作为dubbo服务提供者,实际上在nacos有两种注册服务,在nacos管理端可以看到其实例:
第二种是springcloud形式注册到nacos的,第一种是dubbo形式注册到nacos, 很明显转发失败的就是转发到第一种上了
那么该问题该怎么解决呢?
因为该问题是因为dubbo注册服务和springcloud注册服务之间导致的冲突,相当于两个注册到一起了,形成了两个实例,那么思路就是让他们不要注册到一起。于是有两种解决方案:
- 方案一:让dubbo服务名和springcloud服务名不一致
这个方式是最简单的,就是让spring.application.name和dubbo.application.name配置的服务名不要一样即可,这个就更改下配置文件即可
重启服务,可以看到服务示例分隔开了,gateway也正常了
- 方案二:让dubbo和springcloud的nacos中的namespace不一致
我们之前在讲解nacos实现环境隔离时也说明过可以使用namespace来区分,那么这里也一样,我们可以定义不同的namespace,以此让其实例分隔开
可参考:springcloud gateway + nacos访问微服务出现invalid version format: UNSUPPORTED
(1)nacos新建一个namespace
(2)复制其ID, 填写到配置bootstrap.yaml
文件中(也可以选择更改dubbo.registry.parameters.namespace
),注意这里不是填写命名空间名,而是其ID
同时gateway、order-server-nacos其他服务的namespace也要更改,不然因为不统一也会导致找不到服务
调整后访问正常
2. 源码
文中源码,可在https://gitee.com/wuhanxue/dubbo_wu_demo下载
3. 总结
至此,我们结合gateway实现的网关就搭建完成了, 如果要实现限流、自定义路由、过滤器等各种网关操作,大家可以结合文章开头列出的gateway组件详解一文