zoukankan      html  css  js  c++  java
  • Dubbo

    软件架构

    单一应用架构

    当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。

    垂直应用架构

    当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。

    分布式服务架构

    当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。

    流动计算架构

    当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。

    SOA

    SOA全称为Service-Oriented Architecture,即面向服务的架构。它可以根据需求通过网络对松散耦合的粗粒度应用组件(服务)进行分布式部署、组合和使用。一个服务通常以独立的形式存在于操作系统进程中。

    站在功能的角度,把业务逻辑抽象成可复用、可组装的服务,通过服务的编排实现业务的快速再生,目的:把原先固有的业务功能转变为通用的业务服务,实现业务逻辑的快速复用。

    通过上面的描述可以发现SOA有如下几个特点:分布式、可重用、扩展灵活、松耦合

    原来的单体项目如何改为SOA架构?

    原来的单体工程项目大多分为三层:表现层(Controller)、业务层(Service)、持久层(Dao),要改为SOA架构,其实就是将业务层提取为服务并且独立部署即可,表现层通过网络和业务层进行通信,如下图:

     

    Dubbo简介

    Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。

    Dubbo提供了三大核心能力

    面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现

    RPC是什么

    RPC全称为remote procedure call即远程过程调用。比如两台服务器ABA服务器上部署一个应用,B服务器上部署一个应用,A服务器上的应用想调用B服务器上的应用提供的方法,由于两个应用不在一个内存空间,不能直接调用,所以需要通过网络来表达调用的语义和传达调用的数据。

    需要注意的是RPC并不是一个具体的技术,而是指整个网络远程调用过程。

    RPC是一个泛化的概念,严格来说一切远程过程调用手段都属于RPC范畴。各种开发语言都有自己的RPC框架。Java中的RPC框架比较多,广泛使用的有RMIHessianDubbo等。

    Dubbo架构图(左侧为Dubbo官方提供)

    调用关系说明:

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

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

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

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

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

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

    zookeeper简介

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

    流程说明:

    服务提供者(Provider)启动时: /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址

    服务消费者(Consumer)启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址

    监控中心(Monitor)启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址

    Dubbo快速入门

    Dubbo作为一个RPC框架,其最核心的功能就是要实现跨网络的远程调用。我们创建两个应用,一个作为服务的提供者,一个作为服务的消费者。通过Dubbo来实现服务消费者远程调用服务提供者的方法。

    服务提供者开发

     创建maven工程(打包方式为wardubbodemo_provider,在pom.xml文件中导入如下坐标

    <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>
    <spring.version>5.0.5.RELEASE</spring.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>${spring.version}</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
    </dependency>

    <!-- dubbo相关 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.7</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> </dependencies>

    创建服务接口和实现类

    接口

    public interface HelloService {
       public String sayHello(String name);
    }

    实现类

    @Service  //(阿里巴巴的service注解)
    public class HelloServiceImpl implements HelloService {
       public String sayHello(String name) {
          return "hello " + name;
       }
    }

    注意:服务实现类上使用的Service注解是Dubbo提供的,用于对外发布服务

    xml配置

     src/main/resources下创建applicationContext-service.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:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/mvc
             http://www.springframework.org/schema/mvc/spring-mvc.xsd
             http://code.alibabatech.com/schema/dubbo
             http://code.alibabatech.com/schema/dubbo/dubbo.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
        <dubbo:application name="dubbodemo_provider" />
        <!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
        <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
        <!-- 注册  协议和port   端口默认是20880 -->
        <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
        <!-- 扫描指定包,加入@Service注解的类会被发布为服务  -->
        <dubbo:annotation package="com.jia.service" />
    </beans>

    配置web.xml

    <!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd" >
    <web-app>
        <display-name>Archetype Created Web Application</display-name>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext*.xml</param-value>
        </context-param>
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>

    tomcat启动服务

    服务消费者开发

    创建maven工程(打包方式为wardubbodemo_consumerpom.xml配置和上面服务提供者相同

    将服务提供者工程中的HelloService接口复制到当前工程

    编写Controller

    @Controller
    public class HelloController {
       @Reference
       private HelloService helloService;
    
       @RequestMapping("/hello")
       @ResponseBody
       public String getName(String name){
          //远程调用
          String result = helloService.sayHello(name);
          System.out.println(result);
          return result;
       }
    }

    注意:Controller中注入HelloService使用的是Dubbo提供的@Reference注解

     src/main/resources下创建applicationContext-web.xml

      <!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
        <dubbo:application name="dubbodemo-consumer" />
        <!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
        <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
        <!-- 扫描的方式暴露接口  -->
        <dubbo:annotation package="com.jia.controller" />

    配置web.xml

    <!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd" >
    <web-app>
        <display-name>Archetype Created Web Application</display-name>
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext-web.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    </web-app>

    测试运行

    思考

    思考一:上面的Dubbo入门案例中我们是将HelloService接口从服务提供者工程(dubbodemo_provider)复制到服务消费者工程(dubbodemo_consumer)中,这种做法是否合适?还有没有更好的方式?

    答:这种做法显然是不好的,同一个接口被复制了两份,不利于后期维护。更好的方式是单独创建一个maven工程,将此接口创建在这个maven工程中。需要依赖此接口的工程只需要在自己工程的pom.xml文件中引入maven坐标即可。

    思考二:在服务消费者工程(dubbodemo_consumer)中只是引用了HelloService接口,并没有提供实现类,Dubbo是如何做到远程调用的?

    答:Dubbo底层是基于代理技术为HelloService接口创建代理对象,远程调用是通过此代理对象完成的。可以通过开发工具的debug功能查看此代理对象的内部结构。另外,Dubbo实现网络传输底层是基于Netty框架完成的。

    思考三:上面的Dubbo入门案例中我们使用Zookeeper作为服务注册中心,服务提供者需要将自己的服务信息注册到Zookeeper,服务消费者需要从Zookeeper订阅自己所需要的服务,此时Zookeeper服务就变得非常重要了,那如何防止Zookeeper单点故障呢?

    答:Zookeeper其实是支持集群模式的,可以配置Zookeeper集群来达到Zookeeper服务的高可用,防止出现单点故障。

    Dubbo配置说明

    包扫描
    服务提供者和服务消费者都需要配置,表示包扫描,作用是扫描指定包(包括子包)下的类
    <dubbo:annotation package="com.jia.service" />
    
    如果不使用包扫描,也可以通过如下配置的方式来发布服务
    <bean id="helloService" class="com.jia.service.impl.HelloServiceImpl" />
    <dubbo:service interface="com.jia.HelloService" ref="helloService" />
    
    作为服务消费者,可以通过如下配置来引用服务:
    <!-- 生成远程服务代理,可以和本地bean一样使用helloService -->
    <dubbo:reference id="helloService" interface="com.jia.HelloService" />
    
    上面这种方式发布和引用服务,一个配置项(dubbo:service、dubbo:reference)只能发布或者引用一个服务,如果有多个服务,这种方式就比较繁琐了。推荐使用包扫描方式。
    3.3.2协议
    <dubbo:protocol name="dubbo" port="20880"/>
    
    一般在服务提供者一方配置,可以指定使用的协议名称和端口号。
    其中Dubbo支持的协议有:dubbo、rmi、hessian、http、webservice、rest、redis等。
    推荐使用的是dubbo协议。
    dubbo 协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
    也可以在同一个工程中配置多个协议,不同服务可以使用不同的协议
    
    3.3.3启动时检查
    <dubbo:consumer check="false"/>
    
    上面这个配置需要配置在服务消费者一方,如果不配置默认check值为true。Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题。可以通过将check值改为false来关闭检查。
    建议在开发阶段将check值设置为false,在生产环境下改为true。

     Dubbo管理端工具

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

    安装

    安装步骤:
    
    (1)这里我用的是dubbo-admin-2.6.0.war,把这个文件复制到tomcat的webapps目录下
    
    (2)启动tomcat,此war文件会自动解压
    
    (3)修改WEB-INF下的dubbo.properties文件,注意dubbo.registry.address对应的值需要对应当前使用的Zookeeper的ip地址和端口号
    
    dubbo.registry.address=zookeeper://Ip:2181 ​ 
    
    dubbo.admin.root.password=root ​ 
    
    dubbo.admin.guest.password=guest
    
    (4)重启tomcat

    使用

    操作步骤:
    
    (1) 访问http://localhost:8080/dubbo-admin-2.6.0/,输入用户名(root)和密码(root)
    2) 启动服务提供者工程和服务消费者工程,可以在查看到对应的信息
  • 相关阅读:
    阿里云:面向5G时代的物联网无线连接服务
    走近科学,探究阿里闲鱼团队通过数据提升Flutter体验的真相
    Redis 5.0新功能介绍
    阿里云发布 Redis 5.0 缓存服务:全新 Stream 数据类型带来不一样缓存体验
    荣获“5G MEC优秀商用案例奖”,阿里云边缘计算发力新零售
    阿里云亮相2019联通合作伙伴大会,边缘计算等3款云产品助力5G时代产业数字化转型
    noip2014 寻找道路
    noip2014 无线网络发射器选址
    noip2014 联合权值
    noip2013 华容道
  • 原文地址:https://www.cnblogs.com/WonderfulU/p/11193986.html
Copyright © 2011-2022 走看看