`

Dubbo实现RPC调用使用入门

 
阅读更多

转自:http://shiyanjun.cn/archives/341.html

使用Dubbo进行远程调用实现服务交互,它支持多种协议,如Hessian、HTTP、RMI、Memcached、Redis、Thrift等等。由于Dubbo将这些协议的实现进行了封装了,无论是服务端(开发服务)还是客户端(调用服务),都不需要关心协议的细节,只需要在配置中指定使用的协议即可,从而保证了服务提供方与服务消费方之间的透明。
另外,如果我们使用Dubbo的服务注册中心组件,这样服务提供方将服务发布到注册的中心,只是将服务的名称暴露给外部,而服务消费方只需要知道注册中心和服务提供方提供的服务名称,就能够透明地调用服务,后面我们会看到具体提供服务和消费服务的配置内容,使得双方之间交互的透明化。

示例场景

我们给出一个示例的应用场景:
服务方提供一个搜索服务,对服务方来说,它基于SolrCloud构建了搜索服务,包含两个集群,ZooKeeper集群和Solr集群,然后在前端通过Nginx来进行反向代理,达到负载均衡的目的。
服务消费方就是调用服务进行查询,给出查询条件(满足Solr的REST-like接口)。

应用设计

基于上面的示例场景,我们打算使用ZooKeeper集群作为服务注册中心。注册中心会暴露给服务提供方和服务消费方,所以注册服务的时候,服务先提供方只需要提供Nginx的地址给注册中心,但是注册中心并不会把这个地址暴露给服务消费方,如图所示:
provider-registry-consumer
我们先定义一下,通信双方需要使用的接口,如下所示:

01 package org.shirdrn.platform.dubbo.service.rpc.api;
02  
03 public interface SolrSearchService {
04  
05     String search(String collection, String q, ResponseType type, int start, int rows);
06      
07     public enum ResponseType {
08         JSON,
09         XML
10     }  
11 }

基于上图中的设计,下面我们分别详细说明Provider和Consumer的设计及实现。

  • Provider服务设计

Provider所发布的服务组件,包含了一个SolrCloud集群,在SolrCloud集群前端又加了一个反向代理层,使用Nginx来均衡负载。Provider的搜索服务系统,设计如下图所示:
solrcloud-cluster
上图中,实际Nginx中将请求直接转发内部的Web Servers上,在这个过程中,使用ZooKeeper来进行协调:从多个分片(Shard)服务器上并行搜索,最后合并结果。我们看一下Nginx配置的内容片段:

01 user  nginx;
02 worker_processes  4;
03  
04 error_log  /var/log/nginx/error.log warn;
05 pid        /var/run/nginx.pid;
06  
07  
08 events {
09     worker_connections  1024;
10 }
11  
12  
13 http {
14     include       /etc/nginx/mime.types;
15     default_type  application/octet-stream;
16  
17     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
18                       '$status $body_bytes_sent "$http_referer" '
19                       '"$http_user_agent" "$http_x_forwarded_for"';
20  
21     access_log  /var/log/nginx/access.log  main;
22  
23     sendfile        on;
24     #tcp_nopush     on;
25  
26     keepalive_timeout  65;
27  
28     #gzip  on;
29  
30     upstream master {
31         server slave1:8888 weight=1;
32         server slave4:8888 weight=1;
33         server slave6:8888 weight=1;
34     }
35  
36     server {
37         listen 80;
38         server_name master;
39         location / {
40             root /usr/share/nginx/html/solr-cloud;
41             index  index.html index.htm;
42             proxy_pass   http://master;
43             include /home/hadoop/servers/nginx/conf/proxy.conf;
44         }
45     }
46 }

一共配置了3台Solr服务器,因为SolrCloud集群中每一个节点都可以接收搜索请求,然后由整个集群去并行搜索。最后,我们要通过Dubbo服务框架来基于已有的系统来开发搜索服务,并通过Dubbo的注册中心来发布服务。
首先需要实现服务接口,实现代码如下所示:

01 package org.shirdrn.platform.dubbo.service.rpc.server;
02  
03 import java.io.IOException;
04 import java.util.HashMap;
05 import java.util.Map;
06  
07 import org.apache.commons.logging.Log;
08 import org.apache.commons.logging.LogFactory;
09 import org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService;
10 import org.shirdrn.platform.dubbo.service.rpc.utils.QueryPostClient;
11 import org.springframework.context.support.ClassPathXmlApplicationContext;
12  
13 public class SolrSearchServer implements SolrSearchService {
14  
15     private static final Log LOG = LogFactory.getLog(SolrSearchServer.class);
16     private String baseUrl;
17     private final QueryPostClient postClient;
18     private static final Map<ResponseType, FormatHandler> handlers = new HashMap<ResponseType, FormatHandler>(0);
19     static {
20         handlers.put(ResponseType.XML, new FormatHandler() {
21             public String format() {
22                 return "&wt=xml";
23             }
24         });
25         handlers.put(ResponseType.JSON, new FormatHandler() {
26             public String format() {
27                 return "&wt=json";
28             }
29         });
30     }
31      
32     public SolrSearchServer() {
33         super();
34         postClient = QueryPostClient.newIndexingClient(null);
35     }
36      
37     public void setBaseUrl(String baseUrl) {
38         this.baseUrl = baseUrl;
39     }
40  
41     public String search(String collection, String q, ResponseType type,
42             int start, int rows) {
43         StringBuffer url = new StringBuffer();
44         url.append(baseUrl).append(collection).append("/select?").append(q);
45         url.append("&start=").append(start).append("&rows=").append(rows);
46         url.append(handlers.get(type).format());
47         LOG.info("[REQ] " + url.toString());
48         return postClient.request(url.toString());
49     }
50      
51     interface FormatHandler {
52         String format();
53     }
54      
55     public static void main(String[] args) throws IOException {
56         String config = SolrSearchServer.class.getPackage().getName().replace('.''/') + "/search-provider.xml";
57         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
58         context.start();
59         System.in.read();
60     }
61  
62 }

对应的Dubbo配置文件为search-provider.xml,内容如下所示:

01 <?xml version="1.0" encoding="UTF-8"?>
02  
07  
08     <dubbo:application name="search-provider" />
09     <dubbo:registry address="zookeeper://slave1:2188?backup=slave3:2188,slave4:2188" />
10     <dubbo:protocol name="dubbo" port="20880" />
11     <bean id="searchService" class="org.shirdrn.platform.dubbo.service.rpc.server.SolrSearchServer">
12         <property name="baseUrl" value="http://nginx-lbserver/solr-cloud/" />
13     </bean>
14     <dubbo:service interface="org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService" ref="searchService" />
15  
16 </beans>

上面,Dubbo服务注册中心指定ZooKeeper的地址:zookeeper://slave1:2188?backup=slave3:2188,slave4:2188,使用Dubbo协议。配置服务接口的时候,可以按照Spring的Bean的配置方式来配置,注入需要的内容,我们这里指定了搜索集群的Nginx反向代理地址http://nginx-lbserver/solr-cloud/

  • Consumer调用服务设计

这个就比较简单了,拷贝服务接口,同时要配置一下Dubbo的配置文件,写个简单的客户端调用就可以实现。客户端实现的Java代码如下所示:

01 package org.shirdrn.platform.dubbo.service.rpc.client;
02  
03 import java.util.concurrent.Callable;
04 import java.util.concurrent.Future;
05  
06 import org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService;
07 import org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService.ResponseType;
08 import org.springframework.beans.BeansException;
09 import org.springframework.context.support.AbstractXmlApplicationContext;
10 import org.springframework.context.support.ClassPathXmlApplicationContext;
11  
12 import com.alibaba.dubbo.rpc.RpcContext;
13  
14 public class SearchConsumer {
15      
16     private final String collection;
17     private AbstractXmlApplicationContext context;
18     private SolrSearchService searchService;
19      
20     public SearchConsumer(String collection, Callable<AbstractXmlApplicationContext> call) {
21         super();
22         this.collection = collection;
23         try {
24             context = call.call();
25             context.start();
26             searchService = (SolrSearchService) context.getBean("searchService");
27         catch (BeansException e) {
28             e.printStackTrace();
29         catch (Exception e) {
30             e.printStackTrace();
31         }
32     }
33      
34     public Future<String> asyncCall(final String q, final ResponseType type, final int start, final int rows) {
35         Future<String> future = RpcContext.getContext().asyncCall(new Callable<String>() {
36             public String call() throws Exception {
37                 return search(q, type, start, rows);
38             }
39         });
40         return future;
41     }
42      
43     public String syncCall(final String q, final ResponseType type, final int start, final int rows) {
44         return search(q, type, start, rows);
45     }
46  
47     private String search(final String q, final ResponseType type, final int start, final int rows) {
48         return searchService.search(collection, q, type, start, rows);
49     }
50      
51     public static void main(String[] args) throws Exception {
52         final String collection = "tinycollection";
53         final String beanXML = "search-consumer.xml";
54         final String config = SearchConsumer.class.getPackage().getName().replace('.''/') + "/" + beanXML;
55         SearchConsumer consumer = new SearchConsumer(collection, new Callable<AbstractXmlApplicationContext>() {
56             public AbstractXmlApplicationContext call() throws Exception {
57                 final AbstractXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
58                 return context;
59             }
60         });
61          
62         String q = "q=上海&fl=*&fq=building_type:1";
63         int start = 0;
64         int rows = 10;
65         ResponseType type  = ResponseType.XML;
66         for (int k = 0; k < 10; k++) {
67             for (int i = 0; i < 10; i++) {
68                 start = 1 10 * i;
69                 if(i % 2 == 0) {
70                     type = ResponseType.XML;
71                 else {
72                     type = ResponseType.JSON;
73                 }
74 //              String result = consumer.syncCall(q, type, start, rows);
75 //              System.out.println(result);
76                 Future<String> future = consumer.asyncCall(q, type, start, rows);
77 //              System.out.println(future.get());
78             }
79         }
80     }
81 }

查询的时候,需要提供查询字符串,符合Solr语法,例如“q=上海&fl=*&fq=building_type:1”。配置文件,我们使用search-consumer.xml,内容如下所示:

01 <?xml version="1.0" encoding="UTF-8"?>
02  
07  
08     <dubbo:application name="search-consumer" />
09     <dubbo:registry address="zookeeper://slave1:2188?backup=slave3:2188,slave4:2188" />
10     <dubbo:reference id="searchService" interface="org.shirdrn.platform.dubbo.service.rpc.api.SolrSearchService" />
11  
12 </beans>

运行说明

首先保证服务注册中心的ZooKeeper集群正常运行,然后启动SolrSearchServer,启动的时候直接将服务注册到ZooKeeper集群存储中,可以通过ZooKeeper的客户端脚本来查看注册的服务数据。一切正常以后,可以启动运行客户端SearchConsumer,调用SolrSearchServer所实现的远程搜索服务。

参考链接

分享到:
评论

相关推荐

    dubbo相关资料,学习,指南

    有关Dubbo服务框架的简单使用,可以参考我的其他两篇文章(《基于Dubbo的Hessian协议实现远程调用》,《Dubbo实现RPC调用使用入门》,后面参考链接中已给出链接),这里主要围绕Dubbo分布式服务相关配置的使用来说明...

    springboot集成dubbo实现服务提供调用

    在现代微服务架构中,Spring Boot以其简洁的配置和快速的应用开发能力被广泛应用,而Dubbo作为阿里巴巴开源的高性能服务框架,致力于提供高性能和透明化的RPC(远程过程调用)服务。本教程将详细讲解如何将Spring ...

    dubbo从入门到精通教程

    "dubbo从入门到精通教程" dubbo是一种分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案。它是阿里巴巴SOA服务化治理方案的核心框架,每天为2000+个服务提供300000000+次访问量支持,并被广泛应用于...

    dubbo入门示例源码

    总的来说,这个入门示例涵盖了 Dubbo 的基础使用,通过创建服务提供者和消费者,演示了服务的注册、发现和调用过程。对于初学者来说,这是一个很好的起点,后续可以深入学习 Dubbo 的高级特性,如集群、调用链跟踪等...

    Dubbo入门到精通架构高级课程

    - **透明化的RPC调用**:对于开发者而言,使用Dubbo就像调用本地方法一样简单,无需关注底层的网络通信细节。 - **强大的服务治理能力**:提供了服务降级、熔断、限流等机制,有效保障系统的稳定性和可靠性。 #### ...

    Dubbo分布式服务框架入门2

    在这个"Dubbo分布式服务框架入门2"的学习资料中,我们将深入探讨如何在实际开发中使用Dubbo来构建分布式系统。 首先,我们要理解“发布服务”的概念。在第三节(Dubbo发布服务)中,你会了解到如何将一个本地的服务...

    dubbo demo 入门基础

    Dubbo致力于提供高性能和透明化的RPC远程调用服务,以及丰富的服务治理功能。通过这个入门Demo,我们可以学习如何在实际项目中快速启动和使用Dubbo。 【描述】"dubbo入门demo,简单实用,方便理解。idea可直接导入...

    Dubbo入门到精通架构高级课程(视频+课件+源码)

    1. **Dubbo基础**:了解服务提供者和服务消费者的概念,配置Dubbo应用,掌握基本的RPC调用。 2. **服务注册与发现**:学习Zookeeper或Eureka等注册中心的使用,理解服务注册和发现的过程。 3. **负载均衡策略**:...

    dubbo 入门经验 总结

    4. 远程通讯(Remoting):Dubbo提供了多种网络通信框架,如Netty、MINA等,用于服务间的RPC调用。 5. 服务接口(Interface):定义服务的API,通常为Java接口,服务提供者实现该接口并提供服务,服务消费者通过该...

    dubbo入门例子程序

    【Dubbo入门例子程序】是...通过这个【Dubbo入门例子程序】,你可以了解到Dubbo的基本工作原理和使用方法,为进一步学习和实践Dubbo打下基础。同时,这也是理解分布式系统、微服务架构以及RPC通信的一个很好的起点。

    SpringCloud入门 nacos 使用dubbo调用服务

    在本文中,我们将深入探讨如何在Spring Cloud项目中利用Nacos作为服务中心,并使用Dubbo进行服务调用。首先,理解Spring Cloud和Nacos是至关重要的。 **Spring Cloud** 是一个微服务开发工具集,它为开发者提供了在...

    Dubbo入门_实战

    Dubbo是一款由阿里巴巴开发的分布式服务框架,它致力于提供高性能和透明化的RPC远程服务调用方案。该框架是阿里巴巴SOA服务化治理方案的核心组件之一,每天能够为超过2000个服务提供超过3亿次的访问量支持,并广泛...

    dubbo入门例子

    Dubbo是一个高性能、轻量级的开源Java RPC框架,由阿里巴巴开发并维护,它致力于解决因网络异步导致的服务调用问题,提升系统的可扩展性和可维护性。 【描述】中的"一个用spring配置的dubbo的小例子"意味着这个实例...

    dubbo实现demo

    Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了面向接口的远程方法调用能力,使得服务消费方可以像调用本地方法一样调用远程服务。在本示例 "dubbo实现demo" 中,我们可以通过三个关键部分理解其工作...

    dubbo+zookeeper+ssm入门案例

    综合以上分析,这个入门案例将涵盖如何设置Zookeeper服务注册中心,如何使用Dubbo创建服务提供者和服务消费者,以及如何在SSM框架下实现业务逻辑并将其与Dubbo服务集成。学习这个案例,可以帮助开发者深入理解分布式...

    dubbo+zookeeper入门资源

    2. **RPC调用**:Dubbo支持基于接口的远程方法调用,使得调用远程服务如同调用本地方法一样简单。 3. **负载均衡**:在多台服务器之间进行请求分发,如随机、轮询、最少活跃调用数等策略。 4. **服务治理**:包括...

    ssm Dubbo分布式系统架构实战入门,良心详解之作二

    - Dubbo是阿里巴巴开源的高性能RPC框架,用于实现服务间的调用,支持多种通信协议和服务治理功能。 - 服务提供者(Provider):暴露服务的服务提供方。 - 服务消费者(Consumer):调用远程服务的服务消费方。 -...

    Dubbo入门实例Demo

    【Dubbo入门实例Demo】是针对初学者设计的一个实践教程,旨在帮助新手快速理解并掌握Apache Dubbo这一高性能、轻量级的Java RPC框架。在学习过程中,新手往往会在配置、依赖、通信等方面遇到诸多问题,这个Demo就是...

    分布式RPC框架Apache Dubbo

    Apache Dubbo 是一个基于Java的RPC框架,它通过定义服务接口,实现了服务的发布、查找和调用。Dubbo的主要特点包括:高性能NIO通信、动态服务发现、丰富的监控、服务治理等。它旨在提高微服务架构中的服务间通信效率...

    java高级软件工程师教程快速入门Zookeeper+dubbo视频教程

    Dubbo是一款高性能、轻量级的开源Java RPC框架,提供面向接口代理的高性能RPC调用、智能负载均衡、服务自动注册和发现、运行期流量调度、可视化服务治理和运维等功能。 本套课程中,第一阶段深入Zookeeper原理和源码...

Global site tag (gtag.js) - Google Analytics