后端框架:SpringBoot+Mybatis+Dubbox(zookeeper+dubbo-admin)

一、Dubbox 框架

Dubbox 是一个分布式服务框架,其前身是阿里巴巴开源项目 Dubbo ,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在 Dubbo 基础上进行优化,并继续维护,为了与原有的 Dubbo 区分,故将其命名为 Dubbox。

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

节点角色说明:

Provider: 暴露服务的服务提供方

Consumer: 调用远程服务的服务消费方

Registry: 服务注册与发现的注册中心

Monitor: 统计服务的调用次调和调用时间的监控中心

Container: 服务运行容器。

调用关系说明:

0. 服务容器负责启动,加载,运行服务提供者。

1. 服务提供者在启动时,向注册中心注册自己提供的服务。

2. 服务消费者在启动时,向注册中心订阅自己所需的服务。

3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

 二、注册中心 Zookeeper的安装与启动

官方推荐使用 zookeeper 注册中心。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbox 服务的注册中心,工业强度较高,可用于生产环境。

 windows安装zookeeper

 第一步:下载安装包

官网地址:https://zookeeper.apache.org/releases.html


下载的文件如下:

 第二步:开始安装

解压后:

1)、将conf目录下的zoo_sample.cfg文件,复制一份,重命名为zoo.cfg

2)、在安装目录下面新建一个空的data文件夹和log文件夹

 

 3)、修改zoo.cfg配置文件,将dataDir=/tmp/zookeeper修改成zookeeper安装目录所在的data文件夹,再添加一条添加数据日志的配置。

tickTime=2000
initLimit=10
syncLimit=5
dataDir=F:/work/apache-zookeeper-3.7.0-bin/data
dataLogDir=F:/work/apache-zookeeper-3.7.0-bin/log
clientPort=2181

注意:dataDir和dataLogDir这两个路径中是/而不是\,因为windows的文件分隔符是/,而不是.

tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。

initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒

syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2*2000=4 秒

dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。

clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

 第三步:启动程序

双击zkServer.cmd

 三、服务提供者

1、引入依赖:
<!--dubbo-->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <!--zookeeper-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

2、dubbo的配置

#dubbo
dubbo.application.name=pts-server  #应用名
dubbo.protocol.name=dubbo  #协议名
dubbo.protocol.port=20880  #dubbo服务暴露的端口
dubbo.provider.timeout=20000
dubbo.registry.address=zookeeper://127.0.0.1:2181  #zookeeper地址

注意:zookeeper的ip地址12.0.0.1,如果该ip的地址改为其他电脑的ip地址,那么你访问的服务就不是本地的服务了,而是其他电脑上的服务

3、服务提供方接口和实现类

创建service接口

public interface IUserService {
  public String getName();
}

创建service接口实现类UserServiceImpl2

import com.alibaba.dubbo.config.annotation.Service;
import com.ljxx.service.IUserService;

@Service
public class UserServiceImpl2 implements IUserService {
    @Override
    public String getName() {
        return "itcast";
    }
}

注意:Service 注解与原来不同,需要引入 com.alibaba 包下的。

四、服务消费者

1、引入依赖
<!--dubbo-->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
        <!--zookeeper-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

2、dubbo配置

#dubbo
dubbo.application.name=pts-interface
dubbo.registry.address=zookeeper://127.0.0.1:2181

3、将服务提供方的接口拷贝到服务消费方

public interface IUserService {
    public String getName();
}

4、编写controller

import com.alibaba.dubbo.config.annotation.Reference;

@Controller
@RequestMapping("/user")
public class UserController {
    @Reference
    private IUserService userService;
    @RequestMapping("/showName")
    @ResponseBody
    public JSONObject showName(){
        JSONObject jsonObject = new JSONObject();
        String name = userService.getName();
        jsonObject.put("msg",name);
        return jsonObject;
    }
}

五、启动类加@EnableDubbo注解

服务提供方的启动类

@SpringBootApplication
@MapperScan("com.ljxx.dao")
@EnableAsync
@EnableDubbo
public class PtsServerApplication extends SpringBootServletInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(PtsServerApplication.class);
    }

}

服务器消费方的启动类

@SpringBootApplication
@EnableDubbo
public class PtsInterfaceApplication extends SpringBootServletInitializer {

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

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(PtsInterfaceApplication.class);
    }

}

@EnableDubbo:开启基于注解的dubbo功能(主要是包扫描@DubboComponentScan)

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
    @AliasFor(
        annotation = DubboComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = DubboComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};

    @AliasFor(
        annotation = EnableDubboConfig.class,
        attribute = "multiple"
    )
    boolean multipleConfig() default false;
}

也可以在配置文件中使用dubbo.scan.base-package来替代 @EnableDubbo

六、管理中心dubbo-admin部署

我们在开发时,需要知道注册中心都注册了哪些服务,以便我们开发和测试。我们可以通过部署一个管理中心来实现。其实管理中心就是一个 web 应用,部署到 tomcat 即可。

 1、下载安装包

官网下载地址:https://github.com/apache/dubbo/releases?after=dubbo-2.6.3

 注意:下载2.6.0版本的才有dubbo-admin文件夹。

 下载后的目录结构如下:

2、通过命令行的方式使用maven构建jar包

“Ctrl+R”输入“cmd”。进入dubbo-admin安装目录,然后输入下面代码

mvn clean package

打包后如下所示:

3、将jar放到tomcat中并改名字为dubbo-admin

tomcat地址:F:apache-tomcat-8.5.31-windowsapache-tomcat-8.5.31webapps

4、浏览器中输入http://localhost:8088/dubbo-admin/打开界面。

登录账户和密码均为root。

 service为服务名,application为应用名,address为机器IP

点击application,再点击箭头进入下一个页面

七、启动服务提供者和消费者

启动服务提供者和服务消费者后:

点击governence,点击applications,点击application,最后点击箭头,就可以看到服务的提供者和服务的消费者

 

 查看所有的服务提供者

点击governance,再点击services,就可以看到所有服务,其中status为OK的服务表示已经被消费者调用,no.consumer表示没有消费者。

八、测试服务调用

使用postman访问服务消费者,看能不能获取服务提供者返回的数据。

 

 注意:

1、dubbo服务消费方不能传递Date或DateTime类型的数据给服务提供方,可以通过String.valueOf转成字符串传递。

2、dubbo服务提供方抛出的自定义异常会变成RuntimeExceptionm,而且关于自定义异常的细节已经完全丢失,只会剩下一个类名的描述。

先了解Dubbo在遇到异常时的处理方法:

  1)、非RuntimeException不处理,直接返回

  2)、抛出的是方法上注明的异常,直接返回

  3)、如果异常类和接口类在同一jar包,直接返回

  4)、java或者javax目录下的异常类,直接返回

  5)、Dubbo自带的RpcException,直接返回

  6)、其他的异常,会被封装为RuntimeException返回
我的解决办法是在服务提供方抛出自定义的异常,在服务器消费方抛出Dubbo自带的RpcException。

3、服务提供方和服务消费方service接口的包结构要完全一样,否则,服务消费方找不到服务提供方的服务。controller的包接口可以不一样。

原文地址:https://www.cnblogs.com/zwh0910/p/15210306.html