dubbo组成原理-http服务消费端如何调用

article/2025/11/7 19:26:45

dubbo协议已经用的很多了,这里来稍微介绍一下http协议,官方对http协议的说明简直少的让人发指。哈哈

百度大部分都只是讲了http服务端的配置

那就先从服务端的配置说起

dubbo需要的jar包这里就不说明了,网上找些maven的pom就可以

web.xml配置servlet,注意url-pattern 是需要拦截哪些请求

<servlet><servlet-name>dubbo</servlet-name><servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dubbo</servlet-name><url-pattern>/api/*</url-pattern></servlet-mapping>
接着配置dubbo配置文件

<dubbo:application name="imp" ></dubbo:application><!-- <dubbo:protocol name="hessian" contextpath="imp/api" port="${dubbo.hessian.port}" server="servlet" threadpool="cached" threads="5000" register="false"></dubbo:protocol> --><dubbo:protocol name="dubbo" port="30883" /><dubbo:protocol name="http" port="8080" server="servlet" contextpath="imp/api/httpService"/> <dubbo:provider group="${dubbo.group}" /><dubbo:consumer check="false"  group="${dubbo.group}"/><!-- 使用zookeeper注册中心暴露发现服务地址 --><dubbo:registry protocol="zookeeper" address="${dubbo.zookeeper.address}"  check="false" file="/home/epay/.dubbo/dubbo-registry-imp.cache" ></dubbo:registry>

因为dubbo支持多协议,所以这里配置了dubbo与http二种

http配置需要注意contextpath这个参数,引用一下官方说明

  • 协议的上下文路径<dubbo:protocol contextpath="foo" />必须与servlet应用的上下文路径相同

什么看不懂?跑起来打个断点看看

用java模拟一个psot的http请求http://localhost:8080/imp/api/httpService/com.hellowin.imp.common.service.IDeviceService

服务端接收到http请求,因为/api/。所以会被DispatcherServlet拦截执行service

public class DispatcherServlet extends HttpServlet {private static final long serialVersionUID = 5766349180380479888L;private static DispatcherServlet INSTANCE;private static final Map<Integer, HttpHandler> handlers = new ConcurrentHashMap<Integer, HttpHandler>();public static void addHttpHandler(int port, HttpHandler processor) {handlers.put(port, processor);}public static void removeHttpHandler(int port) {handlers.remove(port);}public static DispatcherServlet getInstance() {return INSTANCE;}public DispatcherServlet() {DispatcherServlet.INSTANCE = this;}protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpHandler handler = handlers.get(request.getLocalPort());if( handler == null ) {// service not found.response.sendError(HttpServletResponse.SC_NOT_FOUND, "Service not found.");} else {handler.handle(request, response);}}}

进入handler.handle(request, response);


handle有hession、http、webservice 这里我们只看http的

点击进入HttpProtocol 这个类

 private class InternalHandler implements HttpHandler {public void handle(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException {String uri = request.getRequestURI();HttpInvokerServiceExporter skeleton = skeletonMap.get(uri);if (! request.getMethod().equalsIgnoreCase("POST")) {response.setStatus(500);} else {RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());try {skeleton.handleRequest(request, response);} catch (Throwable e) {throw new ServletException(e);}}}}

同志们看到了吗,skeletonMap.get(uri);。是不是很像springmvc中根据url定位handlermapping


所以http暴露服务的路径是contextpath +暴露接口类名称

最开始我以为可以模拟http请求调用dubbo接口,因为网上始终找不到demo,都是各种复制黏贴的内容,所以打算通过源码来研究一下是否可以通过模拟http请求来实现调用。

当跟进到HttpProtocol 中看到HttpInvokerServiceExporter 感觉不妙

HttpInvokerServiceExporter 是spring-web.jar包下的一个类,以下是介绍

Spring HTTP Invoker一种JAVA远程方法调用框架实现,原理与JDK的RMI基本一致,所以我们先跟其它JAVA远程方法调用实现做下简单比较。

  • RMI:使用JRMP协议(基于TCP/IP),不允许穿透防火墙,使用JAVA系列化方式,使用于任何JAVA应用之间相互调用。

  • Hessian:使用HTTP协议,允许穿透防火墙,使用自己的系列化方式,支持JAVA、C++、.Net等跨语言使用。

  • Burlap: 与Hessian相同,只是Hessian使用二进制传输,而Burlap使用XML格式传输(两个产品均属于caucho公司的开源产品)。

  • Spring HTTP Invoker: 使用HTTP协议,允许穿透防火墙,使用JAVA系列化方式,但仅限于Spring应用之间使用,即调用者与被调用者都必须是使用Spring框架的应用。


Spring一定希望大家尽量使用它的产品,但实际项目中我们还是要根据需求来决定选择哪个框架,下面我们来看看Spring HTTP Invoker的使用。


既然通过是HTTP请求调用,那么客户端肯定需要一个代理用于帮忙发送HTTP请求,帮忙做对象系列化和反系列化等,Spring框架中的HttpInvokerServiceExporter类处理这些杂事;而服务器端需要一个HTTP请求处理器,帮忙处理HTTP请求已经对象系列化和反系列化工作,Spring框架中的HttpInvokerServiceExporter类就是干这活的,对于Sun JRE 6 的HTTP Server,Spring还提供了SimpleHttpInvokerServiceExporter类供选择。


网上有一些SimpleHttpInvokerServiceExporter的服务端和客户端配置说明,这里就不说明了

之前介绍dubbo说过,服务方就是doExport,消费方就是doRefer。继续看HttpProtocol 中这二个方法

protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {String addr = url.getIp() + ":" + url.getPort();HttpServer server = serverMap.get(addr);if (server == null) {server = httpBinder.bind(url, new InternalHandler());serverMap.put(addr, server);}final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter();httpServiceExporter.setServiceInterface(type);httpServiceExporter.setService(impl);try {httpServiceExporter.afterPropertiesSet();} catch (Exception e) {throw new RpcException(e.getMessage(), e);}final String path = url.getAbsolutePath();skeletonMap.put(path, httpServiceExporter);return new Runnable() {public void run() {skeletonMap.remove(path);}};}

httpServiceExporter设置的二个参数

Service实现类,一般引用其它bean

ServiceInterface服务类型

这样就达到了暴露服务


 protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean();httpProxyFactoryBean.setServiceUrl(url.toIdentityString());httpProxyFactoryBean.setServiceInterface(serviceType);String client = url.getParameter(Constants.CLIENT_KEY);if (client == null || client.length() == 0 || "simple".equals(client)) {SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor = new SimpleHttpInvokerRequestExecutor() {protected void prepareConnection(HttpURLConnection con,int contentLength) throws IOException {super.prepareConnection(con, contentLength);con.setReadTimeout(url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT));con.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));}};httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);} else if ("commons".equals(client)) {CommonsHttpInvokerRequestExecutor httpInvokerRequestExecutor = new CommonsHttpInvokerRequestExecutor();httpInvokerRequestExecutor.setReadTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);} else if (client != null && client.length() > 0) {throw new IllegalStateException("Unsupported http protocol client " + client + ", only supported: simple, commons");}httpProxyFactoryBean.afterPropertiesSet();return (T) httpProxyFactoryBean.getObject();}
ServiceUrl路径

ServiceInterface服务类型

这样,消费方在调用服务FactoryBean的getObject()的时候,获取到的代理对象就是httpProxyFactoryBean的对象


所以最后得出结论,dubbo的http协议,只是最后远程调用走的http,消费方通过服务调用还是需要类似dubbo协议的调用方式。如果需要传统http访问方式则需要看dubbox


不过有兴趣的可以看看当当的dubbox

http://dangdangdotcom.github.io/dubbox/rest.html

在Dubbo中开发REST风格的远程调用








http://chatgpt.dhexx.cn/article/cRcd1RKW.shtml

相关文章

Dubbo基本原理机制

分布式服务框架&#xff1a; –高性能和透明化的RPC远程服务调用方案–SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架&#xff0c;基于tcp长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯&#xff0c;适合于小数据量大并发的服务调用&#xff0c;以及服务消费…

Dubbo基本原理与机制

1、什么是Dubbo Dubbo 是一款高性能、轻量级的开源 RPC 框架&#xff0c;提供服务自动注册、自动发现等高效服务治理方案&#xff0c; 可以和 Spring 框架无缝集成。 2、Dubbo依赖关系 1、服务消费者&#xff08;Consumer&#xff09;: 调用远程服务的服务消费方&#xff0c…

dubbo原理和机制

Dubbo 框架是用来处理分布式系统中&#xff0c;服务发现与注册以及调用问题的&#xff0c;并且管理调用过程。 一&#xff0c;工作流程&#xff1a; 服务提供者在启动的时候&#xff0c;会通过读取一些配置将服务实例化。Proxy 封装服务调用接口&#xff0c;方便调用者调用。…

Dubbo的原理与机制

​ Dubbo 前言 在介绍Dubbo之前先了解一下基本概念&#xff1a; Dubbo是一个RPC框架&#xff0c;RPC&#xff0c;即Remote Procedure Call&#xff08;远程过程调用&#xff09;&#xff0c;相对的就是本地过程调用&#xff0c;在分布式架构之前的单体应用架构和垂直应用架…

Dubbo基础及原理机制

1. 什么是Dubbo&#xff1f; Dubbo是 阿里巴巴公司开源的一个高性能RPC 分布式服务框架&#xff0c;使得应用可通过高性能的 RPC 实现服务的输出和输入功能&#xff0c;可以和 Spring框架无缝集成&#xff0c;现已成为 Apache 基金会孵化项目。 2. 为什么要用Dubbo&#xff1…

Dubbo原理和机制详解(非常全面)

Dubbo是一款Java RPC框架&#xff0c;致力于提供高性能的RPC远程服务调用方案。Dubbo 作为主流的微服务框架之一&#xff0c;为开发人员带来了非常多的便利。 本文我们重点详解 Dubbo 的原理机制 mikechen 目录 Dubbo核心功能Dubbo核心组件Dubbo的架构设计Dubbo调用流程 1️…

大地测量学基础(复习)第一部分

写在前面 这篇博文是用来复习课程“大地测量学基础”的&#xff0c;里面仅列出本人觉得这门课程比较重要的部分&#xff0c;希望能够帮助到有需要的朋友。 课本采用《大地测量学基础》孔祥元&#xff0c;武汉大学出版社。 前面已经有一篇“大地测量学基础&#xff08;复习&…

深入理解ArcGIS的地理坐标系、大地坐标系

1、引言 地理坐标&#xff1a;为球面坐标。 参考平面地是 椭球面,坐标单位:经纬度 大地坐标&#xff1a;为平面坐标。参考平面地是 水平面,坐标单位&#xff1a;米、千米等 地理坐标转换到大地坐标的过程可理解为投影。 &#xff08;投影&#xff1a;将不规则的地球曲面转…

GNSS定位中的不同高度概念及计算

文章目录 高度相关的几个基本概念RTKLIB中高度设置与计算参考文献 由于在GNSS定位中由多种高度表示&#xff0c;不同的高度概念很容易混淆&#xff0c;中英文对应有时候也容易搞混。因此整理了一下常用的两种高度——椭球高、正高的概念与计算&#xff0c;并且标注了对应的英文…

概念讲解:大地水准面 | 地球椭球体 | 参考椭球体 | 大地基准面 | 地图投影

文章目录 大地水准面地球椭球体参考椭球体大地基准面地图投影几个概念之间的关系相关文章 大地水准面 指平均海平面通过大陆延伸勾画出的一个连续的封闭曲面。大地水准面包围的球体称为大地球体。从大地水准面起算的陆地高度&#xff0c;称为绝对高度或海拔。 大地水准面是对地…

地图学的基础知识_天文坐标系_大地坐标系_地心坐标系及其相关概念

学习地图学&#xff0c;由于地理知识欠缺&#xff0c;学习相关投影知识还为时过早&#xff0c;需要复习一些基本概念。 阅读对象:测绘类 地球自然球体: 由地球自然表面所包围的的形体称为地球自然体。 地球自然球体形状:地球不是一个正球体&#xff0c;而是一个极半径略短&a…

大地测量学

大地测量学简答题复习 问&#xff1a;建立国家平面控制网的方法&#xff1f; 答&#xff1a; 常规大地测量&#xff1a;三角测量&#xff08;已知一个点的坐标&#xff0c;又精密测量了1&#xff0c;2点的边长和坐标方位角&#xff0c;依据三角形的正弦定理推测出其他边的长…

[复试——大地测量学]第一章节——2022/12/30

PART 1 大地测量学的定义 是在一定的时间和空间的参考系中&#xff0c;测量和描绘地球形状及其重力场并监测其变化&#xff0c;为人类活动提供地球空间信息的一门学科。 大地测量学的作用 1.建立地面控制网 2.精确测定大地控制点的三维位置以及其重力场参数 大地测量学的…

1985高程基准与全球大地水准面(EGM2008)的关系综述

​按照惯例&#xff0c;先给结论&#xff1a; &#xff08;1&#xff09;1985国家高程基准与EGM2008的差异有严密的理论公式计算&#xff1b; &#xff08;2&#xff09;1985国家高程基准与EGM20008的垂直偏差与参考系、水准模型、选取的水准点有关系 &#xff08;3&#xf…

似大地水准面精化

转载自&#xff1a;http://blog.sina.com.cn/s/blog_64886846010153qi.html 大地高是指以参考椭球面作为高程基准面的高程系统&#xff0c;是地面点沿法线到参考椭球面的距离。 正高是地面点沿重力线到大地水准面的距离。正常高是指从一地面点沿过此点的**正常重力线**到似…

正常高、大地高、海拔高的测绘概念

一、海拔高、大地高 高程是地理学和测量学中对地物高度的一种表达。英文的表达是elevation。与高程相关的两个概念——大地高与海拔高,在实践上有差异,但很容易混淆。 王慧麟等编著的《测量与地图学》(南大出版社,2004年)中对这两个概念有明确表述: 点位沿椭球面的法线至…

大地高、正高和正常高及高程异常

测量学习过程中&#xff0c;这几个高程或许曾困扰过许多人&#xff08;其中也包括我&#xff09;&#xff0c;希望我能在这里把这些说清楚。 可以简单地理解&#xff0c;高程其实就是某点到某个基准面的距离。 这么算下来&#xff0c;对于这几个高程的理解就是怎么理解相对应…

大地高、海拔高 地心纬度、大地纬度/地理纬度

大地测量学模型所表示的地球表面&#xff0c;所有点的当地重力矢量都垂直于该表面&#xff0c;即一个“等位面”&#xff1b;这种形状称为大地水准面&#xff01; 但是由于表面及其不规则&#xff0c;见如下图&#xff1a; 真实的地球据说如下&#xff1a; 地球真实不是一个正球…

大地高、正高和正常高的区别

测量学习过程中&#xff0c;这几个高程或许曾困扰过许多人&#xff08;其中也包括我&#xff09;&#xff0c;希望我能在这里把这些说清楚。 可以简单地理解&#xff0c;高程其实就是某点到某个基准面的距离。 这么算下来&#xff0c;对于这几个高程的理解就是怎么理解相对应…

大地高和正常高、正高的详细说明

测量学习过程中&#xff0c;这几个高程或许曾困扰过许多人&#xff08;其中也包括我&#xff09;&#xff0c;希望我能在这里把这些说清楚。 可以简单地理解&#xff0c;高程其实就是某点到某个基准面的距离。 这么算下来&#xff0c;对于这几个高程的理解就是怎么理解相对应…