Spring Cloud Alibaba 教程 | Dubbo(一)

Dubbo产生的背景

Dubbo全称是Apache Dubbo,是一款高性能Java RPC框架。Dubbo由阿里巴巴工程师研发,并且已经贡献给了Apache软件基金会。
官网地址:http://dubbo.apache.org/zh-cn/index.html

在这里插入图片描述

Dubbo是在传统应用的单体架构和常规的垂直架构无法再应对大规模应用的背景下产生的。这时候阿里巴巴需要将企业内部大型应用的核心业务抽取出来拆分成一个个相对独立且稳定的模块服务,从而形成一种新的架构,这种架构就是分布式服务架构,Dubbo将被设计成能够支持这种新的架构的基础框架。

那么传统的的单体架构(垂直架构)和分布式服务架构有哪些区别呢?我们通过下面的表格进行比较一下:

单体架构(垂直架构) 分布式服务架构
新功能研发成本 研发成本高 研发成本较低
部署成本 容易部署,对应用影响很大 部署难度大,对应用影响较小
系统稳定性 故障影响大,稳定性低 故障影响小,稳定性高
架构设计成本 难度小,设计成本低 难度大,设计成本高
系统性能 响应较快,但吞吐量小 响应慢,但吞吐量大
系统维护成本 维护成本低 维护成本高,运维负责
系统扩展性 扩展性很差 扩展性很好
排查问题 简单 复杂

在使用分布式服务架构进行大规模服务化之前,Dubbo需要解决服务的暴露和调用远程服务这两个问题,所以需要有一个服务注册中心,动态地注册和发现服务,使服务的位置透明。并通过在消费方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对 F5 硬件负载均衡器的依赖,也能减少部分成本。
此外由于使用了分布式服务架构,服务实例大规模增加,监控服务的调用量、响应时间、负载等等这些信息将变得非常必要,能够让运维知道服务需要多少机器支撑,什么时候该加机器。


在这里插入图片描述

Dubbo架构

Dubbo架构图

在这里插入图片描述

节点角色说明

节点 角色说明
Provider 暴露服务的服务提供方
Consumer 调用远程服务的服务消费方
Registry 服务注册与发现的注册中心
Monitor 统计服务的调用次数和调用时间的监控中心
Container 服务运行容器

调用关系说明

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

Dubbo快速入门

第一步:使用Zookeeper作为Dubbo框架的注册中心。ZooKeeper是一个分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。Dubbo默认推荐使用Zookeeper作为其注册中心。

zookeeper下载地址(使用3.4.13版本):https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/

在这里插入图片描述

下载完成之后,拷贝到Linux机器下运行,windows环境也是可以的。

#上传文件到linux服务器使用tar命令解压
tar -zxvf zookeeper-3.4.13.tar.gz
#进入到zookeeper目录
cd zookeeper-3.4.13
#创建数据目录
mkdir data
#复制配置文件
cp conf/zoo_sample.cfg conf/zoo.conf
#根据需要修改相关配置 这里我只修改了data目录
vi conf/zoo.conf
在这里插入图片描述

在bin目录执行./zkServer.sh start 启动Zookeeper。


在这里插入图片描述

测试Zookeeper是否启动正常。

[root@test1 bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/server/zookeeper-3.4.13/bin/../conf/zoo.cfg
Mode: standalone

第二步:安装Dubbo管理台Dubbo Admin。Dubbo提供了一个简易的管理台,通过管理台可以看到注册到注册中心Zookeeper上面的服务的基本情况。

Dubbo管理台下载地址:https://github.com/apache/dubbo-admin/tree/master

在这里插入图片描述

在这里插入图片描述

下载完成之后解压进入到dubbo-admin文件夹,使用maven命令mvn package编译打包Dubb-admin。
在这里插入图片描述

打包完成之后得到dubbo-admin-0.0.1-SNAPSHOT.jar,这是一个springboot项目,所以可以直接使用java -jar dubbo-admin-0.0.1-SNAPSHOT.jar命令运行Dubbo管理台。

注意:运行Dubbo管理台之前需要先运行zookeeper注册中心。

Dubbo管理台默认端口是7001,用户名和密码都是root。


在这里插入图片描述

在这里插入图片描述

第三步: 创建测试项目dubbo-learn

在这里插入图片描述

<modules>
    <module>provider-service</module>
    <module>api-service</module>
    <module>consumer-service</module>
</modules>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <dubbo.version>2.6.2</dubbo.version>
    <curator.version>2.12.0</curator.version>
</properties>

api-service模块

@Data
public class UserInfo implements Serializable {
    private String name;
    private String address;
    private Date birthday;
    private Integer age;
}

public interface UserInfoService {
    List<UserInfo> userInfoList(String name);
}

第四步: 提供者服务依赖Dubbo框架。

<dependencies>
    <dependency>
        <groupId>com.luke.dubbo</groupId>
        <artifactId>api-service</artifactId>
        <version>1.0</version>
    </dependency>
    <!--dubbo-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>${dubbo.version}</version>
    </dependency>
    <!--操作zookeeper客户端-->
   <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>${curator.version}</version>
    </dependency>
</dependencies>
public class UserInfoServiceImpl implements UserInfoService {

    @Override
    public List<UserInfo> userInfoList(String name) {
        System.out.println("---------------------userInfoList---------------------"+name);
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setName(name);
        userInfo1.setAddress("beijing");
        userInfo1.setAge(18);
        userInfo1.setBirthday(new Date());
        UserInfo userInfo2 = new UserInfo();
        userInfo2.setName(name);
        userInfo2.setAddress("shanghai");
        userInfo2.setAge(19);
        userInfo2.setBirthday(new Date());
        return Arrays.asList(userInfo1,userInfo2);
    }
}

<?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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
             http://dubbo.apache.org/schema/dubbo
             http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系(服务名称) -->
    <dubbo:application name="provider-service"/>

    <!--指定注册中心地址-->
    <dubbo:registry protocol="zookeeper" address="192.168.0.127:2181"/>

    <!-- 用dubbo协议在20880端口暴露服务(低层通讯框架Netty监听端口) -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.luke.dubbo.api.UserInfoService" ref="userInfoServiceImpl"/>

    <!-- 和本地bean一样实现服务 -->
    <bean id="userInfoServiceImpl" class="com.luke.dubbo.provider.service.impl.UserInfoServiceImpl"/>

</beans>
public class ProviderApp {
    public static void main(String[] args) throws Exception{
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("provider.xml");
        context.start();
        System.in.read(); // 按任意键退出
    }
}

启动provider-service服务后,可以在Dubbo管理台看到注册信息。


在这里插入图片描述

第五步: 消费者服务依赖Dubbo框架。

<dependencies>
   <dependency>
       <groupId>com.luke.dubbo</groupId>
       <artifactId>api-service</artifactId>
       <version>1.0</version>
   </dependency>
   <!--dubbo-->
   <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>dubbo</artifactId>
       <version>${dubbo.version}</version>
   </dependency>
   <!--操作zookeeper客户端-->
   <dependency>
       <groupId>org.apache.curator</groupId>
       <artifactId>curator-framework</artifactId>
       <version>${curator.version}</version>
   </dependency>
</dependencies>
public interface TestService {
    List<UserInfo> userInfoList(String name);
}
@Service
public class TestServiceImpl implements TestService {

    @Autowired
    private UserInfoService userInfoService;

    @Override
    public List<UserInfo> userInfoList(String name) {
        return userInfoService.userInfoList(name);
    }
}

<?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://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
             http://dubbo.apache.org/schema/dubbo
             http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--扫描包-->
    <context:component-scan base-package="com.luke.dubbo.consumer"></context:component-scan>

    <!-- 提供方应用信息,用于计算依赖关系(服务名称) -->
    <dubbo:application name="consumer-service"/>

    <!--指定注册中心地址-->
    <dubbo:registry protocol="zookeeper" address="192.168.0.127:2181"/>
    
    <!--引用远程服务-->
    <dubbo:reference id="userInfoService" interface="com.luke.dubbo.api.UserInfoService" />

</beans>
public class ConsumerApp {
    public static void main(String[] args) throws Exception{
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("consumer.xml");
        TestService testService = context.getBean(TestService.class);
        List<UserInfo> userInfos = testService.userInfoList("test");
        userInfos.forEach(userInfo -> System.out.println(userInfo.getAddress()));
        context.start();
        System.in.read();
    }
}

第六步:测试验证。

执行消费者服务后,控制打印出调用结果:

beijing
shanghai

同时可以在Dubbo管理台看到消费者服务注册信息。


在这里插入图片描述

关注公众号了解更多原创博文

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342