目录
1、Dubbo简单简介
Dubbo是起源于阿里的电商系统,是一款开源、高性能、分布式的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,能与Spring进行无缝集成。
Dubbo架构组成如下:
模块说明:
1、Provider 暴露服务的提供者
2、Registry 服务注册中心
3、Consumer 调用服务的消费者
4、Container 服务运行容器
5、Monitor 统计服务调用次数和调用时间的监控中心
服务调用流程:
0、服务容器负责启动,加载,运行服务提供者
1、服务提供者在启动时,向注册中心注册自己提供的服务
2、服务消费者在启动时,向注册中心订阅自己所需的服务
3、注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
4、服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
5、服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
2、准备工作
2.1、可选择性下载dubbo-demo官方参照,也可不下载,我觉得自己还是能讲清楚的。^ ^ https://github.com/apache/incubator-dubbo/tree/dubbo-2.6.0
2.2、下载注册中心zookeeper,官方下载地址 http://zookeeper.apache.org/releases.html
2.3、使用dubbo专用的管理控制平台dubbo-admin,以图形化界面管理dubbo分布式服务。关于dubbo-admin的下载,网上资源不多,我也找了很久才找到,放上我自己上传的dubbo-admin资源地址 https://download.csdn.net/download/qq_33799366/10613864
3、初入茅庐(正式开始学习Dubbo)
3.1、zookeeper注册中心安装及配置
3.1.1、zookeeper下载到本地硬盘,解压压缩包,打开zookeeper目录是如下的(我的是zookeeper-3.4.13)
3.1.2、进入conf目录下,会看到一个配置文件为zoo_sample.cfg,将其更名为zoo.cfg即可。大家可以看到我这里有两个cfg文件,那是我复制了一个,改名为zoo.cfg的结果。
3.1.3、此时,注册中心已配置完成。进入zookeeper-3.4.13目录下的bin目录下,可以看到zkServer.cmd的启动程序,双击启动注册中心。
此时,cmd如果运行到此步骤,证明注册中心启动成功了。此时出现的 2181端口即为zoo.cfg中配置的zookeeper注册中心的默认端口。
如果没有进行3.1.2步骤,点击zkServer.cmd则会一闪而过,这个问题需要注意一下。
3.2、Dubbo公共服务API模块
3.2.1、创建maven工程
使用Eclipse新建Maven Project,勾选中Create a simple project和Use default Workspace location,点击Next
添加Group Id、Artifact Id、Version、Packing(选jar或者war),点击Finish
此时的Maven项目结构如此
此处可以将此maven项目装换成Web工程,当然不装换也可以,看个人喜好。但我想着,Dubbo本来是为电商网站开发的,还是弄成了Web工程。
关于Maven转换Web工程的方法:点击项目右键properties,选中Project Facets栏,点击灰色的Convert to faceted from...
点击之后页面如下,选中Java和Dybamic Web Module,此时下方会显示Further configuration available...
点击灰色文字,出现如下所示页面,包含项目名称,web根节点,
注意:web.xml配置文件需要勾选,勾选之后点击OK即可成功装换成一个Web工程
切换成功后,项目结构如下:
然后切换Java运行环境,选中JRE System Library右键Properties切换
3.2.2、src/main/java下新建包package,建立一个公共的服务接口DemoService
接口中写一个测试方法即可,代码如下
package com.steven.dubbo;
/**
* 服务提供者接口
* @author Administrator
*
*/
public interface DemoService {
String sayHello(String name);
}
3.3、创建暴露服务的服务提供者
3.3.1、新建Maven Project项目,创建细节就不在多说,参照dubbo-demo-api的创建,,创建结果如下
3.3.2、打开pom.xml文件,在里面添加jar包依赖,同时还需要将公共服务模块dubbo-demo-api引入进来,所有依赖如下所示:
<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>com.steven.dubbo</groupId>
<artifactId>dubbo-demo-provider_api</artifactId>
<version>1.0</version>
<dependencies>
<!-- 继承dubbo-demo-api的maven包 -->
<dependency>
<groupId>com.steven.dubbo</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.35.Final</version>
</dependency>
</dependencies>
</project>
3.3.3、在src/main/java下新建服务的实现类DemoServiceImpl,实现dubbo-demo-api中的DemoService接口,重写sayHello方法
package com.steven.dubbo;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.alibaba.dubbo.rpc.RpcContext;
/**
* 服务提供者实现类
*/
public class DemoServiceImpl implements DemoService {
public String sayHello(String name) {
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
}
}
3.3.4、在资源文件夹下,即src/main/resources下新建配置文件,文件名可以随意写,此处我的文件名为dubbo-demo-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用名称,用于计算依赖关系 -->
<dubbo:application name="demo-provider" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 使用dubbo协议,在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service实现类作为本地的一个bean -->
<bean id="demoService" class="com.steven.dubbo.DemoServiceImpl"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.steven.dubbo.DemoService" ref="demoService"/>
</beans>
3.3.5、在src/test/java下新建测试的服务提供者Provider.java
package com.steven.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 服务提供者接口实现类
* @author Administrator
*
*/
public class Provider {
public static void main(String[] args) throws Exception {
System.setProperty("java.net.preferIPv4Stack", "true");
//此处使用Spring引入dubbo-demo-provider.xml配置文件,需要对应位置才可匹配
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-demo-provider.xml"});
context.start();
System.out.println("服务提供者向注册中心申请服务");
System.in.read(); //持续消费,不加则只执行一次
context.close();
}
}
怕有些小伙伴没跟上,再放上一张服务提供者的结构图
到此,服务提供者就写好了,我们可以测试一波了 ^ ^
3.3.6、测试服务提供者
(1)需要保证注册中心已经先行启动,没有则双击zkServer.cmd启动,直至出现端口号2181。
(2)运行Provider,等待一小会儿,看看Console是否出现了如下结果
(3)同时,查看注册中心zookeeper的窗口中是否发生了变化
这就充分证明了服务提供者dubbo-demo-provicer_api已成功向注册中心提供了服务,到此,心里总算多了一点甜蜜的成就感 ^ ^
接下来,再接再励,继续学习开发消费者。
3.4、调用远程服务的服务消费者
3.4.1、创建服务消费者,命名为dubbo-demo-consumer_api,结构如下:
3.4.2、打开项目下的pom.xml文件,添加jar包依赖,同时添加对公共服务模块dubbo-demo-api的依赖。其实,在这儿的依赖,作者偷懒了,直接将dubbo-demo-provider_api下pom.xml文件拷贝过来就行。不过,还是将依赖包贴出来吧
<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>com.steven.dubbo</groupId>
<artifactId>dubbo-demo-consumer_api</artifactId>
<version>1.0</version>
<dependencies>
<!-- 继承dubbo-demo-api的maven包 -->
<dependency>
<groupId>com.steven.dubbo</groupId>
<artifactId>dubbo-demo-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.35.Final</version>
</dependency>
</dependencies>
</project>
3.4.3、src/main/resources下新建消费者配置文件,命名依然可修改,我用的是dubbo-demo-consumer.xml,里面的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 消费方应用名称,用于计算依赖关系,不是匹配条件,不要与提供方名称一样 -->
<dubbo:application name="demo-consumer"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<!-- <dubbo:registry address="multicast://224.5.6.7:1234"/> -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 生成远程服务代理,可以与本地bean一样使用 check属性,启动时候是否检查 一般设置成false 启动时候不检查 -->
<dubbo:reference id="demoService" check="false" interface="com.steven.dubbo.DemoService"/>
</beans>
3.4.4、src/test/java下新建消费者测试类Consumer.java
package com.steven.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Consumer {
public static void main(String[] args) {
System.setProperty("java.net.preferIPv4Stack", "true");
//同样的,配置文件需和dubbo-demo-consumer.xml在资源路径下对应
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-demo-consumer.xml"});
context.start();
DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy
try {
Thread.sleep(1000);
String hello = demoService.sayHello("world"); // call remote method
System.out.println("远程调用的结果:" + hello); // get result
System.in.read(); //持续消费,不加则只执行一次
} catch (Throwable throwable) {
throwable.printStackTrace();
}
context.close();
}
}
3.4.5、测试消费者
(1)需要在zookeeper注册中心开启后,并且dubbo-demo-provider_api注册了服务之后才可以进行消费
(2)运行Consumer,Consumer运行结果是否如下所示:
(3)点击Console右边的Display selected Console,切换到服务提供者Provider后,Console会更新消息
(4)而此时,注册中心zookeeper下也会更新日志
说明消费者已经获取到了服务提供者在注册中心注册的服务
3.5、使用Dubbo-admin管理服务
3.5.1、将下载的dubbo-admin-2.5.4.zip解压后可见如下结构:
按照dubbo-admin-2.5.4目录里面的txt文本进行操作解压war文件。Windows下,在此目录同时按住Shift和鼠标右键,打开命令行窗口,运行 jar xvf dubbo-admin-2.5.4.war 命令解压,待命令运行完毕,会在目录下生成这些文件
3.5.2、将该文件夹dubbo-admin-2.5.4放到apache tomcat服务器目录下的webapps目录下
3.5.3、使用dubbo-admin进行服务注册与消费测试
第一步,运行zookeeper注册中心;
第二步,运行tomcat服务器,在tomcat服务器目录下的bin目录中,双击startup.bat启动服务器;
第三步,tomcat启动后,访问http://localhost:8080/dubbo-admin-2.5.4 ,此时会显示密码授权,此密码为dubbo-admin的密码,在dubbo-admin-2.5.4/WEB-INF/dubbo.properties文件中可以查看
dubbo.properties中配置如下:
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
关于密码。管理员身份访问,用户名和密码均为root ;顾客身份访问,用户名和密码均为guest
输入用户名和密码,登陆成功之后界面如下:
点击服务治理--服务 可以看到此时并没有服务
第四步,注册服务。运行Provider程序,向注册中心注册服务之后,刷新dubbo-admin可以看到此时服务已成功注册,但没有被调用
第五步,调用服务。运行Consumer,待运行打印结果后刷新dubbo-admin可以看到,此时显示“正常”,表示服务有了消费者
注意:关闭服务提供者和消费者后,Dubbo-admin下刷新任然会有服务和消费者,这属正常现象,是dubbo-admin缓存机制的作用。
4、Dubbo集群及负载均衡
4.1、Dubbo集群的构建
4.1.1、先来看一下Dubbo集群构建之后的样子
从上图可以看出,只要服务提供者端口号不同,既可以构建多个服务提供者,即所谓的集群。
因此,可以写多个服务提供者,只要指定端口号不同,就能构成集群
4.1.2、为了测试使用,可以共用一个服务提供者dubbo-demo-provider_api的代码,只需要改变一下dubbo-demo-provider.xml文件中dubbo协议端口,再运行Provider即可注册一个服务。为了达到上图的效果,又做了两次服务注册。
修改成<dubbo:protocol name="dubbo" port="20881"/>后,保存,运行Provider
修改成<dubbo:protocol name="dubbo" port="20885"/>后,保存,运行Provider
4.2、负载均衡
负载均衡是分布式集群上的一个重要问题吧,我对负载均衡的理解就是:将一个(批)业务处理、计算任务分摊到集群上的计算机,合理分配计算机性能,使集群效率最大化。简单地说,就是能者多劳嘛。性能强劲的计算机就多分配任务,性能差点的就少分配任务。
不知道有没有心细的朋友看到过,Dubbo-admin的服务提供者后面的操作上有“倍权”,“半权”,而上面的操作还有“批量半权”,“批量倍权”的操作,还有权重,是否感到疑惑?
其实点击此种按钮,便是修改权重,即修改性能或者说是访问优先权,更改权重便能实现对集群负载的调节。
如果某一个节点(对应上面的服务)性能更强,或者需要优先访问,就可以对他增加权重;
如果某一个节点(服务)性能较差,或者不想优先访问,就减少它的权重。
以此,实现Dubbo的负载均衡
本项目的Demo下载地址:https://download.csdn.net/download/qq_33799366/10613843
Github上也分享了Demo的:https://github.com/stevenlin5520/dubbo-demo
学习博客参考自:https://blog.csdn.net/noaman_wgs/article/details/70214612
到此,就结束了!
感谢您的浏览,谢谢!