硬核!Dubbo分布式服务框架入门教程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了硬核!Dubbo分布式服务框架入门教程相关的知识,希望对你有一定的参考价值。

参考技术A

Dubbo是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。

Dubbo内部使用了 Netty、Zookeeper,保证了高性能高可用性,使用Dubbo可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用和灵活扩展,使前端应用能更快速的响应多变的市场需求。

另外,分布式架构可以承受更大规模的并发流量。

Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起。

当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本。

缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加越来越难以维护

垂直应用架构解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率。

缺点:但是在垂直架构中相同逻辑代码需要不断地复制,不能复用。

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心

随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。

课程目标:

了解远程调用PRC的概念,分布式应用为什么使用RPC, 基于PRC协议的Dubbo的使用。Dubbo框架的特点,框架的组件;基于Dubbo服务提供者,消费者,注册中心Zookeeper的分布式应用的开发部署, Dubbo的负载均衡实现。微服务的开发. Spring + Dubbo + Zookeeper + Linux

适用人群:

适合有Java基础,要进入到互联网行业的开发人员,微服务开发。

动力节点的Dubbo课程以实战为主讲解,从基础开始手把手式地详细讲解RPC概念,PRC在分布式应用的重要作用。Dubbo分布式服务框架的应用入门基础。传统应用到分布式以及微服务的转变思想。Dubbo协议的特点。Dubbo分布式服务的详细开发流程、Dubbo服务的实施部署,Zookeeper的服务管理等。

课程目录:

•001.dubbo视频教程-dubbo前言

•002.dubbo视频教程-dubbo概述

•003.dubbo视频教程-初识dubbo

•004.dubbo视频教程-dubbo前世今生

•005.dubbo视频教程-dubbo结构概述-1

•006.dubbo视频教程-dubbo结构概述-2

•007.dubbo视频教程-dubbo的使用-直连方式-1

•008.dubbo视频教程-dubbo的使用-直连方式-2

•009.dubbo视频教程-dubbo的使用-直连方式-3

•010.dubbo视频教程-dubbo的使用-直连方式-4

•011.dubbo视频教程-dubbo服务化最佳实践-概述

•012.dubbo视频教程-dubbo服务化最佳实践-1

•013.dubbo视频教程-dubbo服务化最佳实践-2

•014.dubbo视频教程-dubbo服务化最佳实践-3

•015.dubbo视频教程-dubbo服务化最佳实践-4

•016.dubbo视频教程-dubbo服务化最佳实践-5

•017.dubbo视频教程-注册中心概述

•018.dubbo视频教程-windows下安装及配置zookeeper

•019.dubbo视频教程-linux下安装及配置zookeeper

•020.dubbo视频教程-内容回顾

•021.dubbo视频教程-dubbo实例-使用注册中心-1

•022.dubbo视频教程-dubbo实例-使用注册中心-2

•023.dubbo视频教程-dubbo实例-使用注册中心-3

•024.dubbo视频教程-dubbo实例-使用注册中心-4

•025.dubbo视频教程-dubbo实例-使用注册中心-5

•026.dubbo视频教程-dubbo实例使用linux注册中心

•027.dubbo视频教程-dubbo实例-版本号version的使用-1

•028.dubbo视频教程-dubbo实例-版本号version的使用-2

•029.dubbo视频教程-dubbo实例-版本号version的使用-3

•030.dubbo视频教程-dubbo实例-版本号version的使用-4

•031.dubbo视频教程-解决学生问题

•032.dubbo视频教程-dubbo配置中常见属性

•033.dubbo视频教程-dubbo的高稳定性

•034.dubbo视频教程-监控中心-1

•035.dubbo视频教程-监控中心-2

Dubbo实战视频教程:

https://www.bilibili.com/video/BV1Sk4y197eD

Dubbo全套资料下载

http://www.bjpowernode.com/?toutiao

Dubbo实践入门示例

dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求。

下面将介绍如何搭建一个简单的示例程序(用maven构建)。

众所周知,RPC调用涉及到消费者、提供者和接口,所以需要在maven工程warehouse-component-parent里面新建3个模块,分别是warehouse-component-dubbo-facade(接口)、warehouse-component-dubbo-provider(提供者)和warehouse-component-dubbo-consumer(消费者)。对应的pom文件如下。

warehouse-component-parent:

<?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.wu</groupId>
    <artifactId>warehouse-component-parent</artifactId>
    <version>0.0.1</version>
    <packaging>pom</packaging>
    <name>component warehouse parent</name>

    <modules>
        <module>warehouse-component-dubbo-facade</module>
        <module>warehouse-component-dubbo-provider</module>
        <module>warehouse-component-dubbo-consumer</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>4.12</junit.version>
        <spring.version>4.3.8.RELEASE</spring.version>
        <log4j.over.slf4j.version>1.7.25</log4j.over.slf4j.version>
        <jcl.over.slf4j.version>1.7.25</jcl.over.slf4j.version>
        <logback.version>1.2.3</logback.version>
        <dubbo.version>2.5.3</dubbo.version>
        <zkclient.version>0.1</zkclient.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>

            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!-- logback -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${jcl.over.slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>log4j-over-slf4j</artifactId>
                <version>${log4j.over.slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>${logback.version}</version>
            </dependency>

            <!-- dubbo -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- zkclient -->
            <dependency>
                <groupId>com.github.sgroschupf</groupId>
                <artifactId>zkclient</artifactId>
                <version>${zkclient.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <dependency>
                <groupId>org.wu</groupId>
                <artifactId>warehouse-component-dubbo-facade</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

 warehouse-component-dubbo-provider:

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.wu</groupId>
        <artifactId>warehouse-component-parent</artifactId>
        <version>0.0.1</version>
    </parent>
    <artifactId>warehouse-component-dubbo-provider</artifactId>
    <name>warehouse-component-dubbo-provider</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <!-- zkclient -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>

        <!-- logback -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>

        <dependency>
            <groupId>org.wu</groupId>
            <artifactId>warehouse-component-dubbo-facade</artifactId>
        </dependency>
    </dependencies>
</project>

 warehouse-component-dubbo-consumer:

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.wu</groupId>
        <artifactId>warehouse-component-parent</artifactId>
        <version>0.0.1</version>
    </parent>
    <artifactId>warehouse-component-dubbo-consumer</artifactId>
    <name>warehouse-component-dubbo-consumer</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <!-- zkclient -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>

        <!-- logback -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>

        <dependency>
            <groupId>org.wu</groupId>
            <artifactId>warehouse-component-dubbo-facade</artifactId>
        </dependency>
    </dependencies>
</project>

工程使用的日志框架为logback,配置文件如下:

<?xml version="1.0" encoding="UTF-8" ?>

<configuration scan="true" scanPeriod="3 seconds">

    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
        <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger:%L] %msg%n</pattern>
        </layout>
    </appender>

    <appender name="ALL_LOG_FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>warehouse_component.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                warehouse_component.%d{yyyy-MM-dd}.log
            </FileNamePattern>
        </rollingPolicy>

        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger:%L] %msg%n</pattern>
        </layout>
    </appender>
    
    <appender name="ERROR_LOG_FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>warehouse_component_error.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                warehouse_component_error.%d{yyyy-MM-dd}.log
            </FileNamePattern>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>

        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger:%L] %msg%n</pattern>
        </layout>
    </appender>

    <root>
        <level value="INFO" />
        <appender-ref ref="STDOUT" />
        <appender-ref ref="ALL_LOG_FILE" />
        <appender-ref ref="ERROR_LOG_FILE" />
    </root>

</configuration>

上述配置信息都设置好后,就可以进行dubbo程序的开发了。首先,定义dubbo接口,在warehouse-component-dubbo-facade模块中定义一个接口:

package org.warehouse.component.dubbo.facade;

public interface DemoFacade {
    /**
     * dubbo接口
     */
    String sayHello(String name);
}

接口定义好后,dubbo服务提供者warehouse-component-dubbo-provider需要实现该接口,进行相关的业务逻辑处理。

package org.warehouse.component.dubbo.provider;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.stereotype.Service;
import org.warehouse.component.dubbo.facade.DemoFacade;

import com.alibaba.dubbo.rpc.RpcContext;

@Service("demoFacadeImpl")
public class DemoFacadeImpl implements DemoFacade {

    @Override
    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 form provider: " + RpcContext.getContext().getLocalAddress();
    }

}

并通过spring配置文件(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:context="http://www.springframework.org/schema/context"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 自动检测并装配bean -->
    <context:component-scan base-package="org.warehouse.component.dubbo.provider" />

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="provider-of-hello-world-app" />

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry protocol="zookeeper" address="192.168.1.103:2181" />
    
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="org.warehouse.component.dubbo.facade.DemoFacade" ref="demoFacadeImpl" />

</beans>

现在可以通过加载spring配置启动服务提供者了(运行以下代码):

package org.warehouse.component.dubbo.provider;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Provider {

    public static void main(String[] args) throws IOException {
        @SuppressWarnings("resource")
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-provider.xml");
        context.start();

        System.in.read();
    }

}

服务提供者启动之后,服务消费者通过spring配置(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:context="http://www.springframework.org/schema/context"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 自动检测并装配bean -->
    <context:component-scan base-package="org.warehouse.component.dubbo.consumer" />
    
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="consumer-of-hello-world-app" />

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry protocol="zookeeper" address="192.168.1.103:2181" />
    
    <dubbo:reference id="demoFacade" interface="org.warehouse.component.dubbo.facade.DemoFacade" />

</beans>

加载Spring配置,并调用远程服务(这里是通过spring unit test的方式):

package org.warehouse.component.dubbo.consumer;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.warehouse.component.dubbo.facade.DemoFacade;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:dubbo-consumer.xml"})
public class ConsumerTest {

    @Autowired
    ApplicationContext context;
    
    @Test
    public void testDemoFacade() {
        DemoFacade facade = (DemoFacade) context.getBean("demoFacade");
        String hello = facade.sayHello("world");
        
        System.out.println(hello);
    }
}

服务的调用就像是方法本地调用一样简单,这其实是dubbo将底层通信封装好了,我们只需要关注业务逻辑实现。

在spring文件中配置dubbo服务时,eclipse会出现无法找到dubbo.xsd文件的问题。在本工程的解决办法是将dubbo-2.5.3.jar包中的dubbo.xsd文件(META-INF文件夹中)复制到文件系统中,然后

windows -> Preferrences -> XML -> XML Catalog

Add -> Catalog Entry -> File System 选择刚刚下载的文件路径

修改key值和配置文件的http://code.alibabatech.com/schema/dubbo/dubbo.xsd 相同

保存。。在xml文件右键validate ok解决了。

技术分享

最后还有一点需要说明:dubbo和zkclient需要排除对log4j的依赖后才可以使用logback来记录详细日志,具体排除方式已经在warehouse-component-parent的pom文件中展示。

以上是关于硬核!Dubbo分布式服务框架入门教程的主要内容,如果未能解决你的问题,请参考以下文章

dubbo分布式服务框架入门

资源 | 分布式Dubbo视频讲解教程

Dubbo实践入门示例

这么说吧,dubbo很简单,其实就是一个远程服务调用的框架

dubbo入门

分布式与微服务系列分布式RPC框架Apache Dubbo服务