商城02——dubbo框架整合_商品列表查詢實現_分頁


1.   課程計划

1、服務中間件dubbo

2、SSM框架整合。

3、測試使用dubbo

4、后台系統商品列表查詢功能實現。

5、監控中心的搭建

2.   功能分析

2.1. 后台系統所用的技術

框架:Spring + SpringMVC + Mybatis+dubbo

前端:EasyUI

數據庫:mysql

2.2. 系統間通信

       由於此商城是基於SOA的架構,表現層和服務層是不同的工程。所以要實現商品列表查詢需要兩個系統之間進行通信。

如何實現遠程通信?

1、使用WebService:效率不高,它是基於soap協議(http+xml)。項目中不推薦使用。

2、使用restful形式的服務:http+json。很多項目中應用。如果服務越來越多,服務與服務之間的調用關系復雜,調用服務的URL管理復雜,什么時候添加機器難以確定。

3、使用dubbo。使用rpc協議進行遠程調用,直接使用socket通信。傳輸效率高,並且可以統計出系統之間的調用關系、調用次數,管理服務。

3. dubbo

3.1. 什么是dubbo

       dubbo.io 

       DUBBO是一個分布式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,是阿里巴巴SOA服務化治理方案的核心框架,每天為2,000+個服務提供3,000,000,000+次訪問量支持,並被廣泛應用於阿里巴巴集團的各成員站點。

       隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分布式服務架構以及流動計算架構勢在必行,急需一個治理系統確保架構有條不紊的演進。

 

  • 單一應用架構
    • 當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。
    • 此時,用於簡化增刪改查工作量的 數據訪問框架(ORM) 是關鍵。
  • 垂直應用架構

    當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。

    此時,用於加速前端頁面開發的 Web框架(MVC) 是關鍵。

  • 分布式服務架構

    當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。

    此時,用於提高業務復用及整合的 分布式服務框架(RPC) 是關鍵。

  • 流動計算架構

    當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。

    此時,用於提高機器利用率的 資源調度和治理中心(SOA) 是關鍵。

Dubbo就是資源調度和治理中心的管理工具。

Dubbo 就是類似於webservice的關於系統之間通信的框架,並可以統計和管理服務之間的調用情況(包括服務被誰調用了,調用的次數是如何,以及服務的使用狀況)。

 

3.2. Dubbo的架構

 

節點角色說明:

  • Provider: 暴露服務的服務提供方。
  • Consumer: 調用遠程服務的服務消費方。
  • Registry: 服務注冊與發現的注冊中心。
  • Monitor: 統計服務的調用次調和調用時間的監控中心。
  • Container: 服務運行容器。

調用關系說明:

  • 0. 服務容器負責啟動,加載,運行服務提供者。
  • 1. 服務提供者在啟動時,向注冊中心注冊自己提供的服務。
  • 2. 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
  • 3. 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
  • 4. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
  • 5. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。

3.3. 使用方法

3.3.1.    Spring配置

Dubbo采用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring加載Dubbo的配置即可,Dubbo基於Spring的Schema擴展進行加載。

單一工程中spring的配置local.xml:

  <bean id="xxxService" class="com.xxx.XxxServiceImpl" />

  <bean id="xxxAction" class="com.xxx.XxxAction">

         <property name="xxxService" ref="xxxService" />

  </bean>

 

遠程服務:

在本地服務的基礎上,只需做簡單配置,即可完成遠程化:

 

將上面的local.xml配置拆分成兩份,將服務定義部分放在服務提供方remote-provider.xml,將服務引用部分放在服務消費方remote-consumer.xml。

並在提供方增加暴露服務配置<dubbo:service>,在消費方增加引用服務配置<dubbo:reference>。

服務層發布服務

<!-- 和本地服務一樣實現遠程服務 -->
<bean id="xxxService" class="com.xxx.XxxServiceImpl" />
<!-- 增加暴露遠程服務配置 -->
<dubbo:service interface="com.xxx.XxxService" ref="xxxService" />

表現層調用服務:

<!-- 增加引用遠程服務配置 -->
<dubbo:reference id="xxxService" interface="com.xxx.XxxService" />
<!-- 和本地服務一樣使用遠程服務 -->
<bean id="xxxAction" class="com.xxx.XxxAction">
    <property name="xxxService" ref="xxxService" />
</bean>

3.4. 注冊中心

Zookeeper是Apacahe Hadoop的子項目,是一個樹型的目錄服務,支持變更推送,適合作為Dubbo服務的注冊中心。

4.框架整合

4.1. 添加dubbo的依賴

加入dubbo相關的jar包。服務層、表現層都添加:

    <!-- dubbo相關 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <!-- 排除依賴 -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.jboss.netty</groupId>
                    <artifactId>netty</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>

4.2. 整合思路

4.2.1 Dao層:

mybatis整合spring,通過spring管理SqlSessionFactory、mapper代理對象。需要mybatis和spring的整合包,由spring創建數據庫連接池

4.2.2 Service層:

所有的實現類都放到spring容器中管理。並有spring管理事務;發布dubbo服務

 

web.xml 配置:配置加載spring容器。

4.2.3 表現層

Springmvc整合spring框架,由springmvc管理controller;引入dubbo服務

 

web.xml 的配置:前端控制器的配置,配置URL攔截形式。

 

5. 實現商品列表查詢功能

 

5.1. 功能分析

5.1.1.    整合靜態頁面展示首頁

把靜態頁面添加到taotao-manager-web工程中的WEB-INF下:

 

 由於在web.xml中定義的url攔截形式為“/”表示攔截所有的url請求,包括靜態資源例如css、js等。所以需要在springmvc.xml中添加資源映射標簽:

  <mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
   <mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>

分析:

首頁的請求地址:/

請求參數:無

返回值:index.jsp (首頁)

 

Controller:

@Controller
public class PageController {
    /**
     * 展示首頁
     * @return
     */
    @RequestMapping("/")
    public String showIndex(){
        return "index";
    }
    /**
     * 展示菜單頁面
     * @param page
     * @return
     */
    @RequestMapping("/{page}")
    public String showItemList(@PathVariable String page){
        return page;
    }
}

5.1.2.  商品列表頁面

對應的jsp:  item-list.jsp

請求的url/item/list

請求的參數:page=1&rows=30

響應的json數據格式:

  Easyui中datagrid控件要求的數據格式為:{total:”2”,rows:[{“id”:”1”,”name”:”張三”},{“id”:”2”,”name”:”李四”}]}

5.1.3.    響應的json數據格式EasyUIDataGridResult

創建此類放入taotao-common中

/**
 * 商品列表查詢的返回的數據類
*/
public class EasyUIDataGridResult {
    private Integer total;
    private List rows;
    set/get。。。
}

5.1.4.   分頁處理

       逆向工程生成的代碼是不支持分頁處理的,如果想進行分頁需要自己編寫mapper,這樣就失去逆向工程的意義了。為了提高開發效率可以使用mybatis的分頁插件PageHelper

5.2. 分頁插件PageHelper

5.2.1.    使用方法

第一步:把PageHelper依賴的jar包添加到工程中。

第二步:在Mybatis的全局文件中配置SqlMapConfig.xml中配置攔截器插件:

<plugins>
    <!-- com.github.pagehelper為PageHelper類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <!-- 設置數據庫類型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六種數據庫-->        
        <property name="dialect" value="mysql"/>
    </plugin>
</plugins>

第三步:在代碼中使用

1、設置分頁信息:

   //獲取第1頁,10條內容,默認查詢總數count
    PageHelper.startPage(1, 10);

    //緊跟着的第一個select方法會被分頁
  List<Country> list = countryMapper.selectIf(1);

2、取分頁信息:

//獲取第1頁,10條內容,默認查詢總數count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
//用PageInfo對結果進行包裝
PageInfo page = new PageInfo(list);

5.2.2.   分頁測試

@Test
    public void testPageHelper() throws Exception {
        //初始化spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml");
        //獲得Mapper的代理對象
        TbItemMapper itemMapper = applicationContext.getBean(TbItemMapper.class);
        //設置分頁信息
        PageHelper.startPage(1, 30);
        //執行查詢
        TbItemExample example = new TbItemExample();
        List<TbItem> list = itemMapper.selectByExample(example);
        //取分頁信息
        PageInfo<TbItem> pageInfo = new PageInfo<>(list);
        System.out.println(pageInfo.getTotal());
        System.out.println(pageInfo.getPages());
        System.out.println(pageInfo.getPageNum());
        System.out.println(pageInfo.getPageSize());
    }

5.3. Service層

  參數:int page ,int rows

  業務邏輯:查詢所有商品列表,要進行分頁處理。

  返回值:EasyUIDataGridResult

5.3.1.    接口

taotao-manager-interface工程下com.taotao.service包下的ItemService接口類:

public interface ItemService {
    /**
     *  根據當前的頁碼和每頁 的行數進行分頁查詢
     */
    public EasyUIDataGridResult getItemList(int page,int rows);
}

5.3.2.   實現類

 taotao-manager-service工程下com.taotao.service.impl包下的 ItemServiceImpl 實現類

@Service
public class ItemServiceImpl implements ItemService {
    
    //注入mapper
    @Autowired
    private TbItemMapper itemMapper;

    @Override
    public EasyUIDataGridResult getItemList(int page, int rows) {
        
        //設置分頁信息,使用PageHelper
        PageHelper.startPage(page,rows);
        
        //執行查詢,調用mapper的方法
        TbItemExample example = new TbItemExample();
        List<TbItem> list = itemMapper.selectByExample(example);
        
        //獲取分頁信息
        PageInfo<TbItem> pageInfo = new PageInfo<TbItem>(list);
        
        //創建返回結果對象(將分頁信息封裝到EasyUIDataGridResult)
        EasyUIDataGridResult result = new EasyUIDataGridResult();
        result.setRows(list);
        result.setTotal(pageInfo.getTotal());
        
        return result;
    }
}

5.3.3.    發布服務

在taotao-manager-service中的 applicationContext-service.xml中發布服務:

注意address的值:使用自己的zookeeper所在的系統的ip地址和端口

  <!-- 使用dubbo發布服務 -->
    <!-- 提供方應用信息,用於計算依賴關系 -->
    <dubbo:application name="taotao-manager" />
    <dubbo:registry protocol="zookeeper" address="192.168.25.129:2181" />
    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 聲明需要暴露的服務接口 -->
    <dubbo:service interface="com.taotao.service.ItemService" ref="itemServiceImpl" />

5.4. 表現層

在taotao-manager-web工程中的springmvc.xml中引入服務:

注意address的值:使用自己的zookeeper所在的系統的ip地址和端口

<!-- 引用dubbo服務 -->
    <dubbo:application name="taotao-manager-web" />
    <dubbo:registry protocol="zookeeper" address="192.168.25.129:2181" />
    <dubbo:reference interface="com.taotao.service.ItemService" id="itemService" />

1、初始化表格請求的url:/item/list

2、Datagrid默認請求參數:

  • page:當前的頁碼,從1開始。
  • rows:每頁顯示的記錄數。

3、響應的數據:json數據。EasyUIDataGridResult

@Controller
public class ItemController {
    
    //1.引入服務(springmvc.xml中引入)
    //2.注入服務
    @Autowired
    private ItemService itemService;
    
    @RequestMapping(value="/item/list", method=RequestMethod.GET)
    @ResponseBody
    public EasyUIDataGridResult getItemList(Integer page, Integer rows){
        //3.調用服務的方法
        return itemService.getItemList(page, rows);
    }
}

 


免責聲明!

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



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