加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 运营中心 > 网站设计 > 教程 > 正文

一文详细解读 Dubbo 中的 Http 协议

发布时间:2019-10-15 07:07:50 所属栏目:教程 来源:儒雅程序员
导读:副标题#e# 太阳红彤彤,花儿五颜六色,各位读者朋友好,又来到了分享 Dubbo 知识点的时候了。说到 Dubbo 框架支持的协议,你的第一反应是什么?大概会有 Dubbo 默认支持的 dubbo 协议,以及老生常谈的由当当贡献给 Dubbo 的 rest 协议,或者是今天的主角 htt
副标题[/!--empirenews.page--]

太阳红彤彤,花儿五颜六色,各位读者朋友好,又来到了分享 Dubbo 知识点的时候了。说到 Dubbo 框架支持的协议,你的第一反应是什么?大概会有 Dubbo 默认支持的 dubbo 协议,以及老生常谈的由当当贡献给 Dubbo 的 rest 协议,或者是今天的主角 http。截止到目前,Dubbo 最新版本演进到了 2.7.3,已经支持了:dubbo,hessain,http,injvm,jsonrpc,memcached,native-thrift,thrift,redis,rest,rmi,webservice,xml 等协议,有些协议的使用方式还没有补全到官方文档中。原来 Dubbo 支持这么多协议,是不是有点出乎你的意料呢?

一文详细解读 Dubbo 中的 Http 协议

这么多 RPC 协议,可能有人会产生如下的疑问:rest,jsonrpc,webservice 不都是依靠 http 通信吗?为什么还单独有一个 http 协议?先不急着回答这个问题,而是引出今天的话题,先来介绍下 Dubbo 框架中所谓的 http 协议。

Dubbo 中的 http 协议

在 Dubbo 使用 http 协议和其他协议基本一样,只需要指定 protocol 即可。

  1. <dubbo:protocol name="http" port="8080" server="jetty" /> 

server 属性可选值:jetty,tomcat,servlet。

配置过后,当服务消费者向服务提供者发起调用,底层便会使用标准的 http 协议进行通信。可以直接在 https://github.com/apache/dubbo-samples 中找到官方示例,其中的子模块:dubbo-samples-http 构建了一个 http 协议调用的例子。

为避免大家误解,特在此声明:本文中,所有的 http 协议特指的是 dubbo 中的 http 协议,并非那个大家耳熟能详的通用的 http 协议。

http 协议的底层原理

从默认的 dubbo 协议改为 http 协议是非常简单的一件事,上面便是使用者视角所看到的全部的内容了,接下来我们将会探讨其底层实现原理。

翻看 Dubbo 的源码,找到 HttpProtocol 的实现,你可能会吃惊,基本就依靠 HttpProtocol 一个类,就实现了 http 协议

一文详细解读 Dubbo 中的 http 协议

要知道实现自定义的 dubbo 协议,有近 30 个类!http 协议实现的如此简单,背后主要原因有两点:

  • remoting 层使用 http 通信,不需要自定义编解码
  • 借助了 Spring 提供的 HttpInvoker 封装了 refer 和 exporter 的逻辑

Spring 提供的 HttpInvoker 是何方神圣呢?的确是一个比较生僻的概念,但并不复杂,简单来说,就是使用 Java 序列化将对象转换成字节,通过 http 发送出去,在 server 端,Spring 能根据 Url 映射,找到容器中对应的 Bean 反射调用的过程,没见识过它也不要紧,可以通过下面的示例快速掌握这一概念。

Spring HttpInvoker

本节内容可参见 Spring 文档:https://docs.spring.io/spring/docs/4.3.24.RELEASE/spring-framework-reference/htmlsingle/#remoting-httpinvoker-server

下面的示例将会展示如何使用 Spring 原生的 HttpInvoker 实现远程调用。

创建服务提供者

  1. public class AccountServiceImpl implements AccountService { 
  2.  @Override 
  3.  public Account findById(int id) { 
  4.  Account account = new Account(id, new Date().toString()); 
  5.  return account; 
  6.  } 
  7. @Bean 
  8. AccountService accountService(){ 
  9.  return new AccountServiceImpl(); 
  10. @Bean("/AccountService") 
  11. public HttpInvokerServiceExporter accountServiceExporter(AccountService accountService){ 
  12.  HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); 
  13.  exporter.setService(accountService); 
  14.  exporter.setServiceInterface(AccountService.class); 
  15.  return exporter; 

暴露服务的代码相当简单,需要注意两点:

  1. org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter 是 Spring 封装的一个服务暴露器,它会以 serviceInterface 为公共接口,以 service 为实现类向外提供服务。
  2. @Bean("/AccountService") 不仅仅指定了 IOC 容器中 bean 的名字,还充当了路径映射的功能,如果本地服务器暴露在 8080 端口,则示例服务的访问路径为http://localhost:8080/AccountService

创建服务消费者

  1. @Configuration 
  2. public class HttpProxyConfig { 
  3.  @Bean("accountServiceProxy") 
  4.  public HttpInvokerProxyFactoryBean accountServiceProxy(){ 
  5.  HttpInvokerProxyFactoryBean accountService = new HttpInvokerProxyFactoryBean(); 
  6.  accountService.setServiceInterface(AccountService.class); 
  7.  accountService.setServiceUrl("http://localhost:8080/AccountService"); 
  8.  return accountService; 
  9.  } 
  10. @SpringBootApplication 
  11. public class HttpClientApp { 
  12.  public static void main(String[] args) { 
  13.  ConfigurableApplicationContext applicationContext = SpringApplication.run(HttpClientApp.class, args); 
  14.  AccountService accountService = applicationContext.getBean(AccountService.class); 
  15.  System.out.println(accountService.findById(10086)); 
  16.  } 

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读