
目前,在CSDN包含個人博客中,關(guān)于mongodb集群部署是非常多的,這篇主要是針對于多臺機器,部署mongodb副本集,并通過Java代碼進行驗證,其中,Java代碼使用主流的SpringBoot架構(gòu)。
首先,我們進行mongodb的下載,下載地址為:
https://download.csdn.net/download/weixin_41986096/11539922
可以將mongodb下載后放在任意一個文件夾中,進行解壓。我們是放在了

本文主要采用mongodb在windows中實現(xiàn)副本集集群,由三個節(jié)點組成的 副本集 為網(wǎng)絡(luò)故障或是其他的系統(tǒng)故障提供了足夠的冗余。該副本集也有足夠的分布式讀操作的能力。副本集應(yīng)該保持奇數(shù)個節(jié)點,這也就保證了 選舉 可以正常的進行
在生產(chǎn)環(huán)境的部署中,我們應(yīng)該盡可能將副本集中得節(jié)點置于不同的機器上。當使用虛擬機的時候,我們應(yīng)該將 mongod實例置于擁有冗余電源和冗余網(wǎng)絡(luò)的機器上。我們應(yīng)該將每個節(jié)點部署在獨立的機器上,并使用標準的MongoDB端口 27017 。使用 bind_ip 參數(shù)來限制訪問MongoDB的應(yīng)用程序的地址。
副本集的容錯性是指可以變?yōu)椴豢捎?,并且在該集中仍保留足夠的成員以選擇主要成員的成員數(shù)。換言之,這是一個群體中成員的數(shù)量與選舉初選所需的多數(shù)投票成員之間的差異。沒有主副本集,副本集就不能接受寫操作。容錯是副本集大小的一個影響,但這種關(guān)系不是直接的。見下表

目錄結(jié)構(gòu)的準備:
準備三臺機器為windows服務(wù)器。首先將mongodb拷貝到每一個服務(wù)器中,我們是拷貝到了E:\mongodb\ 下進行解壓文件
啟動mongodb看是否能正常啟動,可使用mongodb 工具進行連接測試

工具下載地址:
https://download.csdn.net/download/weixin_41986096/11540214
這里將三臺服務(wù)器分別定義為A B C 服務(wù)器,方便闡述。
在A B C 服務(wù)器的E:\mongodb\mongodb-win32-x86_64-2008plus-2.6.0\bin中分別編寫mongodb的啟動腳本,如果已經(jīng)有啟動腳本,建議刪除。
腳本如下所示:
mongod --port 27017 --dbpath ..\data\agri\ --logpath ..\logs\mongo.log --logappend --replSet mySet
port Mongodb的監(jiān)聽端口
dbpath 數(shù)據(jù)文件存儲路徑
logpath 系統(tǒng)日志存放路徑
replSet 副本集名稱,我用的是mySet,其他的節(jié)點必須使用這個名字做副本集名稱
logappend 日志的寫入模式是追加,不是默認的覆蓋模式
分別在E:\mongodb\mongodb-win32-x86_64-2008plus-2.6.0\data\下建立文件夾agri,名稱可以隨便起,只要和腳本配置文件路徑保持一致就行。
注意:dbpath 在配置前,必須保證是空文件夾
以上腳本配置可以通過bat文件來完成,也可以建立配置文件來完成,具體配置如下:

建立mongo.conf文件,進行如下配置:
數(shù)據(jù)庫地址
dbpath = E:\mongodb\mongodb-win32-x86_64-2008plus-2.6.0\data\agri
數(shù)據(jù)庫端口號
port = 27017
數(shù)據(jù)庫所在服務(wù)器
bind_ip = 192.168.191.228
日志地址
logpath = E:\mongodb\mongodb-win32-x86_64-2008plus-2.6.0\logs\mongo.log
日志追加
logappend = true
副本集名稱
replSet = mySet
啟動文件mongo_start.bat文件配置如下:
mongod --config mongo.conf
如上步驟,在A B C 三臺服務(wù)器上分別建立啟動腳本和配置文件
連接Mongod實例:
分別啟動A B C 三臺服務(wù)器,并在A 服務(wù)器中找到E:\mongodb\mongodb-win32-x86_64-2008plus-2.6.0\bin位置,開啟cmd窗口,執(zhí)行mongod命令設(shè)置對應(yīng)的副本集配置:
首先輸入mongo -port 27017 連接mongodb庫
連接成功輸入副本集配置信息:
config_set={"_id":"mySet",members:[{_id:0,host:"192.168.191.228:27017"},{_id:1,host:"192.168.191.243:27017"},{_id:2,host:"192.168.191.241:27017"}]}
然后執(zhí)行rs.initiate(config_set)


測試連接A B C 服務(wù)器三個庫:

能正常連接
SpringBoot 進行代碼測試:
首先我們建立一個SpringBoot的項目,在pom中引入需要的jar包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
在application.properties中加入相關(guān)配置信息
#mongodb
# 單機模式 mongodb://name:pass@ip:port/database
# 集群模式 mongodb://user:pwd@ip1:port1,ip2:port2/database
#spring.data.mongodb.uri=mongodb://127.0.0.1:27017/agri
spring.data.mongodb.uri=mongodb://192.168.191.228:27017,192.168.191.243:27017,192.168.191.241:27017/agri
建立需要存儲文本信息的實體
package com.herbert.accident.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.io.Serializable;
import java.util.Date;
/**
* 通知消息對象
* @author oKong
*
*/
@Document(collection="data")//集合名
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NotifyMsg implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8985545025018238754L;
@Id
String id;
/**
* 消息類型
*/
@Indexed
String notifyType;
/**
* 消息單號
*/
@Indexed
String notifyNo;
/**
* 消息通知日期
*/
String notifyDate;
/**
* 消息體
*/
@Field("data")//可指定存儲時的字段名
String notifyMsg;
/**
* 創(chuàng)建時間
*/
@CreatedDate
Date gmtCreate;
}
建立需要存儲文本信息的Server接口
package com.herbert.accident.service;/**
* Created by Herbert on 2019/8/7.
*/
import com.herbert.accident.entity.NotifyMsg;
import java.util.List;
/**
* @author :
* @date :Created in 2019/8/7 15:54
* @description:
* @modified By:
* @version: $
*/
public interface NotifyMsgService {
/**
* 保存數(shù)據(jù)
*
*/
NotifyMsg saveNotifyMsg(NotifyMsg msg);
/**
* 根據(jù)消息號查找
*
*/
NotifyMsg findNotifyMsgByNo(String notifyNo);
/**
* 根據(jù)消息日期查找
*
*/
List<NotifyMsg> findNotifyMsgByDate(String notifyDate);
/**
* 根據(jù)id進行刪除 返回刪除的對象
*
*/
NotifyMsg delNotifyMsgById(String id);
}
建立接口的實現(xiàn)類
package com.herbert.accident.service.impl;/**
* Created by Herbert on 2019/8/7.
*/
import com. herbert.accident.entity.NotifyMsg;
import com. herbert.accident.service.NotifyMsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author :
* @date :Created in 2019/8/7 15:55
* @description:
* @modified By:
* @version: $
*/
@Service
public class NotifyMsgServiceImpl implements NotifyMsgService {
@Autowired
MongoTemplate mongoTemplate;
@Override
public NotifyMsg saveNotifyMsg(NotifyMsg msg) {
//使用 save和insert都可以進行插入
//區(qū)別:當存在"_id"時
//insert 插入已經(jīng)存在的id時 會異常
//save 則會進行更新
//簡單來說 save 就是不存在插入 存在更新
mongoTemplate.insert(msg);
mongoTemplate.save(msg);
return msg;
}
@Override
public NotifyMsg findNotifyMsgByNo(String notifyNo) {
//根據(jù)Criteria 改造查詢條件
Query query = new Query(Criteria.where("notifyNo").is(notifyNo));
return mongoTemplate.findOne(query, NotifyMsg.class);
}
@Override
public List<NotifyMsg> findNotifyMsgByDate(String notifyDate) {
//查找 notifyDate 根據(jù)Criteria 改造查詢條件
Query query = new Query(Criteria.where("notifyDate").is(notifyDate));
return mongoTemplate.find(query, NotifyMsg.class);
}
@Override
public NotifyMsg delNotifyMsgById(String id) {
//查找 id 根據(jù)Criteria 改造查詢條件
Query query = new Query(Criteria.where("id").is(id));
return mongoTemplate.findAndRemove(query, NotifyMsg.class);
}
}
建立請求訪問的Controller
package com.herbert.accident.controller;/**
* Created by Herbert on 2019/8/7.
*/
import com.herbert.accident.entity.NotifyMsg;
import com.herbert.accident.service.NotifyMsgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author :
* @date :Created in 2019/8/7 15:56
* @description:
* @modified By:
* @version: $
*/
@RestController
@RequestMapping("/template")
@Slf4j
public class MongoTemplateController {
@Autowired
NotifyMsgService notifyMsgService;
@PostMapping("/add")
public NotifyMsg add(NotifyMsg msg) {
log.info("mongoTemplate方式新增:{}", msg);
return notifyMsgService.saveNotifyMsg(msg);
}
@PostMapping("del/{id}")
public NotifyMsg del(@PathVariable String id) {
log.info("mongoTemplate方式刪除:{}", id);
return notifyMsgService.delNotifyMsgById(id);
}
@GetMapping("/find/{no}")
public NotifyMsg findNotifyMsgByNo(@PathVariable String no){
log.info("mongoTemplate方式查找:notifyNo-{}", no);
return notifyMsgService.findNotifyMsgByNo(no);
}
@GetMapping("/find/list/{date}")
public List<NotifyMsg> findNotifyMsgByDate(@PathVariable String date){
log.info("mongoTemplate方式查找:notifyDate-{}", date);
return notifyMsgService.findNotifyMsgByDate(date);
}
}
我們進行請求測試,測試工具這邊使用的是postman測試
啟動服務(wù)后:

上面啟動已經(jīng)標明主節(jié)點和子節(jié)點
啟動成功標志:

下來我們進行訪問接口
訪問接口保存數(shù)據(jù):
接口類型為POST請求
http://127.0.0.1:6660/template/add?notifyType=2¬ifyNo=3¬ifyMsg=789456123

請求成功:

訪問接口查詢上次保存的數(shù)據(jù):
接口類型為GET請求

現(xiàn)在我們隨意關(guān)閉A B C中的一個Mongodb,繼續(xù)訪問剛才保存的數(shù)據(jù):
接口類型為GET請求


副本集 為網(wǎng)絡(luò)故障或是其他的系統(tǒng)故障依然可以訪問到原始保存的數(shù)據(jù)。
需要注意問題:
1:在建立dbpath數(shù)據(jù)文件存儲路徑的時候,該路徑下必須為空文件夾
2:創(chuàng)建副本集腳本執(zhí)行的時候,確保和副本集名稱保持一致
3:盡量使用默認標準的MongoDB端口 27017
歡迎關(guān)注微信公眾號:
