本文将介绍怎样使用Dubbo的API去暴露和调用远程服务。下图是项目在IDEA中的项目结构图:
本项目总共有三个子模块,分别为 dubbo-api(定义服务的接口)、dubbo-provider(实现服务接口,然后将服务暴露出来)和 dubbo-consumer(服务消费者,消费dubbo-provider暴露出来的服务)
该子模块依赖 dubbo-api 子模块,实现了 dubbo-api 中定义的服务接口。项目结构如下图:
HelloServiceImpl.java
package com.huangx.dubbo.provider; import com.alibaba.dubbo.config.annotation.Service; import com.huangx.dubbo.hello.HelloService; import com.alibaba.dubbo.rpc.RpcContext; import java.text.SimpleDateFormat; import java.util.Date; /** * 服务实现 */ @Service(version = "1.0.0") public class HelloServiceImpl implements HelloService { public String sayHello(String name) { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); System.out.println("[" + sdf.format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } }
上面代码简单的实现了 dubbo-api 定义的服务。
Provider.java
package com.huangx.dubbo.provider; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.alibaba.dubbo.config.ServiceConfig; import com.huangx.dubbo.hello.HelloService; /** * 加载 Spring 的配置文件,启动 Dubbo 服务提供者 */ public class Provider { public static void main(String[] args) throws Exception { // 服务实现 HelloService helloService = new HelloServiceImpl(); // 当前应用配置 ApplicationConfig application = new ApplicationConfig(); application.setName("demo-provider"); // 连接注册中心配置 RegistryConfig registry = new RegistryConfig(); registry.setProtocol("zookeeper"); registry.setAddress("127.0.0.1:2181"); // 服务提供者协议配置 ProtocolConfig protocol = new ProtocolConfig(); protocol.setName("dubbo"); protocol.setPort(12345); protocol.setThreads(20); // 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口 // 服务提供者暴露服务配置 // 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏 ServiceConfig<HelloService> service = new ServiceConfig<HelloService>(); service.setApplication(application); service.setRegistry(registry); // 多个注册中心可以用setRegistries() service.setProtocol(protocol); // 多个协议可以用setProtocols() service.setInterface(HelloService.class); service.setRef(helloService); service.setVersion("1.0.0"); // 暴露及注册服务 service.export(); // 按任意键退出 System.in.read(); } }
上面代码分为:
创建 ApplicationConfig 应用配置
创建 RegistryConfig 注册配置
创建 ProtocolConfig 服务协议
创建 ServiceConfig 服务配置(一个服务需要包含 ApplicationConfig、RegistryConfig 和 ProtocolConfig )
该子模块也依赖 dubbo-api 模块,根据服务接口调用远程实现(dubbo-provider暴露的服务)。项目结构如下图:
Consumer.java
package com.huangx.dubbo.consumer; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ReferenceConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.huangx.dubbo.hello.HelloService; /** * 加载 Spring 配置,启动 Dubbo 服务消费者 */ public class Consumer { public static void main(String[] args) { // 当前应用配置 ApplicationConfig application = new ApplicationConfig(); application.setName("demo-consumer"); // 连接注册中心配置 RegistryConfig registry = new RegistryConfig(); registry.setProtocol("zookeeper"); registry.setAddress("127.0.0.1:2181"); // 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接引用远程服务 // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 ReferenceConfig<HelloService> reference = new ReferenceConfig<HelloService>(); reference.setApplication(application); reference.setRegistry(registry); // 多个注册中心可以用setRegistries() reference.setInterface(HelloService.class); reference.setVersion("1.0.0"); // 和本地bean一样使用xxxService // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用 HelloService helloService = reference.get(); while(true) { String result = helloService.sayHello("hello"); System.out.println(result); } } }