Dubbo项目双注册中心
🤔为什么要双注册中心?
当前 Dubbo 版本注册粒度是以接口粒度来注册的,而 SpringBoot 是以服务为粒度来注册的。而且 Dubbo 有自己的注册中心(当然 Spring Cloud Alibaba Dubbo 的注册中心可以挂靠在 Spring 上)。所以当一个项目既要调用 Dubbo 服务,又要提供自己的 Web 接口给网关调用时,就要为该项目设置两个注册中心,一个 Dubbo,一个 SpringBoot的(当然可以注册到同一个注册中心上)。
🛠️创建一个 Dubbo 服务提供者
我们先创建一个 Dubbo 服务提供者,然后把它注册到 Zoookeeper 上。我这边用到是 2.7.10
版本到 Dubbo,不同 Dubbo 版本到配置有所差异化。
pom 依赖:
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.10</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.10</version>
<type>pom</type>
</dependency>
然后我们定义一个接口,返回一些文字,记得加上 @DubboService
注解,让 Dubbo 应用发现这个接口并注册到注册 Zookeeper 上。同时在启动类上面还要加上 @EnableDubbo
注解。当然你也可以用配置到方式来配置这些。
@DubboService
public class DemoServiceImpl implements DemoService {
@Override
public String hello() {
return "hello! This is Dubbo's demo";
}
}
定义好接口后,我们在配置文件加上如下配置:
server:
port: 8787
dubbo:
application:
id: dubbo-privode
protocol:
name: dubbo
port: 28808
registry:
address: zookeeper://localhost:2181
在上面配置中,我们定义来项目启动到端口为 8787
,然后配置了 Dubbo 的协议名称和端口,同时也配置了注册地址为本地的 Zookeeper 的地址。
项目启动后,我们就可以看到 Zookeeper 的节点上多了一个 dubbo
节点,节点下面有我们注册上去的 Dubbo 接口
🛠️创建一个服务消费者
消费者基本和服务提供者配置相同,只是要额外加上 web 依赖,应为我们要对外提供 HTTP 接口。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
然后 yml 配置稍作修改,改下端口什么的
server:
port: 8788
dubbo:
application:
id: dubbo-consumer
protocol:
name: dubbo
port: 28808
registry:
address: zookeeper://localhost:2181
配置好后,我们创建一个对外的 HTTP 接口,并且调用上面服务提供者提供的服务,我们可以直接用注解 @DubboReference
来表示我们要调用 Dubbo 服务接口。
@RestController
public class DubboConsumer {
@DubboReference
DemoService demoService;
@GetMapping("/consumer")
public String dubboDemo(){
return demoService.hello();
}
}
启动项目后,注册中心就会出现一个 consumers
节点,这个节点下面有我们注册上去是服务消费者。
这时候我们直接访问 [http://localhost:8788/consumer](http://localhost:8788/consumer)
地址,页面就会响应 hello! This is Dubbo's demo
字符串,这是我们在服务提供者中定义返回的数据,说明我们成功调用了服务提供者提供的 Dubbo 服务。
🔑为消费者再配置一个注册中心
这时候如果我们网关要调用这个消费者提供的 HTTP 接口怎么办?
你可能会想,可以直接把http://localhost:8788/consumer
这个地址配置到网关路由到 uri
字段上。但是我们一般项目不单单是只有一个,而且有时候地址也会变化,这时候网关就要用到服务名来调用对应到服务,网关一般以 lb://service-name
来调用对应到服务。
如果网关想要以服务名来调用这个消费者,那么我们就要以服务名到方式来把这个消费者注册到 Zookeeper 上。
由于 Spring Cloud 官方已经将 Zookeeper 整合进了 Spring Cloud 体系,所以我们可以直接用 Spring Cloud 下的包。需要添加如下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR11</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
同时配置文件需要再添加如下配置,下面的配置中我们指定了要注册到 Zookeeper 到服务名 dubbo-consumer
,配置了注册中心到地址。
spring:
application:
name: dubbo-consumer
cloud:
zookeeper:
connect-string: localhost:2181
同时启动类也要加上 @EnableDiscoveryClient
注解,不然是不会注册到 Zookeeper 上到。
启动项目后,我们就可以在 Zookeeper 的 services
节点下面看到我们的服务了
同样的我们可以看到注册上去到数据:
{
"name": "dubbo-consumer",
"id": "beff8ece-85a3-47ed-bd0b-34fc193eb3f1",
"address": "169.254.238.114",
"port": 8788,
"sslPort": null,
"payload": {
"@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance",
"id": "application-1",
"name": "dubbo-consumer",
"metadata": {
"instance_status": "UP"
}
},
"registrationTimeUTC": 1620123669588,
"serviceType": "DYNAMIC",
"uriSpec": {
"parts": [
{
"value": "scheme",
"variable": true
},
{
"value": "://",
"variable": false
},
{
"value": "address",
"variable": true
},
{
"value": ":",
"variable": false
},
{
"value": "port",
"variable": true
}
]
}
}
🍰网关调用
服务注册上去后,我们就可以修改下我们上节网关项目到路由配置,把它改成用服务名调用。我们可以修改 yml 配置,把 uri
改成服务调用的格式
spring:
cloud:
gateway:
routes:
- id: route-demo
uri: lb://dubbo-consumer
predicates:
- Path=/**
或者如果我们是用 Java 代码方式配置的路由可以改成如下代码:
@Bean
public RouteLocator routesConfig(RouteLocatorBuilder builder){
return builder.routes()
.route("route-demo",r -> r.path("/**").uri("lb://dubbo-consumer"))
.build();
}
修改完成后,启动网关,然后访问网关地址 http://localhost:8080/consumer
就可以看到页面显示 hello! This is Dubbo's demo