一 知识点回顾
首先回顾以下两个名词:
RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。
SOA:是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。
具体(可以参考分布式服务架构(一))
二 Dubbo是什么?
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。它是一套微服务系统的协调者,在它这套体系中,一共有三种角色,分别是:服务提供者(下面简称提供者)、服务消费者(下面简称消费者)、注册中心。
主要解决的问题:
1.项目服务化后,项目之间的高性能通讯问题。(项目被拆分成多个服务模块后必然会涉及模块之间的通讯)
2.服务的URL管理,当项目拆分为N个服务并且不断增加时,如何有效的管理的服务URL
3.服务发现和服务移除,动态的管理服务
三 Dubbo架构:
模块分包:
dubbo-common 公共逻辑模块:包括 Util 类和通用模型。
dubbo-remoting 远程通讯模块:相当于 Dubbo 协议的实现,如果 RPC 用 RMI协议则不需要使用此包。
dubbo-rpc 远程调用模块:抽象各种协议,以及动态代理,只包含一对一的调 用,不关心集群的管理。
dubbo-cluster 集群模块:将多个服务提供方伪装为一个提供方,包括:负载 均衡, 容错,路由等,集群的地址列表可以是静态配置的,也可以是由注册中 心下发。
dubbo-registry 注册中心模块:基于注册中心下发地址的集群方式,以及对各 种注册中心的抽象。
dubbo-monitor 监控模块:统计服务调用次数,调用时间的,调用链跟踪的服 务。
dubbo-config 配置模块:是 Dubbo 对外的 API,用户通过 Config 使用D ubbo,隐藏 Dubbo 所有细节。
dubbo-container 容器模块:是一个 Standlone 的容器,以简单的 Main 加载 Spring 启动,因为服务通常不需要 Tomcat/JBoss 等 Web 容器的特性,没必 要用 Web 容器去加载服务。
图例说明:
-
图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代 表层或模块,蓝色的表示与业务有交互,绿色的表示只对 Dubbo 内部交互。
-
图中背景方块 Consumer, Provider, Registry, Monitor 代表部署逻辑拓扑节点
-
图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行 时同步调用。
-
图中只包含 RPC 的层,不包含 Remoting 的层,Remoting 整体都隐含在 Protocol 中。
调用关系说明:
0 服务容器负责启动,加载,运行服务提供者。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
四 Dubbo实例
Dubbo是一套微服务系统的协调者,在它这套体系中,一共有三种角色,分别是:服务提供者(下面简称提供者)、服务消费者(下面简称消费者)、注册中心。
你在使用的时候需要将Dubbo的jar包引入到你的项目中,也就是每个服务都要引入Dubbo的jar包。然后当这些服务初始化的时候,Dubbo就会将当前系统需要发布的服务、以及当前系统的IP和端口号发送给注册中心,注册中心便会将其记录下来。这就是服务发布的过程。与此同时,也是在系统初始化的时候,Dubbo还会扫描一下当前系统所需要引用的服务,然后向注册中心请求这些服务所在的IP和端口号。接下来系统就可以正常运行了。当系统A需要调用系统B的服务的时候,A就会与B建立起一条RPC信道,然后再调用B系统上相应的服务。
首先定义一个dubbo.api接口供dubbo-provider(提供者),dubbo-consumer(消费者)调用
简单的定义一个接口:
User
注意:该类需要实现序列化
package com.dubbo.model;
public class User implements Serializable{
private String name;
private int age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
UserService:
package com.dubbo.api;
import java.util.List;
import com.dubbo.model.User;
public interface UserService {
public String sayHi(String name);
public List<User> getUserList();
}
然后将其打包部署到maven仓库中,如果不熟悉,请参考我写的这篇文章https://blog.csdn.net/qq_33223299/article/details/87167814
如果打包完毕,就可以做接下来的工作了。
1.注册中心
Dubbo的注册中心有好多种,包括Multicast、Zookeeper、Redis、Simple等。Dubbo官方推荐使用Zookeeper注册中心,我所使用过的也只是Zookeeper注册中心。关于Zookeeper安装参考我发布的文章https://blog.csdn.net/qq_33223299/article/details/87605598
2.提供者(dubbo-provider项目)
pom.xml (需要添加前面我们打包好的dubbo-api依赖)
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.chp.mydubbo</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
dubbo-provider.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" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 快速失败,只发起一次调用,失败立即报错 -->
<dubbo:provider cluster="failfast" />
<!-- 具体的实现bean -->
<bean id="userService" class="com.dubbo.provider.UserServiceImpl" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.dubbo.api.UserService" ref="userService" />
</beans>
userService的实现类:
package com.dubbo.provider;
import java.util.ArrayList;
import java.util.List;
import com.dubbo.api.UserService;
import com.dubbo.model.User;
public class UserServiceImpl implements UserService {
@Override
public List<User> getUserList() {
User user1=new User();
user1.setName("张三");
user1.setAge(23);
user1.setAddress("杭州");
User user2=new User();
user2.setName("李四");
user2.setAge(23);
user2.setAddress("北京");
User user3=new User();
user3.setName("王五");
user3.setAge(25);
user3.setAddress("上海");
List<User> list=new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
return list;
}
@Override
public String sayHi(String name) {
// TODO Auto-generated method stub
return "hello" + name;
}
}
首先我们先打开Zookeeper.cmd,然后运行下面代码加载Spring配置,启动服务:
public class Main {
public static void main(String[] args) throws IOException {
// com.alibaba.dubbo.container.Main.main(args);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"dubbo-provider.xml"});
context.start();
System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟
}
}
3.消费者(dubbo-consumer项目)
pom.xml jar包依赖(同理我们也需要导入dubbo-api jar包依赖)
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.chp.mydubbo</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
</dependencies>
dubbo-consumer.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-consumer"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:consumer check="false"/>
<dubbo:reference id="userService" interface="com.dubbo.api.UserService" />
</beans>
加载spring配置,并调用远程服务
package com.dubbo.consumer.web;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dubbo.api.UserService;
import com.dubbo.model.User;
public class Test {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "dubbo-consumer.xml" });
context.start();
UserService userService = (UserService) context.getBean("userService");
String hello = userService.sayHi("jack");
List<User> list = userService.getUserList();
System.out.println(hello);
for (User user : list) {
System.out.println(user);
}
System.in.read();
}
}
运行结果:
4.管理者(dubbo-admin)
这个可以自己去htts://github.com/alibaba/dubbo 下载dubbo源码,然后将duubo-admin这个文件通过maven打包成war包,我这里已经打包好(dubbo-admin-2.5.4-SNAPSHOT.war),需要的话可点击百度网盘获取 链接: https://pan.baidu.com/s/1Bfq_xrNBSLS3gCvbF3BnKQ 提取码: mgc4
(一)通过tomcat解压dubbo-admin-2.5.4-SNAPSHOT.war
将该war放入tomcar下的webapps目录下,如下图所示
修改tomcat的端口为8088,修改方法如下,打到conf下的文件 server.xml,因为zookeeper会用到8080的端口,所以为了不冲突,把Tomcat的端口改一下。记得一定要改!!!
<Connector port="8090" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
点击tomcat bin目录下的startup.bat,会自动将该war包解压好
(二)配置属性文件
打开WEB-INF中的dubbo.properties
(三)运行aubbo-admin平台
启动zookeeper,然后再启动tomcat,在浏览器输入 http://localhost:8090/dubbo-admin-2.5.4-SNAPSHOT/
弹出框,输入用户名密码,主界面如下图所示
提供者:
消费者: