Spring+Maven+Dubbo+MyBatis+Linner+Handlebars—Web開發環境搭建

       本文主要分三部分,分別是:後臺核心業務邏輯、橋樑輔助控制和前臺顯示頁面。css

       本Web開發環境綜合了多種工具,包括Maven包管理與編譯工具、Dubbo分佈式服務框架、MyBatis數據持久化工具、Linner頁面管理工具和Handlebars Js模板引擎等前衛的開發工具。html

        首先介紹一下:後臺核心業務邏輯搭建。前端

1. 後臺核心業務邏輯搭建

      後臺核心業務邏輯大體分爲三個層次:最底層的核心數據邏輯層(biz層),中間層Dubbo服務實現層(service-impl層)Dubbo服務接口層(service-client層)。此外還有公共的jar包管理父工程(parent工程)公共業務邏輯工程(common工程)任務調度工程(task工程)總的maven管理工程java

      示例以下圖:node

       

     接下來我會按照搭建順序簡單介紹一下相關工程的配置:web

     基本的順序是parent工程→biz工程→common工程→task工程→service-client工程→service-impl工程。ajax

   1.1 基本jar包管理和服務環境配置parent工程

     parent工程結構以下圖所示:redis

     

    parent工程主要包括pom工程配置文件,filters文件下的三個開發環境配置文件和maven打包bat批處理命令文件。spring

    首先介紹一下parent工程的pom文件:sql

     (1)  不一樣的打包環境配置,使用不一樣的打包配置便利了項目整個開發,測試到生產流程的統一化管理。默認將開發環境激活,配置以下圖所示:

     

   (2)  編譯時設置不對指定的資源文件進行替換。包括Freemarker模板文件ftl,靜態-dynamic.xml文件,mybatis動態SQL Mapper文件。以下圖:

    

    (3)   工程編碼和打包插件配置:包括工程編碼插件Java版本1.7,生成javadoc插件,打包Java源碼插件,導入eclipse工程插件等的配置。以下圖所示:

    

   (4)  單元測試覆蓋率統計插件配置:

   忽略對如下路徑文件的單元測試覆蓋率統計:action、webapp、interceptor、taglib、domain、model、dto和util/DataFormat.class。下圖相應配置信息:

    

   1.2  biz核心業務邏輯工程

       biz工程結構以下圖所示:
       

   按模塊劃分的動態SQLMapper文件:示例:SamStateInfoMapper.xml,如圖1-21

   序號①指定mybatis基本配置文件sqlMapConfig.xml的路徑。

    序號②指定動態SQL Mapper文件的路徑。

    序號③爲基礎的baseDAO Bean的聲明。

    a包類文件,主資源文件;測試Java包類文件,測試資源文件四大部分組成。

     主Java包類文件的文件路徑爲com.ouc.mkhl.supplier,下按模塊劃分,示例中爲jmx、security和util 3個模塊。security模塊又細分爲advice包、dao數據訪問對象包、domain包、model數據實體類包和service服務接口包,service服務接口包下包含impl服務接口實現包。

     主資源文件包含email郵箱模板文件、logs日誌配置文件、mybatis配置文件、spring相關配置文件。以後將對各配置文件作逐一介紹。

     測試Java包類文件包含與主Java包相關的各單元測試文件。

     測試資源文件包含springcache文件和mybatis數據持久層generator配置文件。

     1)  biz工程的pom配置文件:以下圖所示:

     

    序號①爲工程的父maven工程配置。

    序號②爲工程的繼承和引用工程關係配置。   

   2)  biz工程主資源配置文件說明:

    (1)  mybatis配置文件:首先介紹基本的SQLMap配置文:sqlMapConfig.xml

    

    按模塊劃分的動態SQLMapper文件:示例:SamStateInfoMapper.xml,以下圖

   

   (2)  spring相關配置文件:

   ①   緩存cache配置文件:ehcache.xml,spring-cache-security.xml,spring-cache.xml。

   ②   jmx運行期系統管理配置文件:spring-jmx-mbean.xml。

   ③   按模塊劃分的自定義Bean聲明配置文件:示例:spring-upload.xml

   

   序號①爲相似DAO的數據庫接口操做類Bean。

   序號②爲服務接口Bean方法。

   b爲聲明的切面,a爲前置通知和後置通知要執行的方法。

   ④  公用操做的配置文件spring-common.xml。

   

   序號①指定mybatis基本配置文件sqlMapConfig.xml的路徑。

   序號②指定動態SQL Mapper文件的路徑。

   序號③爲基礎的baseDAO Bean的聲明。

   ⑤  spring配置工具配置:spring-config-toolkit.xml

   

   ⑥   數據源配置:spring-datasource.xml

   

   ⑦  Dubbo服務接口發佈配置:spring-dubbo.xml

  

  ⑧   服務擴展接口配置:spring-external.xml

  

  ⑨   業務日誌配置:spring-log.xml

 

   ⑩  Quartz監控配置:spring-monitor.xml

  

  傳輸事物管理配置:spring-transaction.xml

   biz工程代碼示例:

    a.Jmx運行期管理擴展服務:

    用戶暴露系統相關管理接口,以實現運行期調用:ExposeMethodInterface

    

   運行期管理系統接口實現:Configuration

    

    b.系統初始化:SystemBootstrap

 1 package com.ouc.mkhl.supplier.util;
 2 import java.io.IOException;
 3 import java.io.InputStream;
 4 import java.util.Properties;
 5 import mx4j.tools.adaptor.http.HttpAdaptor;
 6 import org.apache.commons.logging.Log;
 7 import org.apache.commons.logging.LogFactory;
 8 import org.springframework.beans.factory.InitializingBean;
 9 import org.springframework.core.env.AbstractEnvironment;
10 import com.ouc.openplatform.SysException;
11 import com.ouc.openplatform.console.audit.AuditInfoCollector;
12 import com.ouc.openplatform.session.listener.MaxSessionUtil;
13 import com.ouc.openplatform.util.Env;
14 import com.ouc.openplatform.util.HOPConstant;
15 
16 /**
17  * @author WuPing
18 */
19 public class SystemBootstrap implements InitializingBean {
20     /*
21      * CONFIG_FILE_PATH 系統變量配置文件路徑
22      */
23     private static final String CONFIG_FILE_PATH = "/env.properties";
24     private static final Log LOG = LogFactory.getLog(SystemBootstrap.class);
25     private HttpAdaptor httpAdaptor;
26     public static void  init() {
27         InputStream inputStream = null;
28         Properties properties = new Properties();
29         try{
30     inputStream SystemBootstrap.class.getResourceAsStream(CONFIG_FILE_PATH);
31             properties.load(inputStream);
32             LOG.info("系統配置項:"+properties);
33         }catch (Exception e) {
34             LOG.error("讀取系統配置文件時發生錯誤:",e);
35             throw new SysException(e);
36         }finally{
37             if(inputStream != null){
38                 try {
39                     inputStream.close();
40                 } catch (IOException e) {
41                     LOG.error("關閉文件輸入流失敗:",e);
42                 }
43             }
44         }
45         Env.init(properties);
46         AuditInfoCollector.setAppNM(Env.getProperty(Env.KEY_SERVER_NAME));
47         HOPConstant.setAppName(Env.getProperty(Env.KEY_SERVER_NAME));
48         //設置一些全局參數
49     MaxSessionUtil.setMaxSessionKey(Env.getProperty(Env.KEY_SERVER_NAME)+"_MAX_SESSION_KEYS");
50         //使用spring的profile
51     System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, Env.getProperty(Env.ENV_TYPE));
52     }
53 
54     @Override
55     public void afterPropertiesSet() throws Exception {
56         httpAdaptor.start();
57     }
58 
59     public void setHttpAdaptor(HttpAdaptor httpAdaptor) {
60         this.httpAdaptor = httpAdaptor;
61     }
62 }
View Code

     c.DAO:SupplyUserDAO:

 1 package com.ouc.mkhl.supplier.security.dao;
 2 import java.util.List;
 3 import com.ouc.mkhl.supplier.security.model.SupplyUser;
 4 public interface SupplyUserDAO {
 5     public int deleteByPrimaryKey(String supplycode);
 6     public int insert(SupplyUser record);
 7     public SupplyUser selectByPrimaryKey(String supplycode);
 8     public int updateByPrimaryKey(SupplyUser record);
 9     public List<SupplyUser> selectAllSupplyUser();
10     public SupplyUser selectByVCode(String supplycode);
11 }
View Code

     d. Model:SupplyUser

 1 package com.ouc.mkhl.supplier.security.model;
 2 
 3 import java.io.Serializable;
 4 
 5 public class SupplyUser implements Serializable{
 6 
 7     private static final long serialVersionUID = -123120032141L;
 8     
 9     private String supplycode;
10 
11     private String supplypass;
12 
13     private String supplyname;
14 
15     public String getSupplycode() {
16         return supplycode;
17     }
18 
19     public void setSupplycode(String supplycode) {
20         this.supplycode = supplycode == null ? null : supplycode.trim();
21     }
22 
23     public String getSupplypass() {
24         return supplypass;
25     }
26 
27     public void setSupplypass(String supplypass) {
28         this.supplypass = supplypass == null ? null : supplypass.trim();
29     }
30 
31     public String getSupplyname() {
32         return supplyname;
33     }
34 
35     public void setSupplyname(String supplyname) {
36         this.supplyname = supplyname == null ? null : supplyname.trim();
37     }
38 }
View Code

   1.3 service-client服務接口工程

       service-client工程結構如圖:

  

  分爲傳輸DTO包,輔助功能helper包,客戶端服務接口聲明service包和客戶端工具類util包。

    service-client示例代碼:

    a. DTO:SupplyUserDTO

 1 package com.ouc.mkhl.supplier.dto;
 2 
 3 import java.io.Serializable;
 4 
 5 import com.ouc.openapi.dubbo.governance.annotation.DubboField;
 6 
 7 public class SupplyUserDTO implements Serializable{
 8 
 9     private static final long serialVersionUID = -223120032141L;
10     
11     @DubboField(description = "供應商V碼")
12     private String supplycode;
13     
14     @DubboField(description = "供應商登陸密碼-未加密")
15     private String supplypass;
16     
17     @DubboField(description = "供應商全稱")
18     private String supplyname;
19 
20     public String getSupplycode() {
21         return supplycode;
22     }
23 
24     public void setSupplycode(String supplycode) {
25         this.supplycode = supplycode == null ? null : supplycode.trim();
26     }
27 
28     public String getSupplypass() {
29         return supplypass;
30     }
31 
32     public void setSupplypass(String supplypass) {
33         this.supplypass = supplypass == null ? null : supplypass.trim();
34     }
35 
36     public String getSupplyname() {
37         return supplyname;
38     }
39 
40     public void setSupplyname(String supplyname) {
41         this.supplyname = supplyname == null ? null : supplyname.trim();
42     }
43 }
View Code
    b. 客戶端服務接口service:SupplyUserServiceClient
 1 package com.ouc.mkhl.supplier.service;
 2 
 3 import io.terminus.pampas.client.Export;
 4 
 5 import com.ouc.openapi.dubbo.governance.annotation.DubboMethod;
 6 import com.ouc.openapi.dubbo.governance.annotation.DubboParam;
 7 import com.ouc.openapi.dubbo.governance.annotation.DubboService;
 8 import com.ouc.mkhl.supplier.dto.SupplyUserDTO;
 9 
10 import java.util.List;
11 
12 /**
13  * 供客戶端調用的遠程接口
14  * 
15  * @author WuPing
16  * 
17  */
18 @DubboService(description = "供應商用戶服務", displayName = "SupplyUser服務")
19 public interface SupplyUserServiceClient {
20 
21     // get請求
22     // @return List<SupplyUserDTO>
23     @Export(paramNames = {})
24     @DubboMethod(description = "獲取全部供應商用戶信息", displayName = "getAllSupplyUsers", returnParamDes = "供應商用戶DTO列表")
25     public List<SupplyUserDTO> getAllSupplyUsers();
26 
27     // 用戶登陸處理
28     @Export(paramNames = { "username", "password" })
29     @DubboMethod(description = "用戶登陸驗證", displayName = "userLogin", returnParamDes = "驗證結果")
30     public String userLogin(
31         @DubboParam(name = "username", description = "登陸用戶名", example = "V187") String username,
32         @DubboParam(name = "password", description = "密碼", example = "123456") String password);
33 
34 }
View Code

  1.4 service-impl服務接口具體實現功能工程

     Service-impl工程結構如圖:

   

    該工程包括異常處理filter包和客戶端服務接口具體實現impl包。主資源文件有客戶端Dubbo接口發佈基本配置文件spring-dubbo.xml和用戶自定義服務配置文件spring-user-provider.xml。以下圖所示:

    序號①爲代理平臺分配的應用S碼。

    序號②爲後臺接口代理服務。

    序號③爲服務方法認證相關服務接口。

    序號④爲服務自動註冊接口。

   

    Service-impl示例代碼:

    客戶端接口實現Service-impl:SupplyUserServiceClientImpl
  1 package com.ouc.mkhl.supplier.service.impl;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 import javax.annotation.Resource;
  7 import javax.ws.rs.BeanParam;
  8 import javax.ws.rs.Consumes;
  9 import javax.ws.rs.DefaultValue;
 10 import javax.ws.rs.FormParam;
 11 import javax.ws.rs.GET;
 12 import javax.ws.rs.POST;
 13 import javax.ws.rs.Path;
 14 import javax.ws.rs.PathParam;
 15 import javax.ws.rs.Produces;
 16 import javax.ws.rs.QueryParam;
 17 import javax.ws.rs.core.MediaType;
 18 
 19 import org.springframework.stereotype.Service;
 20 
 21 import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
 22 import com.ouc.openapi.dubbo.governance.annotation.DubboParam;
 23 import com.ouc.mkhl.supplier.dto.SupplyUserDTO;
 24 import com.ouc.mkhl.supplier.service.SupplyUserServiceClient;
 25 import com.ouc.mkhl.supplier.security.service.SupplyUserService;
 26 import com.ouc.mkhl.supplier.security.model.SupplyUser;
 27 import com.ouc.mkhl.supplier.helper.EncryptHelper;
 28 
 29 @Path("supplyUser")
 30 @Consumes({ ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8 })
 31 // 參數類型
 32 @Produces({ ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8 })
 33 // 返回值類型
 34 @Service("supplyUserServiceClient")
 35 public class SupplyUserServiceClientImpl implements SupplyUserServiceClient {
 36 
 37     @Resource
 38     private SupplyUserService supplyUserService;
 39 
 40     public SupplyUserService getSupplyUserService() {
 41     return supplyUserService;
 42     }
 43     public void setSupplyUserService(SupplyUserService supplyUserService) {
 44     this.supplyUserService = supplyUserService;
 45     }
 46     
 47     @GET
 48     @Path("getAllSupplyUser")
 49     @Override
 50     public List<SupplyUserDTO> getAllSupplyUsers() {
 51 
 52     List<SupplyUserDTO> supplyUserDTOList = new ArrayList<SupplyUserDTO>();
 53 
 54     List<SupplyUser> supplyUserList = supplyUserService.getAllSupplyUser();
 55     for (int i = 0; i < supplyUserList.size(); i++) {
 56         SupplyUserDTO tempSupplyUserDTO = new SupplyUserDTO();
 57         tempSupplyUserDTO.setSupplycode(supplyUserList.get(i)
 58             .getSupplycode());
 59         tempSupplyUserDTO.setSupplypass(supplyUserList.get(i)
 60             .getSupplypass());
 61         tempSupplyUserDTO.setSupplyname(supplyUserList.get(i)
 62             .getSupplyname());
 63         supplyUserDTOList.add(tempSupplyUserDTO);
 64     }
 65 
 66     return supplyUserDTOList;
 67     }
 68 
 69     @SuppressWarnings({ "unused" })
 70     @GET
 71     @Path("getUserByIdAndName")
 72     @Override
 73     public String userLogin(
 74         @DefaultValue("V187") @QueryParam("username") String username,
 75         @DefaultValue("123456") @QueryParam("password") String password) {
 76     System.out.println("當前登陸用戶:" + username);
 77     String md5Pass = ""; // MD5處理過的密碼
 78     
 79     // 設置登陸反饋信息變量:1—成功;2—用戶名不存在;3—密碼無效登陸失敗。
 80     String msg = null;
 81 
 82     EncryptHelper md5Helper = new EncryptHelper();
 83 
 84     // 應用本地庫
 85     SupplyUser suppUser = new SupplyUser();
 86     
 87     try {
 88         suppUser = supplyUserService.getSupplyUserByVCode(username);
 89     } catch (Exception e) {
 90         suppUser = null;
 91         e.printStackTrace();
 92     }
 93     
 94     if (suppUser == null) {
 95         suppUser = new SupplyUser();
 96         if (username.equals("suptest")){
 97         suppUser.setSupplycode("V187");
 98         suppUser.setSupplyname("供應商端測試");
 99         suppUser.setSupplypass("123456");
100         }
101         else if(username.equals("ouctest")) {
102         suppUser.setSupplycode("ouctest");
103         suppUser.setSupplyname("ouc端測試");
104         suppUser.setSupplypass("123456");
105         }
106     } else {
107         try {
108         md5Pass = md5Helper.md5Encode(password).toUpperCase();
109         } catch (Exception e) {
110         // TODO Auto-generated catch block
111         e.printStackTrace();
112         }
113         System.out.println("MD5後的密碼:" + md5Pass);
114         password = md5Pass;
115     }
116 
117     // 反饋信息設置
118     if (suppUser == null) {
119         msg = "2";   // 用戶名不存在
120     } else {
121         if (suppUser.getSupplypass().equals(password)) {
122         if (suppUser.getSupplycode().equals("haiertest")){
123             //msg = "1";      //ouc端用戶登陸
124             msg = "ouc";      //ouc端
125         }
126         else {
127             //msg = "0";      //供應商端用戶登陸
128             msg = suppUser.getSupplycode();  //供應商端V碼
129         }
130         } else {
131            msg = "3";// 密碼無效
132         }
133     }
134     return msg;
135     }
136 
137 }
View Code

   1.5 task任務調度工程

       Task任務調度工程結構如圖:
      
    示例中的爲帳號過時按期掃描做業AccountExpireJob。

    配置文件示例spring-lts-job.xml:如圖1-35所示。

    序號①爲設置做業執行週期。

   

2. 橋樑輔助控制

    橋樑工程結構以下圖所示:
   

    包括控制controller、輔助類domain、excel處理、環境配置過濾器filter、操做攔截器interceptor、輔助工具utils等。

資源文件有:spring接口和代理服務配置文件root-context.xml、網頁servlet攔截器配置文件servlet-context.xml、redis配置文件redis-persistence-context.xml。  項目環境配置文件filter,網頁web.xml配置文件。

    1)  項目環境配置文件filter:dev.properties,以下圖所示。

   dev.properties文件中:

    序號①爲項目環境類別說明。

    序號②爲日誌配置。

    序號③爲項目驗證url地址。

    序號④爲redis相關配置。

    序號⑤爲dubbo相關配置。

    序號⑥爲項目中央倉庫地址配置。

   序號⑦爲集羣平臺terracotta配置。

    ★序號⑧爲與頁面工程相關的配置:

    應用簡稱(app.name),服務器名稱(server.name),與頁面工程有關的服務Key(server.key),dubbo應用名(dubbo.application.name),頁面工程路徑(publicPathPrefix),瀏覽器訪問域名(domain.name)和默認跳轉頁面(login.after.jump.url)。

    序號⑨爲項目集團內網和外網環境安全配置。

   

  2)  Web.xml配置文件:

   主要內容有配置系統啓動監聽器startupListeners,基於緩存實現的集羣session配置和編碼過濾等內容。

  

3. 前臺頁面工程

  1) 頁面工程結構以下.

  典型的被linner管理的項目前端工程結構以下:

├─a: app ##app是開發者自開發代碼的存儲目錄.
│ ├─a1: components ##存放項目的組件文件.
│ │ └─ dropdown ##示例組件(此處假設爲dropdown).
│ │     └─ templates ##組件自身的前端模板.
│ │      ├─ view.coffee | view.js ##組件js,可使coffee也能夠是js.
│ │      ├─view.hbs ##組件模板
│  │      └─ view.scss | view.css  ##組件樣式文件,能夠是scss,也能夠是css.
│ ├─ a3: images ##存放項目相關的圖片文件.
│  │       └── logo.png
│ ├─ a5: scripts ##存放項目相關的JavaScript文件.
│ │       └── app.coffee
│ ├─ a6: styles ##存放項目相關的StyleSheet文件.
│ │       └── app.scss
│ ├─ a7: templates ##存放項目相關的前端模板文件.
│ │       └── welcome.hbs
│ ├─ a8: views ##用於存放項目相關的頁面文件.
│ │       └──index.html
│ └─ a2: files ##用於存放相關配置文件,例如front_config.yaml等.
├─bin ##用戶可基於此啓動本地服務器(以當前文件夾爲根),固然更好的選擇是適用jigglepuff來啓動一個帶渲染邏輯的服務器.
│ └── server.
├─config.yml ##是整個項目的配置文件.
├─ b: public ##是項目執行linner build後生成的打包文件位置,是發佈項目所須要的全部文件.
├── test ##測試前端項目的單元測試文件所在目錄.
└─ c:  vendor ##存放引入的第三方代碼組件,例如jQuery、Underscore等.

                    

   2) 頁面調用後臺服務

      
 特別注意:配置文件對空格敏感,請謹慎編寫。

  3)   整個項目的配置文件config.yml。

  

  4)  後端服務back_config.yaml配置:

  

  5)  前端頁面引用服務front_config.yaml配置:

  

    6) 頁面hbs示例:

  組件類型調用服務示例

  

   ajax類型服務調用方式

  友情連接:

   handlebars官網:http://handlebarsjs.com/

   Node.js官網:https://nodejs.org/en/

   CoffeeScript 中文網:http://coffee-script.org/#top

   Redis中文官網:http://www.redis.cn/

附件

 A.LTS輕任務調度框架介紹:

   •   LTS框架概況:

      LTS是一個輕任務調度框架,參考hadoop的部分思想。有三種角色, JobClient, JobTracker,TaskTracker。各個節點都是無狀態的,能夠部署多個,來實現負載均衡,實現更大的負載量, 而且框架具備很好的容錯能力。 採用Zookeeper暴露節點信息,master選舉。Mongo存儲任務隊列和任務執行日誌, netty作底層通訊。

       ▶ JobClient : 主要負責提交任務, 和接收任務執行反饋結果。

       ▶ JobTracker : 負責接收並分配任務,任務調度。

       ▶ TaskTracker: 負責執行任務,執行完反饋給JobTracker。

   •   架構圖:

   •   節點組:

      ▶ 一個節點組等同於一個集羣,同一個節點組中的各個節點是對等的,外界不管鏈接節點組中的任務一個節點都是能夠的。

      ▶ 每一個節點組中都有一個master節點,採用zookeeper進行master選舉(master宕機,會自動選舉出新的master節點),框架會提供接口API來監聽master節點的變化,用戶能夠本身使用master節點作本身想作的事情。

      ▶ JobClient和TaskTracker均可以存在多個節點組。譬如JobClient 能夠存在多個節點組。譬如:JobClient 節點組爲‘QN_WEB’中的一個節點提交提交一個只有節點組爲‘QN_TRADE’的TaskTracker 才能執行的任務。

      ▶ (每一個集羣中)JobTacker只有一個節點組。

      ▶ 多個JobClient節點組和多個TaskTracker節點組再加上一個JobTacker節點組, 組成一個大的集羣。


•   工做流程:

     ▶ JobClient提交一個任務給 JobTracker, 這裏我提供了兩種客戶端API, 一種是若是JobTracker 不存在或者提交失敗,直接返回提交失敗。另外一種客戶端是重試客戶端, 若是提交失敗,先存儲文件,返回給客戶端提交成功的信息,待JobTracker可用的時候,再將任務提交。

     ▶ JobTracker收到JobClient提交來的任務,先生成一個惟一的JobID。而後將任務儲存在Mongo集羣中。JobTracker 發現有(任務執行的)可用的TaskTracker節點(組)以後,將優先級最大,最早提交的任務分發給TaskTracker。這裏JobTracker會優先分配給比較空閒的TaskTracker節點,達到負載均衡。

     ▶ TaskTracker收到JobTracker分發來的任務以後,執行。執行完畢以後,再反饋任務執行結果給JobTracker(成功or 失敗[失敗有失敗錯誤信息]),若是發現JobTacker不可用,那麼存儲文件,等待TaskTracker可用的時候再反饋。反饋結果的同時,詢問 JobTacker有沒有新的任務要執行。

      ▶ JobTacker收到TaskTracker節點的任務結果信息,生成並插入(mongo)任務執行日誌。根據任務信息決定要不要反饋給客戶端。不須要反饋的直接刪除, 須要反饋的(一樣JobClient不可用存儲文件,等待可用重發)。

     ▶ JobClient收到任務執行結果,進行本身想要的邏輯處理。

•   特性

    ▶ 負載均衡:

       ▷ JobClient和 TaskTracker會隨機鏈接JobTracker節點組中的一個節點,實現JobTracker負載均衡。當鏈接上後,將一直保持鏈接這個節點,保持鏈接通道,知道這個節點不可用,減小每次都從新鏈接一個節點帶來的性能開銷。

        ▷ JobTracker分發任務時,是優先分配給最空間的一個TaskTracker節點,實現TaskTracker節點的負載均衡。

    ▶ 健壯性:

        ▷ 當節點組中的一個節點當機以後,自動轉到其餘節點工做。當整個節點組當機以後,將會採用存儲文件的方式,待節點組可用的時候進行重發。

       ▷ 當執行任務的TaskTracker節點當機以後,JobTracker會將這個TaskTracker上的未完成的任務(死任務),從新分配給節點組中其餘節點執行。

    ▶ 伸縮性:

    由於各個節點都是無狀態的,能夠動態增長機器部署實例, 節點關注者會自動發現。

•   調用示例

     安裝 zookeeper 和 mongo , 執行 data/mongo目錄下的 mongo.md 中的語句見 job-example 這裏給出的是java API(設置配置)方式啓動,也可使用配置文件中。

   ▶ JobTracker端


   ▶ JobClient端


   ▶ TaskTracker端

相關文章
相關標籤/搜索