【原】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 方法
  •  輸出結果如下。

 

 

 

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM