官网地址:http://dubbo.apache.org/zh-cn/
GitHub源码地址:https://github.com/apache/dubbo
1. 概述 1.1 简介 Dubbo: 2011.10,阿里开源Java RPC框架;2012年,当当、网易、中国人寿、海尔等采用…
Apache Dubbo:一款**高性能 Java RPC 框架
**。
RPC:Remote Procedure Call 远程过程调用
Dubbo 采用流逝计算架构(SOA)。
SOA:
面向服务的架构是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构件在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
1.2 作用 Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo 架构:
节点
角色说明
Provider
暴露服务的服务提供方
Consumer
调用远程服务的服务消费方
Registry
服务注册与发现的注册中心
Monitor
统计服务的调用次数和调用时间的监控中心
Container
服务运行容器
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
1.3 功能
面向接口代理的高性能RPC调用
智能负载均衡
服务自动注册与发现
高度可扩展能力
运行期流量调度
可视化的服务治理与运维
1.4 传输协议 Dubbo 为了提升传输的性能,支持多种传输协议:
Dubbo 解决高并发,文件传输使用 rmi。
Dubbo 协议(推荐)
采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 连接个数:单连接 连接方式:长连接 传输协议:TCP 传输方式:NIO 异步传输 序列化:Hessian 二进制序列化 适用范围:传入传出参数数据包较小(建议小于100K)
,消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。 适用场景:常规远程服务方法调用
1 <dubbo:protocol name ="dubbo" port ="20880" />
rmi 协议
采用 JDK 标准的 java.rmi.*
实现,采用阻塞式短连接和 JDK 标准序列化方式。 连接个数:多连接 连接方式:短连接 传输协议:TCP 传输方式:同步传输 序列化:Java 标准二进制序列化 适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件
。 适用场景:常规远程服务方法调用,与原生RMI服务互操作
1 <dubbo:protocol name ="rmi" port ="1099" />
http 协议 基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现。 连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 序列化:表单序列化 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件
。 适用场景:需同时给应用程序和浏览器 JS 使用的服务。
1 <dubbo:protocol name ="http" port ="8080" />
1.5 注册中心
Zookeeper 注册中心 http://dubbo.apache.org/zh-cn/docs/user/references/registry/zookeeper.html
Nacos 注册中心
http://dubbo.apache.org/zh-cn/docs/user/references/registry/nacos.html
Multicast 注册中心 http://dubbo.apache.org/zh-cn/docs/user/references/registry/multicast.html
2. Demo Dubbo 采用全 Spring 配置方式,透明化接入应用,对应用没有任何 API 侵入,只需用 Spring 加载 Dubbo 的配置即可,Dubbo 基于 Spring 的 Schema 扩展 进行加载。
xml 约束:
DTD - eg: mybatis, web.xml…
Schema - eg: spring, springmvc…
架构模块图:(消费者、提供者)
2.1 消费者 ● pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 项目_业务接口 spring-webmvc 5 .2 .8 dubbo 2 .7 .8 dubbo-registry-nacos 2 .7 .8 javax.servlet-api 4 .0 .1 jackson-core 2 .9 .5 jackson-databind 2 .9 .5 jackson-annotations 2 .9 .5 springfox-swagger2 2 .6 .1 springfox-swagger-ui 2 .6 .1
● springmvc.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:mvc ="http://www.springframework.org/schema/mvc" xmlns:context ="http://www.springframework.org/schema/context" xmlns:tx ="http://www.springframework.org/schema/tx" xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:dubbo ="http://dubbo.apache.org/schema/dubbo" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd " > <context:component-scan base-package ="com.applet.consumer.controller.user" /> <context:component-scan base-package ="com.applet.consumer.controller.search" /> <mvc:annotation-driven /> <mvc:default-servlet-handler /> <mvc:resources mapping ="swagger-ui.html" location ="classpath:/META-INF/resources/" /> <mvc:resources mapping ="/webjars/**" location ="classpath:/META-INF/resources/webjars/" /> <bean id ="swaggerConfig" class ="com.applet.consumer.config.SwaggerConfig" /> <dubbo:application name ="searchApi" /> <dubbo:registry address ="nacos://47.94.193.104:8848" username ="nacos" password ="nacos" /> <dubbo:reference id ="searchHistoryService" interface ="com.applet.service.search.SearchHistoryService" check ="true" timeout ="10000" retries ="5" /> <dubbo:reference id ="userService" interface ="com.applet.service.personal.UserService" check ="true" timeout ="10000" retries ="5" /> </beans >
● web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app > <display-name > ConsumerApi</display-name > <servlet > <servlet-name > dispatcherServlet</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:springmvc.xml</param-value > </init-param > </servlet > <servlet-mapping > <servlet-name > dispatcherServlet</servlet-name > <url-pattern > /</url-pattern > </servlet-mapping > </web-app >
2.2 提供者 ● pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 项目_业务接口spring -web 5.2 .8 spring -context 5.2 .8 spring -tx 5.2 .8 spring -jdbc 5.2 .8 aspectjweaver 1.9 .6 mybatis 3.5 .5 mybatis-spring 2.0 .5 mysql-connector-java 8.0 .21 druid 1.1 .22 dubbo 2.7 .8 dubbo-registry-nacos 2.7 .8
● jdbc.properties
1 2 3 4 jdbc.driver =com.mysql.cj.jdbc.Driver jdbc.url =jdbc:mysql://39.98.140.199:3306/db_youju?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false jdbc.username =root jdbc.password =1234
● spring-dao.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:mvc ="http://www.springframework.org/schema/mvc" xmlns:context ="http://www.springframework.org/schema/context" xmlns:tx ="http://www.springframework.org/schema/tx" xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd " > <context:property-placeholder location ="classpath:jdbc.properties" /> <bean id ="dataSource" class ="com.alibaba.druid.pool.DruidDataSource" > <property name ="driverClassName" value ="${jdbc.driver}" /> <property name ="url" value ="${jdbc.url}" /> <property name ="username" value ="${jdbc.username}" /> <property name ="password" value ="${jdbc.password}" /> </bean > <bean id ="sessionFactory" class ="org.mybatis.spring.SqlSessionFactoryBean" > <property name ="dataSource" ref ="dataSource" /> <property name ="mapperLocations" value ="classpath:mapper/*.xml" /> </bean > <bean id ="mapper" class ="org.mybatis.spring.mapper.MapperScannerConfigurer" > <property name ="basePackage" value ="com.applet.personal.dao" /> </bean > </beans >
● spring-service.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:mvc ="http://www.springframework.org/schema/mvc" xmlns:context ="http://www.springframework.org/schema/context" xmlns:tx ="http://www.springframework.org/schema/tx" xmlns:aop ="http://www.springframework.org/schema/aop" xmlns:dubbo ="http://dubbo.apache.org/schema/dubbo" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd " > <context:component-scan base-package ="com.applet.personal.provider" /> <bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name ="dataSource" ref ="dataSource" /> </bean > <tx:advice id ="txAdvice" transaction-manager ="transactionManager" > <tx:attributes > <tx:method name ="*" propagation ="REQUIRED" isolation ="SERIALIZABLE" rollback-for ="java.lang.Exception" /> </tx:attributes > </tx:advice > <aop:config proxy-target-class ="false" > <aop:pointcut id ="ptt1" expression ="execution(* com.applet.personal.provider.*.save*(..))" /> <aop:pointcut id ="ptt2" expression ="execution(* com.applet.personal.provider.*.update*(..))" /> <aop:pointcut id ="ptt3" expression ="execution(* com.applet.personal.provider.*.delete*(..))" /> <aop:advisor advice-ref ="txAdvice" pointcut-ref ="ptt1" /> <aop:advisor advice-ref ="txAdvice" pointcut-ref ="ptt2" /> <aop:advisor advice-ref ="txAdvice" pointcut-ref ="ptt3" /> </aop:config > <dubbo:protocol name ="dubbo" port ="-1" /> <dubbo:application name ="personalServer" /> <dubbo:registry address ="nacos://47.94.193.104:8848" username ="nacos" password ="nacos" /> <dubbo:service interface ="com.applet.service.personal.UserService" ref ="userServiceImpl" timeout ="10000" retries ="5" /> </beans >
● web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app > <display-name > PersonalServer</display-name > <context-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:spring-*.xml</param-value > </context-param > <listener > <listener-class > org.springframework.web.context.ContextLoaderListener</listener-class > </listener > </web-app >
2.3 公共模块 Common、Entity、Service 的 pom.xml 最好加上 maven 编译插件。
1 2 3 4 5 6 7 8 9 10 <build > <plugins > <plugin > <groupId > org.apache.maven.plugins</groupId > <artifactId > maven-compiler-plugin</artifactId > <version > 3.8.1</version > </plugin > </plugins > </build >
如果IDEA没有tomcat(如社区版),可以到插件中安装一个 smarttomcat。 proxy-target-class=”true” // jdk 动态代理 proxy-target-class=”false” // CGLib 动态代理
3. 跳坑记录
如果服务模块注册不上nacos,检查所有扫描路径的地方是否正确
服务模块,不论消费者还是提供者,需在pom中打war包
对返回结果封装的 R 类,也同样需要实现 序列化,不仅仅是实体类需要序列化(Dubbo在远程过程调用时需要保证传输数据是序列化格式的)
对Common、Entity、Service这些公共模块,需要添加 maven 的编译插件
局域网内Dubbo的服务可以在不同的机器上启动,只要Nacos中可以注册,那么服务就是可被消费者消费的