文章目录

  • 1. 什么是RPC?什么是Dubbo?
  • 2. RPC(Remote Procedure Call)
  • 3. Dubbo的特点
  • 4. Dubbo 设计架构
  • 5. Dubbo 环境搭建 之 zookeeper注册中心
  • 6. Dubbo 环境搭建 之 控制台管理(admin)
  • 7. Dubbo 环境搭建 之 创建 服务提供者 和 服务消费者 工程
  • 8. Dubbo 环境搭建 之 服务提供者配置
  • 9. Dubbo 环境搭建 之 服务消费者配置
  • 10. Dubbo 环境搭建 之 监控中心(Monitor)


提示:使用的dubbo版本是2.6.2版本,zookeeper版本是3.8.0版本。

1. 什么是RPC?什么是Dubbo?


rpc 调用的 分布式事务问题_dubbo


rpc 调用的 分布式事务问题_Dubbo_02

也就是只有分布式的时候才有dubbo这样分布式服务器框架的需求。

Dubbo就像一个治理系统,来处理这些分布式的复杂的逻辑。简而言之,Dubbo就是一个专门处理分布式服务的框架。

分布式系统是若干个独立系统的集合,用户使用起来像是使用一套系统是的。

正常的大公司内部都有自己的一套处理分布式相关的一套系统,目前仅仅学习使用Dubbo而已。

RPC分布式服务器架构模型如下:

rpc 调用的 分布式事务问题_java_03

了解流动计算架构:

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_04

2. RPC(Remote Procedure Call)


RPC是远程过程调用,是一种进程间通信方式,是一种技术思想,不是规范。

RPC就是A服务器调用B服务器相关函数功能(可能传递参数),并且返回相关回调。

RPC过程原理:

  • RPC两个核心模块:通讯,序列化。
  • 序列化为json字符串(也可能序列化为xml格式,但是xml相比较json效率低!),反序列化为对象。

RPC框架有很多,虽然用法不同,但是思想原理都是一样的:

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_05

3. Dubbo的特点


Dubbo出生于阿里,后来阿里捐献给了apache基金会。dubbo起源于电商系统,电商系统的架构经历过一系列演变。

Dubbo面向接口的高性能RPC调用

  • A服务器调用B功能,只需要在A调用B对应功能的接口就可以了。

Dubbo负载均衡

  • 例如用户业务系统,就可以均衡的将处理量分配到每一台处理用户业务的服务器,不至于压垮其中一台或者多台。

Dubbo注册中心(服务和发现)

  • 注册中心的作用就是标识哪些服务器是处理用户业务的,哪些服务器处理业务,哪些处理支付等等。
  • 同样还是实时感知,一些服务器的状态。

Dubbo运行期流量调用

  • 就是对于一些请求可以做到很轻松的调用。
  • 什么是灰度发布? 就是比如100台服务器要进行升级,可以让其中20台先进行升级,其他的保持原来版本;之后升级的20台没什么问题,就依次渐渐在升级20台;如此往后全部升级,大体上这个过程就是灰度发布。

rpc 调用的 分布式事务问题_Dubbo_06

Dubbo可视化服务治理与运维

  • 可以通过一些可视化页面啥的,来查询一些数据,状态,配置参数等等操作。

Dubbo支持的协议:

  • 官方推荐dubbo协议,默认端口20880

4. Dubbo 设计架构


Dubbo设计架构如下:

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_07

Consumer:消费者就是Web层用户。

Provider:提供者就是业务相关系统。

Container:指的Dubbo框架容器。

Monitor:是监控中心,作用就是监控消费者和服务者的一些信息。

Registry:服务注册与发现的中心,提供目录服务,亦称为服务注册中心。

5. Dubbo 环境搭建 之 zookeeper注册中心



第一步:官方下载zookeeper。

主要注意的是:

  • ZooKeeper服务器是用Java创建的,它运行在JVM之上。需要安装JDK 7或更高版本。
  • 对于apache-zookeeper-3.8.0-bin.tar.gz包,也可以在window系统上面解压出来,bin下面的zkServer.cmd文件执行。

第二步:配置zoo.cfg文件。

解压后直接启动报一个zoo.cfg file is missing的错误。

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_08

在config文件下面,有一个sample样本复制一份,来配置。

rpc 调用的 分布式事务问题_rpc_09

注意事项:

  • window系统启动,要重新设置一下zoo.cfg的dataDir(因为默认是linux系统目录)。
  • dataDir是定义存放临时数据的目录。

    (…/data是上级目录的data目录下)

第三步:去zookeeper安装目录bin下面,执行zkServer.cmd启动zookeeper,执行zkCli.cmd进入zookeeper客户端。

rpc 调用的 分布式事务问题_Dubbo_10


第四步:zookeeper常用命令。

  • ls / :查看当前所有信息。
  • create -e /name value : 创建一个name对应的value。
  • get /name :获取name对应的value。

rpc 调用的 分布式事务问题_rpc_11


rpc 调用的 分布式事务问题_rpc_12

6. Dubbo 环境搭建 之 控制台管理(admin)


去Dubbo官方的Github上面。

注意:现在有很多分支版本,大部分教学视频或者网页查询都是使用的master-0.2.0分支,如下图:

rpc 调用的 分布式事务问题_rpc_13


(所以最好git checkout 一下!!使用之前版本对应上。)


新版本可能将dubbo admin单独拿出来了,其他版本也可能是在Dubbo OPS里面(包含dubbo admin和dubbo monitor)。

找到Dubbo Admin,clone下来,

rpc 调用的 分布式事务问题_rpc_14

将每个文件的application.properties对应注册中心进行修改:

rpc 调用的 分布式事务问题_Dubbo_15

然后可以mvn clean package进行mvn打包。

  • 因为网络原因遇到一个坑,下载不了nodejs包,见博客
  • mvn clean package编译非常好用!
  • 也建议去官方提示步骤运行:

打包后可以在每个对应的target目录下,找到打包后的jar包:

  • java -jar 包名 :就可以执行的。
  • 注意要启动zookeeper注册中心。

开启的时候又遇到一个坑,就是zookeeper 的一些高版本中包含一个AdminServer默认的端口是8080,所以导致8080端口占用,dubbo的jar包没法启动。

解决办法:

  • 方式一:(不推荐,因为dubbo-admin访问不进去…) 修改zookeeper端口,去zoo.cfg文件下面添加admin.serverPort=xxxx。按道理可以,但是试了试admin管理页面进不去!目前没找到原因。
  • 方式二:(推荐使用,因为成功访问了admin管理页面了。) 不修改zookeeper的8080端口,修改dubbo-admin-server目录下面的application.properties文件添加server.port=8070,将其端口号改为8070。自然对应访问页面也就是变成http://localhost:8070/了。

(启动项目的时候,不难看出其实dubbo-admin-server其实就是springboot项目。此外,zookeeper也是使用java写的。)


dubbo-admin是管理页面应该属于Monitor监视部分,就算没有也不影响整个dubbo的工作:

  • dubbo admin是dubbo的图形页面控制台,具有服务查询、服务治理的功能。

7. Dubbo 环境搭建 之 创建 服务提供者 和 服务消费者 工程


理解服务消费者和服务提供者:

rpc 调用的 分布式事务问题_Dubbo_16


直接点就是,创建一个consumer服务消费者项目工程,再创建一个provider服务提供者项目功能。

consumer项目要调用provider项目的一些功能系统。

这样要通过dubbo将实现它们之间的调用。


注意事项:

因为要传输数据掉接口,所以不同项目之间调用的实体类和接口都是一样的,所以官方推荐创建一个公共项目,该公共项目包含公共的实体类接口等等。这样其他项目只需要依赖公共项目就可以了。

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_17


rpc 调用的 分布式事务问题_dubbo_18


rpc 调用的 分布式事务问题_rpc_19

搭建好上面的服务消费者 和 服务提供者相当于完成了下面的部分:

rpc 调用的 分布式事务问题_dubbo_20

8. Dubbo 环境搭建 之 服务提供者配置


1、将服务提供者注册到注册中心(暴露服务)

  • 1)、导入dubbo依赖(导入对应dubbo版本依赖,这里用的是dubbo2.6.2,因此是apache下面的dubbo,其他版本可能是alibaba版本的dubbo)。
  • rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_21

  • 2)、注册中心使用的是zookeeper,引入操作zookeeper的客户端。
  • rpc 调用的 分布式事务问题_Dubbo_22

  • 服务提供者项目和服务消费者项目导入的依赖:(这里他们必须要用相同版本)
<!-- 引入Dubbo3 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.2</version>
</dependency>

<!-- 注册中心使用的是zookeeper,引入操作zookeeper的客户端 -->
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-framework</artifactId>
  <version>2.12.0</version>
</dependency>
  • 3)、测试Dubbo,在服务提供者项目上面创建配置文件,如下:。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   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://dubbo.apache.org/schema/dubbo 
	        http://dubbo.apache.org/schema/dubbo/dubbo.xsd
	        http://code.alibabatech.com/schema/dubbo 
	        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            ">
	
	<!-- 1.指定当前服务(也就是应用的名字)(同样的服务名字相同,不要和别的服务同名) -->
	<dubbo:application name="user-service-provider"></dubbo:application>

	<!-- 2.指定注册中心的位置,官方有两种写法 -->
	<!-- <dubbo:registry address="zookeeper://127.0.0.1:2181" /> -->
	<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />

	<!-- 3.指定通信规则(指定通信协议和通信端口) 协议有很多可以去官方协议手册查看,目前使用dubbo协议。 -->
	<dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
	
	<!-- 
		4.暴露服务,将服务暴露出去就可能让别人使用。 
			interface指定暴露的接口。
			ref指向服务的真正的实现对象,也就是接口实现类。
	-->
	<dubbo:service interface="com.itholmes.gmall.service.UserService" ref="userServiceImpl"></dubbo:service>
	<!-- 服务实现 -->
	<bean id="userServiceImpl" class="com.itholmes.gmall.service.impl.UserServiceImpl"></bean>
	
</beans>

rpc 调用的 分布式事务问题_rpc_23


因此,我们这边只需要导入xml文件,在spring中执行就可以了:

package com.itholmes.gmall;

import java.io.IOException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApplication {
	public static void main(String[] args) throws IOException {
		ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
		//启动ioc容器
		ioc.start();
		//system.in.read()方法的作用是从键盘读出一个字符,然后返回它的Unicode码。
		int read = System.in.read();
		System.out.println(read);
	}
}

这样我们执行上面main方法,就可以在dubbo-admin管理页面查询到,我们暴露的服务了。

rpc 调用的 分布式事务问题_java_24


这样我们就暴露了一个服务提供者的一个接口。(这里使用的是最新版本的dubbo admin管理页面代码)大部分网页使用如下格式的dubbo admin管理页面代码(github上面master 0.2.0分支版本)

rpc 调用的 分布式事务问题_java_25

9. Dubbo 环境搭建 之 服务消费者配置


2、将服务消费者去注册中心订阅服务提供者的服务地址

  • 1)、同样先导入相同版本的dubbo和操作zookeeper的curator。
  • 2)、创建consumer.xml文件,配置dubbo对应文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
	   xmlns:context="http://www.springframework.org/schema/context"
       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/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://dubbo.apache.org/schema/dubbo 
	        http://dubbo.apache.org/schema/dubbo/dubbo.xsd
	        http://code.alibabatech.com/schema/dubbo 
	        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
            ">
            
	<!-- 1.指定当前服务(也就是应用的名字)(同样的服务名字相同,不要和别的服务同名) -->
	<dubbo:application name="order-service-consumer"></dubbo:application>
	
	<!-- 2.指定注册中心zookeeper的位置,官方有两种写法 -->
	<dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
	
	<!-- 
		3.声明需要调用的远程服务的接口;生成远程服务代理 
			interface:是我们要引用的服务提供者暴露的接口。
			id:起一个id,这样它在容器中就有了id名字,方便我们在代码中使用。
		这样我们只需要在需要的代码上面添加:
			@Service(或者其他的扫描)注意:这里使用spring的Service,不用dubbo的Service。
			@Autowired:自动装配就可以了。
	-->
	<dubbo:reference interface="com.itholmes.gmall.service.UserService" id="userService"></dubbo:reference>
	
	<!-- 4.添加扫描包,对应@Service -->
	<context:component-scan base-package="com.itholmes.gmall.service.impl"></context:component-scan>
</beans>

这样我们就可以测试Spring相关容器里面的内容:

  • 下面是Service调用的相关代码:
package com.itholmes.gmall.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itholmes.gmall.bean.UserAddress;
import com.itholmes.gmall.service.OrderService;
import com.itholmes.gmall.service.UserService;

/**
 * 1、将服务提供者注册到注册中心(暴露服务)
 *		1)、导入dubbo依赖(导入对应dubbo版本依赖,这里用的是dubbo3,因此是apache下面的dubbo,其他版本可能是alibaba版本的dubbo)。
 *		2)、注册中心使用的是zookeeper,引入操作zookeeper的客户端。
 *		3)、配置服务提供者。
 * 2、将服务消费者去注册中心订阅服务提供者的服务地址
 * @author Administrator
 *
 */

@Service//这里使用spring的Service,不用dubbo的Service。
public class OrderServiceImpl implements OrderService {

	@Autowired
	UserService userService;
	
	public void initOrder(String userId) {
		// TODO Auto-generated method stub
		System.out.println("用户ID:"+userId);
		//1.查询用户的收货地址,也就是调用user-service-provider项目中的查询收货地址的功能
		List<UserAddress> list = userService.getUserAddressList(userId);
		for(UserAddress user:list) {
			System.out.println(user);
		}
	}
	
}
  • 创建一个main方法来测试,是否能调用成功:
package com.itholmes.gmall;

import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.itholmes.gmall.service.OrderService;

public class MainApplication {
	public static void main(String[] args) throws IOException {
		ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
		OrderService bean = ioc.getBean(OrderService.class);
		//调用容器里面的Service方法
		bean.initOrder("1");
		System.out.println("调用完成...");
		System.in.read();
	}
}

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_26

10. Dubbo 环境搭建 之 监控中心(Monitor)


第一步:同样对应dubbo ops里面的master-0.2.0版本,下载dubbo-monitor:

rpc 调用的 分布式事务问题_java_27

第二步:直接进行mvn package打包操作,生成dubbo-monitor监控中心:

  • 注意是要解压打包后的压缩包。

这样解压出来的文件就是一个简易的监控中心了:

rpc 调用的 分布式事务问题_dubbo_28

第三步:去conf文件,配置dubbo.properties文件:

dubbo.container=log4j,spring,registry,jetty-monitor
dubbo.application.name=simple-monitor
dubbo.application.owner=dubbo
#dubbo.registry.address=multicast://224.5.6.7:1234

#zookeeper的注册中心的地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#也可以是其他注册中心的地址
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090

#protocol协议端口号,是其他服务与dubbo-monitor监控中心的通信端口
dubbo.protocol.port=7070

#监控中心Web页面的访问地址
dubbo.jetty.port=8888

dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${user.home}/monitor/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN

第四步:去assembly.bin目录下,启动dubbo-monitor。

rpc 调用的 分布式事务问题_java_29

第五步:给服务消费者和服务提供者的spring配置文件上面,配置上监控中心dubbo-monitor相关信息。

  • 可以去官方搜一下dubbo:xxx一些标签,找到对应参考手册,全是相关dubbo标签相关配置。
<!-- 
	有两种方式连接监控中心:
		方式一:指定protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。
		方式二:address="127.0.0.1:7070 ,直连dubbo-monitor地址,端口号是dubbo-monitor通信端口号。
-->
<dubbo:monitor protocol="registry"></dubbo:monitor>
<!-- <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor> -->

这样我们重新启动一下之前测试用的两个main方法,再查看dubbo-monitor监控中心页面:

rpc 调用的 分布式事务问题_rpc 调用的 分布式事务问题_30