2.dubbox整合

Dobbo特点/简介(RPC,SOA框架):

Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。

作为RPC∶支持各种传输协议,如dubbo,hession,json,fastjson,底层采用mina,netty长连接进行传输!典型的provider和cusomer模式!

作为SOA:具有服务治理功能,提供服务的注册和发现!用zookeeper实现注册中心!启动时候服务端会把所有接口注册到注册中心,并且订阅configurators,服务消费端订阅provide, configurators,routers,订阅变更时,zk以会推送providers,configurators, routers,启动时注册长连接,进行通讯! proveider和proider动后,后台启动定时器,发送统计数据到monitor(监控中心提供各)!种容错机制和负载均衡策略!!

Dobbo优点:

​ 1.单一应用架构:功能内聚,减少部署时间和成本,数据库访问框架ORM是关键

​ 2.单独业务单独部署,功能上线快

Dobbo缺点:

​ 1.开发难度大

​ 2.涉及到联合开发,开发周期长

​ 3.依赖注册中心:zookeeper

安装Zookeeper:

(5条消息) windows环境下安装zookeeper教程详解(单机版)_风轩雨墨的博客-CSDN博客

安装Dubbox:

下载:dubbo-admin-0.0.1-SNAPSHOT.jar 的jar包

双击执行即可

idea建立分布式项目

1 创建项目:

  1. 创建一个Idea项目,并把除了下面两个和pom的文件全部删除。(此项目没有任何依赖)
  2. 删除pom依赖中的dependency和builder。
  3. 刷新maven项目使项目显现,在项目上右键新建三个model。
  4. 三个项目分别是center-api、center-consumer和center-provide。

2 最外部的pom修改

  1. 添加打包方式
  2. 增加模块管理系统。
  3. 添加dobbo和zkclient依赖, 以及api模块,并在properties中统一管理项目依赖版本。

3 内层的pom修改

  1. 将最外层pom中groupId标签、artifactId标签、version标签复制到内层pom中parent标签中的对应标签上,并添加relativePath标签
  2. 向provide和consumer的pom中添加外层依赖,dobbo和zkclient依赖, 以及api模块,无需版本号
  3. 删除api模块pom中的build,并添加打包方式

最外层pom

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.lcywings.sbt</groupId>
    <artifactId>springboot-09-dubbox</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- 父模块的打包类型必须是pom,作为子模块的统一依赖pom -->
    <packaging>pom</packaging>
    <name>springboot-09-dubbox</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <!-- 统—管理项目依赖版本 -->
        <dubbo.version>0.1.0</dubbo.version>
        <zkclient.version>0.10</zkclient.version>
    </properties>

    <!-- 模块管理 -->
    <modules>
        <module>edoccenter-api</module>
        <module>edoccenter-consumer</module>
        <module>edoccenter-provider</module>
    </modules>

    <!-- 管理所有的版本依赖,子模块中添加依赖,如果已经被父pom进行统一管理,就不需要再写版本号了
            注意,dependencyManagement里面的依赖不会自动下载jar包依赖,一般都是先在外面下载好依赖,在添加到统—管理 -->
 <dependencyManagement>
    <dependencies>
        <!-- dubbo begin springboot 1.5.9,对应dubbo 0.1.0 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <!-- dubbo end -->

        <!-- zkclient begin -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>${zkclient.version}</version>
        </dependency>
        <!-- zkclient end -->

        <!-- api模块是consumer和provider公共依赖-->
        <dependency>
            <groupId>com.lcywings.sbt</groupId>
            <artifactId>edoccenter-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- api end -->
    </dependencies>
</dependencyManagement>

</project>

consumer模块pom

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.lcywings.sbt</groupId>
        <artifactId>springboot-09-dubbox</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lcywings.sbt</groupId>
    <artifactId>edoccenter-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>edoccenter-consumer</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- dubbo begin springboot 1.5.9,对应dubbo 0.1.0 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!-- dubbo end -->

        <!-- zkclient begin -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>
        <!-- zkclient end -->

        <!-- api模块是consumer和provider公共依赖-->
        <dependency>
            <groupId>com.lcywings.sbt</groupId>
            <artifactId>edoccenter-api</artifactId>
        </dependency>
        <!-- api end -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

provider模块pom

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.lcywings.sbt</groupId>
        <artifactId>springboot-09-dubbox</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lcywings.sbt</groupId>
    <artifactId>edoccenter-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>edoccenter-provider</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- dubbo begin springboot 1.5.9,对应dubbo 0.1.0 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <!-- dubbo end -->

        <!-- zkclient begin -->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>
        <!-- zkclient end -->

        <!-- api模块是consumer和provider公共依赖-->
        <dependency>
            <groupId>com.lcywings.sbt</groupId>
            <artifactId>edoccenter-api</artifactId>
        </dependency>
        <!-- api end -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

api模块pom

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.lcywings.sbt</groupId>
        <artifactId>springboot-09-dubbox</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lcywings.sbt</groupId>
    <artifactId>edoccenter-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>edoccenter-api</name>
    <!-- api模块修改打包方式为jar,注意目的就是作为公共依赖模块jar包,提供给consumer和provider使用,实现多模块中代码的共用
     注意:必须去除spring-boot-maven-plugin依赖(打的包是可执行jar)
    -->
    <packaging>jar</packaging>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

Dubbo项目开发(业务实现)

查询功能实现

分布式项目:

  1. 在api模块下:beans包->创建实体类并且序列化增加序列号,api包下创建公用接口类;
  2. 在consumer模块下:controller包->控制类,service包->服务类,修改配置文件
  3. 在provider模块下:provider包->公用接口实现类,修改配置文件
  4. 在provider模块下的主启动类上加上@EnableDubbo注解

beans实体类

package com.lcywings.sbt.beans;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

/**
 * Created on 2021/8/2.
 * <p>
 * Author : Lcywings
 * <p>
 * Description : 电子文档详情实体
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class EdocEntry implements Serializable {

    /**
     * 不序列化,实体对象就不可以再网络中进行传输-不同jvm之间必须实现序列化,
     * 否则接口调用报错( 不序列化,实体对象就不可以再网络中进行传输-不同jvm之间)
     * Serializable class without 'serialversionUID"
     */
    private static final long serialVersionUID = -7512611965543990248L;

    /**
     * 文档编号
     */
    private Integer id;

    /**
     * 文档分类编号
     */
    private Integer cid;

    /**
     * 文档标题
     */
    private String title;

    /**
     * 文档摘要
     */
    private String summary;

    /**
     * 文档作者
     */
    private String uploadUser;

    /**
     * 文档创建时间
     */
    private Date createDate;

}

api下公共接口类

package com.lcywings.sbt.api;

import com.lcywings.sbt.beans.EdocEntry;

/**
 * Created on 2021/8/2.
 * <p>
 * Author : Lcywings(
 * <p>
 * Description : 电子文档操作公共接口
 */
public interface EdocEntryApi {

    /**
     * @author : Lcywings
     * @date : 2021/8/2 17:19
     * @acl : true
     * @description : 根据文档编号查询文档详情
     */
    EdocEntry getEdocEntryById(Integer id);
}

controller包下控制类

package com.lcywings.sbt.controller;

import com.lcywings.sbt.beans.EdocEntry;
import com.lcywings.sbt.service.EdocEntryService;
import lombok.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created on 2021/8/2.
 * <p>
 * Author : Lcywings
 * <p>
 * Description :
 */
@RestController
public class EdocEntryContorller {

    @Autowired
    private EdocEntryService edocEntryService;

    /**
     * @author : Lcywings
     * @date : 2021/8/2 16:49
     * @acl : true
     * @description : 根据电子文档编号查询电子文档详情
     */
    @GetMapping("/edocEntry")
    public EdocEntry edocEntry(@RequestParam Integer id) {
        System.out.println("======= 根据文档编号:" + id + "查询文档详情 ======");
        return edocEntryService.queryEdocEntryById(id);
    }

}

service下服务类接口以及其实现类

package com.lcywings.sbt.service;

import com.lcywings.sbt.beans.EdocEntry;

/**
 * Created on 2021/8/2.
 * <p>
 * Author : Lcywings
 * <p>
 * Description : 电子文档业务接口
 */
public interface EdocEntryService {

    /**
     * @author : Lcywings
     * @date : 2021/8/2 16:57
     * @acl : true
     * @description :  根据电子文档编号查电子文档详情
     */
    EdocEntry queryEdocEntryById(Integer id);
}
package com.lcywings.sbt.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.lcywings.sbt.api.EdocEntryApi;
import com.lcywings.sbt.beans.EdocEntry;
import com.lcywings.sbt.service.EdocEntryService;
import org.springframework.stereotype.Service;

/**
 * Created on 2021/8/2.
 * <p>
 * Author : Lcywings
 * <p>
 * Description : 电子文档业务实现类
 */
@Service // spring注解,业务组件
public class EdocEntryServiceImpl implements EdocEntryService {

    @Reference  // 是alibaba包下,注册为消费者,订阅提供的服务
    private EdocEntryApi edocEntryApi;

    @Override
    public EdocEntry queryEdocEntryById(Integer id) {
        return null;
    }
}

provider中的配置文件

# 端口号
server.port=8089
# dubbo+zookeeper配置
dubbo.application.name=edoc-provider
# 注册中心地址
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper
dubbo.protocol.port=20880

provider包下共用接口实现类

package com.lcywings.sbt.provider;

import com.alibaba.dubbo.config.annotation.Service;
import com.lcywings.sbt.api.EdocEntryApi;
import com.lcywings.sbt.beans.EdocEntry;

import java.util.Date;

/**
 * Created on 2021/8/2.
 * <p>
 * Author : Lcywings
 * <p>
 * Description : 电子文档功能实现服务提供者
 */
@Service    // 在alibaba的包下面的,将其服务注册为提供者
public class EdocEntryProvider implements EdocEntryApi {
    @Override
    public EdocEntry getEdocEntryById(Integer id) {
        // TODO 通过jpa或者mybatis实现数据查询(依赖只能加在提供者模块)
        return EdocEntry.builder().id(id).cid(1).title("雪中悍刀行").summary("大人物小人物。是珠子,大故事小故事,是串线。")
                .createDate(new Date()).build();
    }
}

consumer中的配置文件

# 端口号
server.port=8090
# dubbo+zookeeper配置
dubbo.application.name=edoc-consumer
# 注册中心地址
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper

provider主启动类

package com.lcywings.sbt;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class EdoccenterProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(EdoccenterProviderApplication.class, args);
    }
}

课后作业:

在提供者模块,提供一个通过mybatis或者jpa实现的查询电子文档列表功能,在消费者调用此功能获取电子文档列表

要求:

  1. mybatis或者jpa的依赖,只能在提供者模块依赖
  2. 加swagger在线接口,只能在consumer模块依赖

Jpa使用注意事项:

@Colume中name=""必须是user_name的类似形式,因为他只能识别到此种形式。就算数据库中的列明为userName,@Colume中写userName也是无法识别到数据库的。解决办法是修改数据库列明,使她符合规范

Jpa无需增加@MapperScan注解

模块依赖

每个模块依赖自己需要的依赖,不要全部写在公共模块中


新增模块

直接复制相应的需要重复功能的模块,然后修改一下参数:

  1. pom中的artifactId标签
  2. pom中的name标签
  3. properties中的端口号
  4. properties中的注册中心端口号dubbo.protocol.port

如果要删除模块,先右键Remove Module,再右键Delete

扫描所有的服务提供

# 扫描所有的服务提供者(@Service注解的类)
dubbo.scan.base-packages=com.lcywings.sbt.provider

dubbo.protocol.port=-1:注册中心端口号自动累加

# 如果是-1,默认就是从20880开始,累加,20881,20882
dubbo.protocol.port=-1

提供者模块Dubbo操作

倍权:表示该提供者模块权重翻倍,使得服务器有更大概率选择该模块提供数据。

半权:表示该提供者模块权重减半,使得服务器有更小概率选择该模块提供数据。

禁用:

消费者模块Dubbo操作

禁止:直接禁用客户端使用提供者模块,此时消费者模块无法调用此提供者模块。强行调用会报错。

屏蔽:屏蔽后,将不发起远程调用,直接在客户端返回空对象。

容错:容错后,当远程调用失败时,返回空对象。

负载均衡

随机:默认就是随机,当请求到达服务器时到到各个端口上。

轮询:服务器依次将请求分配到各个端口上。

最少并发:服务器永远按最少并发数量将请求进行分配。

Q.E.D.