官网地址:Apache Dubbo
dubbo是一个轻量级、高性能java RPC框架,主要三大核心功能:面向接口的远程方法调用、智能容错和负载均衡、服务自动注册和发现
1、什么是RPC
RPC即为远程过程调用,如A服务器上的某个功能调用B服务器上的某个功能即为远程过程调用,
一个RPC框架两个很重要也是影响效率性能的点是
- 如何高效实现序列化和反序列化
- 如何快速建立通信
2、dubbo就是通过这一思想实现的框架,实现语言是java
3、架构
Provider:服务提供方,服务启动时向注册中心注册自己提供的服务
Consumer:服务消费者,在启动服务时向注册中心订阅自己所需的服务,从服务提供者地址列表中基于负载均衡算法选一台提供者进行调用,如果调用失败再选一台调用;consumer调用provider提供的服务使用的协议就是dubbo协议端口是20880,dubbo提供的协议有很多如http、dubbo、rmi等,
Registry:注册中心返回服务提供者地址列表给服务消费者,如果有变更,注册中心将基于长连接推送变更数据给服务消费者;这个注册中心可以不用,直接消费服务提供者提供的服务,这种消费称为直连消费
Monitior:监控中心,服务消费着和服务提供者在内存中累计调用次数和调用时间,定时每分钟发送一次数据到监控中心
二、dubbo直连工程
dubbo直连消费就是没有注册中心,消费者直接消费服务提供者提供的服务
1、创建provider工程(服务提供者)
依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.0</version> </dependency> <!--Spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--springmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency>
服务接口以及实现类
public interface MsgService { String hello(String hello); } public class MsgServiceImpl implements MsgService { public String hello(String hello) { return "hello"+hello; } }
springApplicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--声明dubbo服务名称,保证名称使用唯一性,dubbo内部使用的唯一标识--> <dubbo:application name="dubbo-provider"/> <!--指定dubbo协议名称和端口号 name:指定协议名称 官网推荐dubbo port:指定协议的端口号默认是20880--> <dubbo:protocol name="dubbo" port="20880"/> <!--暴露服务 interface:暴露服务的接口全限定类名 ref:接口在spring容器中的标识名称 registry:使用直连方式 不使用注册中心 值为N/A--> <dubbo:service interface="service.MsgService" ref="msgServiceImpl" registry="N/A"/> <!--加载接口实现类--> <bean id="msgServiceImpl" class="service.impl.MsgServiceImpl"/> </beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springApplicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
2、创建consumer工程(服务消费者)
依赖
<!--消费者要知道服务提供者提供了哪些服务 就要引入--> <dependency> <groupId>org.example</groupId> <artifactId>provider</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--DUBBO--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.0</version> </dependency> <!--Spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--springmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency>
测试方法
@RestController public class MsgController { @Autowired private MsgService msgService; @RequestMapping("hello") public String hello(Model model){ String msg = msgService.hello("ni hao"); model.addAttribute("msg",msg); return "index"; } }
springMvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--扫描组件--> <context:component-scan base-package="demo.controller"/> <!--试图解析器--> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
springApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--dubbo内部服务 name唯一标识--> <dubbo:application name="dubbo-consumer"/> <!--引用远程服务 id:远程服务代理对象名称 interface:接口的全限定名称 url:调用远程接口服务的地址 registry:直连方式 N/A--> <dubbo:reference interface="service.MsgService" id="msgService" url="dubbo://localhost:20880" registry="N/A"/> </beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <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,classpath:springApplicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
使用tomcat依次部署provider和consumer两个项目,浏览器访问
三、dubbo推荐的项目结构
官方推荐的dubbo项目结构包括三部分,分别是
- 服务消费工程:war工程 服务提供方
- 服务提供工程:war工程 服务消费方
- 服务接口工程:jar工程 ,业务接口和实体类
对上面的工程改造,创建一个interface的java工程,此工程只有一个接口类
//注意实体类要实现Serializable public class User implements Serializable { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } //接口 public interface MsgService { String hello(String hello); }
provider工程需要修改的地方
1、pom依赖引入接口坐标
<!--interface--> <dependency> <groupId>org.example</groupId> <artifactId>interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
2、删除provider原有的接口
3、实现类实现接口工程的接口和方法
4、核心xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo-provider"/> <dubbo:protocol name="dubbo" port="20880"/> <!--interface改为接口工程的接口类路径--> <dubbo:service interface="service.MsgService" ref="msgServiceImpl" registry="N/A"/> <!--加载接口实现类--> <bean id="msgServiceImpl" class="service.impl.MsgServiceImpl"/> </beans>
consumer工程需要修改地方
1、pom依赖删掉之前的provider坐标,增加interface工程坐标
2、springApplicationContext文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo-consumer"/> <!--interface改为接口工程的接口类路径--> <dubbo:reference interface="service.MsgService" id="msgService" url="dubbo://localhost:20880" registry="N/A"/> </beans>
3、测试
@RestController public class MsgController { //接口工程接口bean @Autowired private MsgService msgService; @RequestMapping("hello") public String hello(Model model){ String msg = msgService.hello("ni hao"); model.addAttribute("msg",msg); return "index"; } }
四、dubbo结合注册中心使用
上面说的直连方式在企业项目中基本不会使用,因为随着项目系统复杂,服务的数量增加,通过注册中心可以统一的管理服务,实际管理的就是服务url地址
注册中心可以有很多种,dubbo官方推荐使用zookeeper
关于zookeeper学习参考文章 ZooKeeper_程序三两行的博客-CSDN博客_zookeeper
1、创建接口工程interface
maven创建一个java工程即可,创建服务接口类
1. public interface MsgService { 2. String hello(String hello); 3. }
接口和上面直连方式一样没有什么变化
2、创建服务提供者provider
maven创建一个web工程,相较于直连方式,引入依赖有所变化
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>provider</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!--DUBBO--> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!--zookeeper--> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> <!--Spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--springmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--interface--> <dependency> <groupId>org.example</groupId> <artifactId>interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
核心配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo-provider"/> <dubbo:protocol name="dubbo" port="20880"/> <!--注定注册中心--> <dubbo:registry address="zookeeper://localhost:2181"/> <dubbo:service interface="service.MsgService" ref="msgServiceImpl"/> <bean id="msgServiceImpl" class="service.impl.MsgServiceImpl"/> </beans>
其他代码和上面直连方式一样
3、创建服务消费者consumer
依赖和provider一样
核心配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo-consumer"/> <!--指定注册中心--> <dubbo:registry address="zookeeper://localhost:2181"/> <dubbo:reference id="msgService" interface="service.MsgService"/> </beans>
其他代码和上面直连方式一样
4、测试
@RestController public class MsgController { //接口工程接口bean @Autowired private MsgService msgService; @RequestMapping("hello") public String hello(Model model){ String msg = msgService.hello("ni hao"); return msg; } }
5、查看zookeeper目录
五、dubbo配置
关于dubbo相关的配置,我们一般都在服务提供者工程中进行配置,因为服务提供正更了解服务的各种参数
1、关闭检查
dubbo默认是开启检查依赖服务的,我们可以在配置文件中关闭
<!--服务提供者关闭注册中心启动检查--> <dubbo:registry address="zookeeper://localhost:2181" check="false"/> <!--服务消费着关闭依赖服务检查,开发一般false 生产true--> <dubbo:reference interface="service.RoleService" check="false"/>
2、重试次数
消费着访问服务提供者,如果访问失败,则切换重试访问其他服务器,但是切换会带来更长的延迟,访问时间变长,影响用户体验,通过retries="2"来设置重试次数
<dubbo:service retries="2" interface=""/> 或 <dubbo:reference retries="2" interface=""
这个配置一般不用设置,默认重试一次就行
3、超时时间
服务提供和访问超时时间,一般只在服务提供者设置就行
<dubbo:service interface="service.MsgService" ref="msgServiceImpl" timeout="500"/>
4、版本号
随着项目的迭代更新,一个接口服务可能有多个实现类,区分不同的接口实现使用version
如下provider工程增加一个服务实现类MsgServiceImpl2
配置文件变化
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo-provider"/> <dubbo:protocol name="dubbo" port="20880"/> <dubbo:registry address="zookeeper://localhost:2181"/> <!--dubbu暴露的服务是接口 当接口有多个实现类时 ,使用version区分--> <dubbo:service interface="service.MsgService" ref="msgServiceImpl" version="1.0"/> <dubbo:service interface="service.MsgService" ref="msgServiceImpl" version="2.0"/> <bean id="msgServiceImpl" class="service.impl.MsgServiceImpl"/> </beans>
consumer配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubbo-consumer"/> <!--指定注册中心--> <dubbo:registry address="zookeeper://localhost:2181"/> <!--服务消费者通过version选择服务提供者同一个接口服务不同的实现--> <dubbo:reference id="msgService" interface="service.MsgService" version="1.0"/> <dubbo:reference id="msgService2" interface="service.MsgService" version="2.0"/> </beans>
测试
@RestController public class MsgController { //接口工程接口bean @Autowired private MsgService msgService; @Autowired private MsgService msgService2; @RequestMapping("hello") public String hello(Model model){ String msg = msgService.hello("ni hao"); String msg2 = msgService2.hello("ni hao 2"); return msg+"==="+msg2; } }
六、监控中心
dubbo-admin可视化的dubbo服务管理,安装时候需要指定注册中心,启动时候从注册中心获取服务消费者和提供者管理
参考使用
(4条消息) dubbo-admin安装以及dubbo-admin简单使用_尤雨东的博客-CSDN博客_dubbo-admin