zoukankan      html  css  js  c++  java
  • 【原】Spring和Dubbo基于XML配置整合过程

            

    背景

    随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

    image

    单一应用架构

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

    • Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。关于注册中心、协议支持、服务监控等内容
    • Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等

         使用案例:

                 先前由于业务需求,要出很多新的功能,考虑到服务器的压力(用户正常访问的业务+不断迭代的新功能明显感觉得到系统缓慢,响应延迟),单一的webservice或者httpclient互相调用不同的服务也感觉比较笨拙,加上某个提供者挂掉导致部分业务不能正常访问,所以就有采用了dubbo框架作为不同的服务之间相互调用。                  

    -----------------------------------------------------------------分割线--------------------------------------------------------------

    • 整合dubbo之前我先贴上几段spring代码(如何搭建dubbo和Zookeeper环境这里就不介绍了,网上有很多教程, 我的dubbo版本是2.5.4,zookeeper是3.3.6),主要是模拟spring mvc的一个简单过程,但是没用到数据库和spring 事务等, 用来对比dubbo和spring整合后到底哪里发生了改变
    1.   首先是实体类,我们经常说的pojo
    package com.zdd.dubbo.provider;
    
    /**
     * 
     * @ClassName: Goods 
     * @Description: 商品表
     * @author: kevin
     * @date: 2016-10-21 上午10:23:03
     */
    public class Goods {
        
        
        private int id;
        private String name;
        private double price;
        private int num;
        private String color;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public int getNum() {
            return num;
        }
        public void setNum(int num) {
            this.num = num;
        }
        public String getColor() {
            return color;
        }
        public void setColor(String color) {
            this.color = color;
        }
        
        @Override
        public String toString() {
            return "Goods [id=" + id + ", name=" + name + ", price=" + price
                    + ", num=" + num + ", color=" + color + "]";
        }
    
    }

       
    查询商品接口以及实现类

    package com.zdd.dubbo.provider;
    
    import java.util.List;
    
    public interface GoodsService {
    
        List<Goods> findAllGoodsByParams();
    }
    package com.zdd.dubbo.provider;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 
     * @ClassName: GoodsServiceImpl
     * @Description: 实现类,模拟从数据库查出数据
     * @author: kevin
     * @date: 2016-10-21 上午10:28:36
     */
    public class GoodsServiceImpl implements GoodsService {
    
        @Override
        public List<Goods> findAllGoodsByParams() {
    
            List<Goods> glist = new ArrayList<>();
    
            Goods g = new Goods();
            g.setColor("蓝色");
            g.setId(1);
            g.setName("耐克长袖");
            g.setPrice(268);
            Goods g1 = new Goods();
            g1.setColor("黑色");
            g1.setId(1);
            g1.setName("阿迪达斯板鞋");
            g1.setPrice(499);
            glist.add(g);
            glist.add(g1);
            return glist;
        }
    
    }

     

     

    控制层代码,在springmvc又称handler

    package com.zdd.dubbo.consumer;
    
    import javax.xml.bind.annotation.XmlAccessOrder;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.zdd.dubbo.provider.GoodsService;
    
    public class GoodsAction {
        
        
        
        private static GoodsService goodsService;
    
        /**
         * 
         * @Title: main 
         * @Description: 模拟spring mvc的 请求 类似于 @Controller
         * @param args
         * @return: void
         */
        public static void main(String[] args) {
            //spring 注入
            ApplicationContext  applicationContext = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-web-consumer/spring/applicationContext.xml");
            goodsService = (GoodsService) applicationContext.getBean("getGoodService");
            System.out.println(goodsService.findAllGoodsByParams());
            
        }
    }

     

     

    spring的配置文件

    <?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd
            ">
        <!-- <import resource="dubbo-provider.xml"></import> -->
        <!-- spring注入 -->
        <bean id="getGoodService" class="com.zdd.dubbo.provider.GoodsServiceImpl"></bean>
    </beans>

     

    通过spring注入然后执行main方法调用本地的service获取一个商品list,输出结果如下图。

     

     


     

    #这时候我打算用dubbo框架改变上面的代码,通过dubbo把需要提供的服务暴露出去,然后消费者再进行调用,使得2个系统之间耦合度变低,我的理解是消费者只关心他要调用什么服务,提供者只关心他提供什么服务, 它们之间通过rpc协议来进行传输。因为当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。

     

    • dubbo-provider.xml 提供者配置(注意:注册中心暴露服务地址是zookeeper的地址,例如你本地安装了zookeeper并启动成功,那么你的地址就是zookeeper://127.0.0.1:2181,必须要启动zookeeper,不然本地服务无法注册上去,无法注册的话就没办法实现远程调用
    <?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:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans        
        http://www.springframework.org/schema/beans/spring-beans.xsd        
        http://code.alibabatech.com/schema/dubbo        
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
     
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="find_all_goods"  />
     
        <!-- 使用multicast广播注册中心暴露服务地址 -->
       <!--  <dubbo:registry address="multicast://224.5.6.7:1234" /> -->
     
         <!-- 使用zookeeper注册中心暴露服务地址 -->
        <dubbo:registry address="zookeeper://xx.xxxx.xx:2181" />
     
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
     
        <!-- 声明需要暴露的服务接口(注意是接口,不是实现类) -->
        <dubbo:service interface="com.zdd.dubbo.provider.GoodsService" ref="goodsService" />
        
        <!-- 这里是具体实现类,id和上面的暴露的服务接口ref要一致,dubbo就是通过这个来注册对应的服务 -->
        <bean id="goodsService" class="com.zdd.dubbo.provider.GoodsServiceImpl"></bean>
        
    </beans>
    • consumer.xml 消费者的xml配置(注意:对比上面的提供者xml配置可以清楚的发现消费者通过 <dubbo:reference id id="goodsService"> 标签指向了 goodsService, 假设我们随便写一个mallService 肯定是不行的,因为我们提供的只有goodService服务)
    <?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:dubbo="http://code.alibabatech.com/schema/dubbo"
        xsi:schemaLocation="http://www.springframework.org/schema/beans        
        http://www.springframework.org/schema/beans/spring-beans.xsd        
        http://code.alibabatech.com/schema/dubbo        
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
        <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
        <dubbo:application name="dubbo-consumer"/>
        <!-- 使用multicast广播注册中心暴露发现服务地址 -->
        <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->
        <dubbo:registry address="zookeeper://xxx.xx.xx:2181" />
        <!-- 生成远程服务代理,可以和本地bean一样调用 -->
        <dubbo:reference id="goodsService" interface="com.zdd.dubbo.provider.GoodsService" />
    </beans>
    • 最后整合完测试一下代码 (注意:这段代码先初始化的是提供者的xml,然后初始化消费者的xml。必须按顺序执行,否则的话服务提供的都没起来,消费方是拿不到zk上面的服务的)
      package com.zdd.dubbo.consumer;
      
      import java.io.IOException;
      
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      import com.zdd.dubbo.provider.GoodsService;
      
      public class GoodsAction {
          private static GoodsService goodsService;
      
          /**
           * 
           * @Title: main 
           * @Description: 模拟spring mvc的 请求 类似于 @Controller
           * @param args
           * @return: void
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              /*//spring 注入
              ApplicationContext  applicationContext = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-web-consumer/spring/applicationContext.xml");
              goodsService = (GoodsService) applicationContext.getBean("getGoodService");
              System.out.println(goodsService.findAllGoodsByParams());*/
              ApplicationContext  dubbo_provider = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-service-provider/spring_dubbo/dubbo-provider.xml");
              ApplicationContext  dubbo_cusumer = new ClassPathXmlApplicationContext("file:D:/workspace/GZDTL_TRUNK/zdd-web-consumer/spring/dubbo-consumer.xml");
              GoodsService  service = (GoodsService) dubbo_cusumer.getBean("goodsService");
              System.out.println(service.findAllGoodsByParams());
              System.in.read();
          }
      }
      dubbo main 方法
    •  输出结果如下。

         

  • 相关阅读:
    Databases Questions & Answers
    SQL语句
    常见的数据库基础面试题大全
    关于GET POST
    经常遇到的浏览器兼容性问题
    关于JavaScript中apply与call的用法意义及区别(转)
    js闭包的用途
    深入理解js闭包
    undefined与null的区别
    HeapSort快速排序
  • 原文地址:https://www.cnblogs.com/zdd-java/p/zdd_soa_dubbo01.html
Copyright © 2011-2022 走看看