Quick Start

Dubbo!用更优雅的方式来实现RPC调用吧 - 掘金

dubbo+zookeeper demo

项目结构:

RpcService

仅仅是提供服务的接口:

public interface HelloService {

String sayHello(String name);

}

DubboServer

pom:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.5.5

com.example

DubboServer

0.0.1-SNAPSHOT

DubboServer

DubboServer

8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

com.alibaba.boot

dubbo-spring-boot-starter

0.2.0

com.alibaba

dubbo

2.6.5

com.alibaba.spring

spring-context-support

1.0.2

org.apache.zookeeper

zookeeper

3.4.12

com.example

RpcService

0.0.1-SNAPSHOT

compile

org.springframework.boot

spring-boot-maven-plugin

org.apache.maven.plugins

maven-compiler-plugin

3.2

1.8

1.8

UTF-8

compile

compile

DubboServerApplication:

package com.example.dubboserver;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

@EnableDubbo(scanBasePackages = {"com.example.dubboserver"})

public class DubboServerApplication {

public static void main(String[] args) {

SpringApplication.run(DubboServerApplication.class, args);

}

}

HelloServiceImpl实现dubbo服务:

package com.example.dubboserver;

import com.alibaba.dubbo.config.annotation.Service;

import com.example.rpcservice.HelloService;

import org.springframework.stereotype.Component;

@Component

@Service

public class HelloServiceImpl implements HelloService {

@Override

public String sayHello(String name) {

return "hello " + name + "!";

}

}

配置文件application.yaml:

dubbo:

application:

name: example-provider

registry:

address: zookeeper://43.143.229.22:2181

protocol:

name: dubbo

port: 20880

zookeeper是我的一台云服务器,zookeeper需要先部署好。

DubboClient

pom文件与Server相似:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.5.5

com.example

DubboClient

0.0.1-SNAPSHOT

DubboClient

DubboClient

8

com.example

RpcService

0.0.1-SNAPSHOT

compile

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

com.alibaba.boot

dubbo-spring-boot-starter

0.2.0

com.alibaba

dubbo

2.6.5

com.alibaba.spring

spring-context-support

1.0.2

org.apache.zookeeper

zookeeper

3.4.12

org.springframework.boot

spring-boot-maven-plugin

DubboClientApplication:

package com.example.dubboclient;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

@EnableDubbo(scanBasePackages = {"com.example.dubboclient"})

public class DubboClientApplication {

public static void main(String[] args) {

SpringApplication.run(DubboClientApplication.class, args);

}

}

RpcService:

package com.example.dubboclient;

import com.alibaba.dubbo.config.annotation.Reference;

import com.example.rpcservice.HelloService;

import org.springframework.stereotype.Service;

@Service

public class RpcService {

@Reference

private HelloService helloService;

public String getHelloServiceResponse(String name) {

return helloService.sayHello(name);

}

}

通过Reference注解标识这是一个dubbo服务接口。

TriggerController:(通过get方法触发dubbo调用,debug用)

package com.example.dubboclient;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("/demo/dubbo")

public class TriggerController {

@Autowired

private RpcService rpcService;

@GetMapping("/{name}")

public String getTime(@PathVariable("name") String name) {

return rpcService.getHelloServiceResponse(name);

}

}

配置文件:

server:

port: 8081

dubbo:

application:

name: example-consumer

registry:

address: zookeeper://43.143.229.22:2181

client: curator

protocol:

name: dubbo

server: false

consumer:

timeout: 3000

dubbo使用nacos作为注册中心

dubbo也可以用nacos作为注册中心。使用docker一键启动nacos2: docker run --name nacos-quick -e MODE=standalone -p 8848:8848 -p 9848:9848 -p 9849:9849 -d nacos/nacos-server:2.0.2 ,如果是部署在云服务器上的话记得防火墙暴露接口。

client和server的代码与上面zookeeper的一致,但是依赖和配置换了,依赖采用alibaba-spring-cloud来提供。这里我为了方便没有创建父项目写dependencyManagement,而是直接在子项目写来管理包版本,这种做法不是很规范。

Server

pom.xml:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.6.3

com.example

DubboServer

0.0.1-SNAPSHOT

DubboServer

DubboServer

2021.0.1.0

2021.0.1

org.springframework.cloud

spring-cloud-dependencies

${spring-cloud.version}

pom

import

com.alibaba.cloud

spring-cloud-alibaba-dependencies

${spring-cloud-clibaba.version}

pom

import

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-config

com.alibaba.cloud

spring-cloud-starter-dubbo

com.example

RpcService

0.0.1-SNAPSHOT

compile

org.springframework.boot

spring-boot-maven-plugin

org.apache.maven.plugins

maven-compiler-plugin

3.2

1.8

1.8

UTF-8

compile

compile

application.yaml:

spring:

main:

# spring boot 2.6.3默认不允许循环依赖, dubbo的这个版本存在循环依赖

allow-circular-references: true

application:

name: demo-server

cloud:

nacos:

config:

enable: false

discovery:

server-addr: 123.56.98.228:8848

namespace: public

dubbo:

consumer:

retries: 5

protocol:

port: -1

name: dubbo

scan:

# 扫描实现类的包路径(可配置多个或数组)

base-packages: com.example.dubboserver # 更改为自己dubbo实现类的路径

registry:

address: nacos://${spring.cloud.nacos.discovery.server-addr}?namespace=${spring.cloud.nacos.discovery.namespace}

cloud:

# 默认*订阅所有, 所以在此处写一个不存在的提供者

# (可订阅多个用,隔开或者用数组的配置方式 -: name)

subscribed-services: "-"

client

pom.xml:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.6.3

com.example

DubboClient

0.0.1-SNAPSHOT

DubboClient

DubboClient

2021.0.1.0

2021.0.1

org.springframework.cloud

spring-cloud-dependencies

${spring-cloud.version}

pom

import

com.alibaba.cloud

spring-cloud-alibaba-dependencies

${spring-cloud-clibaba.version}

pom

import

com.example

RpcService

0.0.1-SNAPSHOT

compile

org.springframework.boot

spring-boot-starter-web

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-config

com.alibaba.cloud

spring-cloud-starter-dubbo

org.springframework.boot

spring-boot-maven-plugin

application.yaml:

spring:

main:

# spring boot 2.6.3默认不允许循环依赖, dubbo的这个版本存在循环依赖

allow-circular-references: true

application:

name: demo-client

cloud:

nacos:

config:

enable: false

discovery:

server-addr: 123.56.98.228:8848

namespace: public

dubbo:

consumer:

retries: 5

protocol:

port: -1

name: dubbo # 协议名称

测试

先上nacos看看服务 ip:8848/nacos:

其中有一个是dubbo自己的服务,剩下三个一个是client应用,一个是server应用,一个是暴露的RpcService服务。

浏览器输入:http://localhost:8080/demo/dubbo/dsasdfaasdf

响应:

没啥问题。

dubbo泛化调用

dubbo泛化调用即在调用方不引入服务方接口包的情况下直接调用服务接口。

适用场景:

比如你做了一个网关项目,网关需要调用后端的多个服务的多个接口,这些接口假如都是dubbo,网关需要引入所有服务的接口包才能调用,这显然不太合理,网关的代码应该和后端服务解耦。

那如何实现泛化调用呢?

服务方不需要更改配置。调用方更改rpc调用的代码。

不使用泛化调用的代码:

@Service

public class RpcService {

@Reference

private HelloService helloService; // 普通调用

public String getHelloServiceResponse(String name) {

return helloService.sayHello(name); // 普通调用

}

}

改为泛化调用:

@Service

public class RpcService {

@DubboReference(interfaceName = "com.example.rpcservice.HelloService", generic = true)

private GenericService genericService;

public String getHelloServiceResponse(String name) {

Object res = genericService.$invoke("sayHello" , new String[]{"java.lang.String"},

new Object[]{name});

return (String) res;

}

}

可以看到将原本的具体的Service接口改为了GenericService, @DubboReference中写明了调用的接口全限定名称,并且generic打开为true。

至此完成泛化调用改动,还是挺简单的。

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: