- Dubbo应用
- Triple协议的流式调用
- 跨语言调用
- 与gRPC互通
- 与Spring Cloud互通
Dubbo应用
- 增加依赖
dubbo-spring-boot-starter
dubbo-rpc-dubbo
dubbo-rpc-rest
兼容 rest 协议,支持 http 调用
dubbo-rpc-triple
dubbo-registry-zookeeper
- 配置文件
dubbo.application.name=provider-application
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.protocols.p2.name=rest
dubbo.protocols.p2.port=8082
dubbo.registry.address=zookeeper://127.0.0.1:2181
@EnableDubbo(scanBasePackages = "com.xx.service")
开启
@DubboService
提供服务
- 如果一个service接口名在多个不同的应用上定义了,dubbo只能注册一个
- 返回的实体类需要实现 Serializable 接口,否则报错
- 兼容 rest 协议
@Path("/user")
指定 url(类和方法都要标注)
@Produces(MediaType.APPLICATION_JSON)
方法返回 json 类型数据
- 类上也要标注
@Produces
@DubboReference
引入一个 Dubbo 服务
Triple协议的流式调用
- Triple 协议的 Stream 对于消费者来说是阻塞的
- 生产者可以onNext分批发送,但是消费者按照发送顺序全部接收完后,才能分批处理,而不是即时处理
- grpc 可以即时处理
- UNARY,就是正常的调用方法
- SERVER_STREAM
public void sayHelloServerStream(String name, StreamObserver<String> response) {
response.onNext(name + " hello");
response.onNext(name + " world");
response.onCompleted();
}
@DubboReference
private UserService userService;
userService.sayHelloServerStream("zhouyu", new StreamObserver<String>() {
@Override
public void onNext(String data) {
System.out.println(data);
}
@Override
public void onError(Throwable throwable) {}
@Override
public void onCompleted() {
System.out.println("complete");
}
});
- CLIENT_STREAM
- BI_STREAM 和 CLIENT_STREAM 一样
public StreamObserver<String> sayHelloStream(StreamObserver<String> response) {
return new StreamObserver<String>() {
@Override
public void onNext(String data) {
response.onNext("result:" + data);
}
@Override
public void onError(Throwable throwable) {}
@Override
public void onCompleted() {
System.out.println("completed");
}
};
}
@DubboReference
private UserService userService;
StreamObserver<String> streamObserver = userService.sayHelloStream(new StreamObserver<String>() {
@Override
public void onNext(String data) {
System.out.println("接收到响应数据:"+ data);
}
@Override
public void onError(Throwable throwable) {}
@Override
public void onCompleted() {
System.out.println("接收到响应数据完毕");
}
});
streamObserver.onNext("request zhouyu hello");
streamObserver.onNext("request zhouyu world");
streamObserver.onCompleted();
跨语言调用
- 与Java实现的Dubbo服务互调的条件
- 该语言有 Dubbo 框架可以用
- 使用 protobuf 技术,并且需要 protobuf 也支持该语言
userservice.proto
syntax = "proto3";
package api;
option go_package = "./;api";
option java_multiple_files = true;
option java_package = "com.xx";
option java_outer_classname = "UserServiceProto";
service UserService {
rpc GetUser (UserRequest) returns (User) {}
}
// The response message containing the greetings
message UserRequest {
string uid = 1;
}
// The response message containing the greetings
message User {
string uid = 1;
string username = 2;
}
- 编译成 Java:
maven -> compile
@DubboService
标注 UserService 的实现类
- 编译成 go
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
go get -u github.com/dubbogo/tools/cmd/protoc-gen-go-triple
go install github.com/golang/protobuf/protoc-gen-go
go install github.com/dubbogo/tools/cmd/protoc-gen-go-triple
protoc -I. userservice.proto --go_out=../api --go-triple_out=../api
go mod tidy
- 然后就可以写 go 语言的服务消费者了
- 新建
conf/dubbogo.yml
,用来配置注册中心
Triple与gRPC互通
- tri 协议在发送请求和发送响应时,都是按照grpc的格式来发送的
- gRPC 可以直接调 tri 协议的 Dubbo
- Dubbo 调用 gRPC 服务
@DubboReference(protocol = "tri", url = "tri://localhost:8008",
proxy = CommonConstants.NATIVE_STUB)
private UserService userService;
与Spring Cloud互通
- 要调用Spring Cloud的服务,得用http协议
- 用tri协议去调用另外一个服务时,并不能去指定controller地址,得用rest协议,底层也是http协议
- 指定controller地址
@Path("/")
@Consumes
public interface HelloService {
@GET @Path("hello")
String hello();
}
@DubboReference(url = "rest://localhost:7070", protocol = "rest")
private HelloService helloService;
- 如果Dubbo服务支持rest协议调用
- SpringCloud应用就不需要引入Dubbo的依赖,直接使用Feign就可以完成调用
- 其他情况要引入Dubbo依赖通过
@DubboReference
来使用
@DubboService(protocol = "rest")
@Produces @Path("/")
public class HelloServiceImpl implements HelloService{
@Override
@GET @Path("hello")
public String hello() {
return "dubbo hello";
}
}
@FeignClient(name = "dubbo-provider-application", url = "localhost:20881")
public interface HelloService {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello();
}