翻译-Your first Dubbo application

Your-First-Dubbo-Demo

Your First Dubbo Demo

Java RMI Introduction(RMI简介)

RMI是一种机制,允许访问或者调用另一台JVM上的对象或者方法。RMI是一种特殊的RPC,使用了支持OOP的java语言来实现。用户可以不经过IDL(Interface Define Language)就可以建造分布式的应用,依赖于轻松自然的接口的方式。

Java RMI Work Flow(RMI工作流程)

  1. 服务端向RMI登记服务并绑定接口;
  2. 客户端向RMI等级服务并获取远程接口;
  3. 客户端调用本地存根对象的方法,就像调用本地其他对象的那样;
  4. 本地存根对象压缩请求信息,并通过网络将之发送到服务端;
  5. 服务端的框架代码接受到了网络请求,并将之解压缩。
  6. 服务端根据请求的信息调用目标对象的方法,并且将结果压缩并通过网络返回给客户端。

image

RMI的一些概念

java RMI是java领域创建分布式应用的技术基石。EJB技术和当前分布式服务的框架依然继承着java RMI的基本概念。在RMI的调用中,有以下几个核心概念:

  1. 远程调用依赖于接口
  2. 将远程调用伪装成本地调用,在客户端叫做Stub object ,在服务端叫做Skeleton object
  3. 服务在RMI注册中心被注册和发现。
    对于第一点:客户端依赖的接口应当被服务端实现。
    对于第二点:在J2SE 1.5及之前,客户端和服务器需要通过rmic来预编译Stub objectSkeleton object。之后的版本就不需要这么做了。

代码示例:

Server service registry
// 初始化服务实例
Hello obj = new HelloImpl(); 
// 创建存根对象
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0); // #2
// 创建注册服务
Registry registry = LocateRegistry.createRegistry(1099); // #3
// 注册并绑定存根对象,客户端即可以通过Hello来找到服务
registry.rebind("Hello", stub); // #4
Client service look-up
// 获取注册中心实例
Registry registry = LocateRegistry.getRegistry(); 
// 寻找名字叫Hello的那个服务实例
Hello stub = (Hello) registry.lookup("Hello");
// 调用RMI远程调用
String response = stub.sayHello(); 

理解RMI的工作流程和基础概念是非常有帮助的,对于当前的分布式服务框架。
推荐阅读RMI 官方文档来获取等多的信息。

Basic Concepts of Dubbo(dubbo的基本概念)

目前分布式服务框架的基本概念和RMI是类似的。他们都使用java 接口作为服务契约,通过注册中心来注册和查询,使用代理隐藏了远程通信的细节。特别的,当Dubbo运行的时候有以下四种类型的角色

  • 服务提供者,初始化的时候在指定端口暴露服务,在注册中心注册服务的地址和端口。
  • 服务消费者,初始化的时候在注册中心订阅自己感兴趣的服务,获取服务提供商的地址列表
  • 注册中心,注册和查找服务。存储服务提供者的地址,并将之发送给消费者。
  • 监控中心,收集并监控服务提供者和消费者的运行状态,调用次数,调用延迟等。
  • 运行容器,初始化并且加载服务提供者,管理运行周期。

image

部署阶段
  • 初始化的时候在指定端口暴露服务,在注册中心注册服务的地址和端口。
  • 初始化的时候在注册中心订阅自己感兴趣的服务,获取服务提供商的地址列表

    运行阶段
  • 注册中心将地址发送给服务消费者;
  • 接收到地址列表后,服务消费者选择出其中的一个并调用。
  • 调用期间,服务提供者和消费者的运行状态被发送给监控中心。

Dubbo Applications Based on API

Dubbo通常由spring组装起来。为了快速创建一个Dubbo应用的话,这里的这个例子放弃了复杂的配置,以面向Dubbo Api的方式创建了服务提供者和服务消费者。另外,本例子中不需要安装或者配置注册中心和监控中心。

在生产环境中,Dubbo服务通常需要和分布式服务注册中心配合起来,比如zookeeper。出于方便的考虑,dubbo提供了俩种方式来避免额外的关于建构注册中心的工作,分别是【namely direct connection】和【assembled podcast】。
本例中使用了后者来注册和查找服务。

Define Service Contract(定义服务契约)
public interface GreetingsService {
    String sayHi(String name); // #1
}

定义了一个简单的服务契约,仅仅只有一个方法【sayHi】会被调用。
入参和返回值都是string类型的。
Provide Contract Implementation(提供契约实现)
public class GreetingsServiceImpl implements GreetingsService { // #1
    @Override
    public String sayHi(String name) {
        return "hi, " + name; // #2
    }
}
服务提供者需要实现服务契约的接口【GreetingsService】。
Implement Dubbo Service Provider(实现服务提供者)
public class Application {
    public static void main(String[] args) throws IOException {
        // 创建一个ServiceConfig 实例,类型是GreetingsService
        ServiceConfig<GreetingsService> service = new ServiceConfig<>(); 
        // 创建一个ApplicationConfig 实例,并将之组装到ServiceConfig实例中
        service.setApplication(new ApplicationConfig("first-dubbo-provider"));
        // 创建一个RegistryConfig 实例,并将之组装到ServiceConfig实例中。
        // 因为注册中心使用的是上文提到的第二种方案,所以参数应该是【multicast://224.5.6.7:1234】
        // 有效的assembled地址范围是224.0.0.0 - 239.255.255.255
        service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234")); 
        // 将服务契约GreetingsService 组装到ServiceConfig实例中
        service.setInterface(GreetingsService.class); 
        // 将服务提供者提供的GreetingsServicelmpl实例组装到ServiceConfig实例中
        service.setRef(new GreetingsServiceImpl()); 
        // 装配好足够的信息后,ServiceConfig实例开始将自己暴露在默认的端口20880。
        service.export();
        // 按任意键或ctrl-c退出以避免服务器停止。
        System.in.read(); 
    }
}
Implement Dubbo Service Consumer(实现dubbo的服务消费者)
public class Application {
    public static void main(String[] args) {
        // 创建一个指定类型为GreetingsService的ReferenceConfig 实例
        ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>(); // #1
        // AplicatonConfig实例
        reference.setApplication(new ApplicationConfig("first-dubbo-client")); // #2
        // 创建RegistryConfig实例,地址必须和服务提供者一样
        reference.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234")); // #3
        reference.setInterface(GreetingsService.class); // #4
        // 从ReferenceConfig中获得一个GreetingsService的代理
        GreetingsService greetingsService = reference.get(); // #5
        // 通过GreetingsService代理执行远程调用
        String message = greetingsService.sayHi("dubbo"); // #6
        System.out.println(message); // #7
    }
}

run (运行这个例子)

完整的例子可以从 https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-api中获得。通过maven或者直接使用ide都可以很方便运行这个例子。一个值得注意的是:因为使用了委派的方式来查找服务,运行的时候需要加上【-Djava.net.preferIPv4Stack=true】。

Build Example(构造实例代码)
  1. 下载代码:git clone https://github.com/dubbo/dubbo-samples.git
  2. Build:mvn clean package
$ git clone https://github.com/dubbo/dubbo-samples.git
$ cd dubbo-samples/dubbo-samples-api/
$ mvn clean package
INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building dubbo-samples-api 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ dubbo-samples-api ---
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.182 s
[INFO] Finished at: 2018-05-28T14:56:08+08:00
[INFO] Final Memory: 20M/353M
[INFO] ------------------------------------------------------------------------
Run the server(运行服务)
$ mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building dubbo-samples-api 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ dubbo-samples-api ---
log4j:WARN No appenders could be found for logger (org.apache.dubbo.common.logger.LoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
first-dubbo-provider is running.
Run the server(运行客户端)
$ mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.consumer.Application exec:java
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building dubbo-samples-api 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ dubbo-samples-api ---
log4j:WARN No appenders could be found for logger (org.apache.dubbo.common.logger.LoggerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
hi, dubbo

Quick Creation of A Dubbo Application

http://start.dubbo.io下载(跟spring.io下载boot项目类似)

Summary

后续教程

Dubbo user manual

Dubbo developer guide

Dubbo admin manual

猜你喜欢

转载自www.cnblogs.com/po-shi/p/11236697.html