🤔 why double registry?
The current Dubbo version is registered at interface granularity, while SpringBoot is registered at service granularity. And Dubbo has its own registry (of course Spring Cloud Alibaba Dubbo’s registry can be attached to Spring). So when a project calls both the Dubbo service and provides its own Web interface to the gateway, set up two registries for the project, one for Dubbo and one for SpringBoot (you can register in the same registry, of course).
🛠️ Create a Dubbo service provider
Let’s create a Dubbo service provider and register it with Zoookeeper. I used version 2.7.10 to Dubbo. Different Dubbo versions have different configurations.
Pom depends on:
<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>
Copy the code
Then we define an interface, return some text, annotate @dubboService, and let the Dubbo application find this interface and register it with registered Zookeeper. Also add the @enabledubbo annotation to the bootstrap class. Of course, you can also configure these using configuration to mode.
@DubboService
public class DemoServiceImpl implements DemoService {
@Override
public String hello(a) {
return "hello! This is Dubbo's demo"; }}Copy the code
After defining the interface, we add the following configuration to the configuration file:
server:
port: 8787
dubbo:
application:
id: dubbo-privode
protocol:
name: dubbo
port: 28808
registry:
address: zookeeper://localhost:2181
Copy the code
In the above configuration, we defined the project startup to port 8787, then configured the protocol name and port of Dubbo, and also configured the registered address of the local Zookeeper address.
After the project was started, we could see a New Dubbo node on the Zookeeper node, under which there was the Dubbo interface registered by us
🛠️ create a service consumer
The consumer is basically the same configuration as the service provider, but with an additional Web dependency because we’re going to provide an HTTP interface externally.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Copy the code
And then you change the YML configuration a little bit, you change the port or something
server:
port: 8788
dubbo:
application:
id: dubbo-consumer
protocol:
name: dubbo
port: 28808
registry:
address: zookeeper://localhost:2181
Copy the code
Once configured, we create an external HTTP interface and invoke the service provided by the above service provider. We can directly use the @dubboReference annotation to indicate that we want to invoke the Dubbo service interface.
@RestController
public class DubboConsumer {
@DubboReference
DemoService demoService;
@GetMapping("/consumer")
public String dubboDemo(a){
returndemoService.hello(); }}Copy the code
After starting the project, a Consumers node appears in the registry, under which we register as service consumers.
This time we have direct access to [http://localhost:8788/consumer] (http://localhost:8788/consumer) address, the page will respond to hello! This is Dubbo’s demo string, which is the data returned by our definition in the service provider, indicating that we successfully invoked the Dubbo service provided by the service provider.
🔑 configure another registry for consumers
What if our gateway wants to invoke the HTTP interface provided by the consumer?
You might think, can be directly to http://localhost:8788/consumer this is the configuration to the gateway address routing to the uri field. However, we usually have not only one project, and sometimes the address will change, so the gateway will use the service name to call the corresponding service, and the gateway usually uses lb://service-name to call the corresponding service.
If the gateway wants to invoke the consumer with the service name, we register the consumer with Zookeeper as the service name.
Since Spring Cloud has officially integrated Zookeeper into the Spring Cloud system, we can directly use the package under Spring Cloud. The following dependencies need to be added:
<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>
Copy the code
At the same time, the following configuration needs to be added to the configuration file. In the following configuration, we specify to register with Zookeeper to the service name dubbo-consumer, and configure the registry to the address.
spring:
application:
name: dubbo-consumer
cloud:
zookeeper:
connect-string: localhost:2181
Copy the code
At the same time, the startup class must be annotated with @enableDiscoveryClient, otherwise it will not be registered with Zookeeper.
After starting the project, we can see our service under the Services node of Zookeeper
Similarly, we can see the registration data:
{
"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}}}]Copy the code
🍰 Gateway Call
Once the service is registered, we can modify the gateway project to route configuration in the previous section to call it with the service name. We can modify the YML configuration to change the URI to the format of the service invocation
spring:
cloud:
gateway:
routes:
- id: route-demo
uri: lb://dubbo-consumer
predicates:
- Path=/**
Copy the code
Or if we configured the route in Java code, we can change it to the following code:
@Bean
public RouteLocator routesConfig(RouteLocatorBuilder builder){
return builder.routes()
.route("route-demo",r -> r.path("/ * *").uri("lb://dubbo-consumer"))
.build();
}
Copy the code
Modification is finished, start the gateway, and then access gateway address http://localhost:8080/consumer can see page hello! This is Dubbo’s demo