JAVA分布式——dubbo(一)Duboo入门,Dubbo的介绍,Dubbo的直连方式,Dubbo的最佳服务的实现,Zookeeper的安装

一、什么是分布式?

1.1 分布式框架

分布式系统是若干独立系统的集合,但是用户使用起来像是在使用一套系统。

1.2 分布式系统

规模的逐步扩大和业务的复杂,单台计算机抗不住过大流量

1.3 演变

1. 单一架构

  • 当网站流量很小的时候,将所有一个用放到一台服务器上,打包运行公司管理系统/超市收银系统
  • 优点:开发简单,部署简单
  • 缺点:扩展性不容易,不易维护,性能难以提升

2. 垂直应用架构

  • 将大应用拆分成为小应用(一般按照业务拆分),根据不同的访问频率决定各自业务部署的服务器数量
  • 优点:拓展容易
  • 缺点:页面一改,可能造成整个项目重新部署,业务和界面没有分离开,随业务种类增加,怎么解决业务之间的互相调用问题,订单服务器和用户服务器交互效率的问题

3. 分布式架构

  • 将业务拆分后,用某种方式实现各个业务模块的远程调用和复用
  • 基于RPC:远程过程调用
  • dubbo阿里巴巴为了顶住双十一的流量而写的一个分布式的框架。各公司有各公司的分布式框架
  • dubbo是一个高性能的RPC框架,解决了分布式中的调用问题
  • 优点:解决了分布式系统中互相调用的问题
  • 缺点:当用户服务器模块使用率小,但订单服务器模块使用率较高。需要有一个统一管理的调度中心去分配服务器的压力(==zookeeper==)

二、初识Dubbo

2.1 dubbo性能高的原因

从底层说起,一个RPC框架,主要是远程过程(方法)的调用,其中调用的过程中最关键、最耗时的两个方面就是:序列化和网络通信

  • 序列化:本地对象想要在网络上传输,必须实现serializable接口。序列化的方案有:xml、json、二进制流…其中最高效率就是二进制流。Dubbo采用的就是效率最高的二进制。

  • 网络通信:不同于HTTP需要进行7步走(三次握手和四次挥手),Dubbo采用Socket通信机制,一步到位,提升了通信效率,并且可以建立长连接,不用反复连接,直接传输数据

2.2 dubbo历史

  • dubbo以往都是阿里内部使用框架
  • 2011年,dubbo背托管到GitHub上(开源)
  • 2014年,宣布停止。此后有一些公司基于dubbo生产出了很多dubbo的变种
  • 2017年,随着SpringCloud推出,随后更新了几个版本
  • 2018年,阿里将Dubbo捐给了Apache基金会。随后由Apache维护和更新,面向全球使用

2.3 dubbo概述

  • Apache Dubbo是一款高性能,轻量级的开源Java RPC框架,提供三大核心能离:==面向接口的远程方法调用==,==智能容错和负载均衡==,以及==服务器自动注册和发现==

  • 网站:http://dubbo.apache.org

在这里插入图片描述

三、Dubbo框架

3.1 基本架构

(官网提供) 在这里插入图片描述 |节点| 角色说明 | |--|--| | 服务提供者(Provider)|暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务| 服务消费者(Consumer)|调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败选择另外一台机器 注册中心(Registry) |服务注册与发现的注册中心,注册返回服务提供者地址列表给消费者,如有变更,注册中心讲基于长连接推送变量数据给消费者 Monitor |统计服务的调用次数和调用时间的监控中心,定时每分钟发送一次统计数据到监控中心 Container |服务运行容器

3.2dubbo支持的协议

  • 支持多种协议:dubbo,hessian,rmi,http,webservice,thrift,memcached,redis
  • dubbo官方推荐使用dubbo协议。dubbo协议默认端口:20880
  • 使用dubbo协议,spring配置文件中加入:
<dubbo:protocol name ="dubbo" port="20880"/>

四、直连方式(无注册中心)

1. 创建一个服务提供者

  • 创建一个maven web工程:服务的提供者

  • 创建一个实体bean查询的结构

  • 提供一个服务接口:xxx

  • 实现这个服务接口:xxxImpl

  • 配置dubbo服务提供者的核心配置文件

    • 声明dubbo服务提供者的名称:保证唯一
    • 声明dubbo使用的协议和端口号
    • 暴露服务,使用直连方式
  • 添加Spring监听器

  • 部分代码展示(dubbo的配置文件)

<!--服务的提供者声明名称:必须保证服务名称的唯一性,它的名称是dubbo内部使用的唯一标识-->
    <dubbo:application name="Dubbo_01"/>

    <!--访问服务协议的名称及端口号,dubbo官方推荐使用dubbo协议,端口号默认为20880-->
    <!--
        name:指定协议的名称
        port:指定协议的端口号(默认为20880)
    -->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--暴露服务接口->dubbo:service
        interface:表示暴露服务接口的全限定类名
        ref:接口引用的实现类在spring容器中的标识
        registry:如果不适用注册中心,则值为N/A
    -->
    <dubbo:service interface="com.aiit.dubbo.service.UserService" ref="userService" registry="N/A"/>
    <!--将接口的实现类加载到spring容器中-->
    <bean id="userService" class="com.aiit.dubbo.service.impl.UserServiceImpl"/>
    <!---->
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userservice-provider.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

2. 创建一个服务的消费者

  • 创建一个maven web工程:服务的消费者

  • 配置pom.xml文件:添加需要的依赖(spring,dubbo)

  • 设置dubbo的核心配置文件

  • 编写controller

  • 因为dubbo面向接口,所以服务的消费者是需要知道提供者的接口。因此我们需要==将服务提供者进行打包== 在这里插入图片描述

  • 将服务提供者引入到pom.xml文件中

 <!--依赖服务提供者-->
    <dependency>
      <groupId>com.aiit.dubbo</groupId>
      <artifactId>001-link-userservice-provider</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  • 书写消费者配置文件
 <!--声明服务消费者的名称:保证唯一性-->
    <dubbo:application name="002-link-consumer"/>
    <!--
        引用远程服务接口:
        id:远程服务接口对象名称
        interface:调用远程接口的全限定类名
        url:访问服务接口的地址
        registry:不使用注册中心,值为N/A
    -->
    <dubbo:reference id="userService"
                     interface="com.aiit.dubbo.service.UserService"
                     url="dubbo://localhost:20880"
                     registry="N/A"/>

 <!--扫描controller-->
    <context:component-scan base-package="com.aiit.dubbo.controller"/>
    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
  • 书写Controller通过接口去实现提供者的接口功能
@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/user")
    public String userDetail(Model model,Integer id){
        User user =this.userService.queryUserById(id);
        model.addAttribute("user",user);
        return "userDetail";
    }    
}

五、最佳服务实现

1. dubbo服务化最佳实践

1.1 分包

  • 建议将服务接口,服务模型(Bean)放到公共包中。也就是我们必须创建一个业务接口工程,也就是一个maven工程。

  • 里面放的内容分别是对外暴露的服务接口(service接口)和实体bean对象

1.2 粒度

  • 服务接口尽可能大的粒度,每个服务方法代表一个功能,而非功能的一个步骤

  • 服务接口建议以业务场景为单位划分,并对相对业务做抽象,防止接口数量爆炸

  • 不建议使用过于抽象的通用接口,如Map Query(map),没有明确语义,给后期维护带来不便

1.3 版本

  • 每个接口都应定义版本号,,区分同一个接口不同实现

2. 将直连方式代码升级

  • 根据上面三个需要,我们使用dubbo官方推荐的模式,将实体bean和业务接口存放到接口工程中 在这里插入图片描述

3. 接口工程

  • 只写接口和实体类
public interface UserService {
    /*根据用户标识获取用户信息*/
    User QueryUserById(Integer id);

    /*查询用户数量*/
    Integer QueryAllUserCount();
}

4. 业务提供者代码实现(部分)

  • dubbo-userservice-provider.xml
<!--声明服务提供者-->
<dubbo:application name="004-link-userservice-provider"/>
<!--声明服务的协议-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--暴漏接口服务-->
<dubbo:service interface="com.aiit.dubbo.service.UserService" ref="userService" registry="N/A"/>
<!--接口实现类注入-->
<bean id="userService" class="com.aiit.dubbo.service.impl.UserServiceImpl"/>
  • 实现接口
public class UserServiceImpl implements UserService {

    @Override
    public User QueryUserById(Integer id) {
        User user = new User();
        user.setId(id);
        user.setUsername("zhangsan");
        return user;
    }

    @Override
    public Integer QueryAllUserCount() {
        return 52;
    }
}

5.服务消费者代码实现(部分)

  • dubbo-consumer.xml文件
<!--保证服务的唯一性-->
<dubbo:application name="005-link-userservice-consumer"/>
<!--引入协议-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--引入远程接口服务-->
<dubbo:reference id="userService"
                 interface="com.aiit.dubbo.service.UserService"
                 url="dubbo://localhost:20880"
                 registry="N/A"/>
<!--接口实现类注入-->
<bean id="userService"  class="com.aiit.dubbo.service.impl.UserServiceImpl"/>
  • applicationContext.xml
 <!--扫描组件Controller层-->
    <context:component-scan base-package="com.aiit.dubbo.controller"/>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/"/>
    </bean>
  • Controller 层
 @Controller
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/userDetail")
    public String userDetail(Model model,Integer id){

        //根据哟ing胡标识获取用户详情
        User user = userService.QueryUserById(id);
        
        //获取用户总任务
        Integer allUserCount = userService.QueryAllUserCount();

        model.addAttribute("user",user);
        model.addAttribute("allUserCount",allUserCount);

        return "userDetail";
    }
}

六、注册中心——Zookeeper

6.1 概述

  • 对于服务提供方,它需要发布服务,而且由于应用系统的复杂性。服务的数量和类型会不断膨胀,对于服务消费方,最关系是如何获取到它所需要的服务,而面对复杂的系统,需要管理大量的服务调用

  • 对于服务提供方和服务消费方来说,有可能兼具两个角色,既需要提供服务,也需要消费服务。==通过将服务统一管理起来,有效的优化内部应用对服务发布/使用的流程和管理==

  • dubbo提供的注册中心有如下:

    • Multicast注册中心:组播方式
    • Redis注册中心:使用Redis作为注册中心
    • Simple注册中心:一个dubbo服务,提供查找服务的功能
    • ==Zookeeper注册中心==:使用Zookeeper作为注册中心
  • 简单来说:==使用Zookeeper即可,相当于记事本,记录服务的提供者所提供服务的地址。不需要服务的消费者去特意指定某个服务==

6.2zookeeper安装

  • 上官网即可下载

  • ==在Windows下安装==

    • 在zookeeper目录下,新建一个data用于存放临时数据

在这里插入图片描述

  • 添加参数,本身zookeeper在启动是会启动8080端口,但是8080端口我们会经常用,所以需要修改 在这里插入图片描述

  • 双击bin下的zkServer,出现如下即说明成功 在这里插入图片描述

  • 在Linux下安装

    • 先将zookeeper上传到Linux中,并进行解压 在这里插入图片描述

    • 新建文件夹data 在这里插入图片描述

    • 修改里面的conf文件 在这里插入图片描述

  • 运行zookeeper

在这里插入图片描述

Java
  • 作者:徐小庆 (联系作者)
  • 发表时间:2021-05-26 21:17
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论