Windows 中Mongodb 多臺服務(wù)器實現(xiàn)副本集,集群部署

首發(fā).png

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

可以將mongodb下載后放在任意一個文件夾中,進行解壓。我們是放在了

image.png

本文主要采用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)系不是直接的。見下表


image.png

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


image.png

工具下載地址:

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文件來完成,也可以建立配置文件來完成,具體配置如下:


image.png

建立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)


image.png

image.png

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


image.png

能正常連接

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ù)后:
image.png

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

啟動成功標志:
image.png

下來我們進行訪問接口

訪問接口保存數(shù)據(jù):

接口類型為POST請求
http://127.0.0.1:6660/template/add?notifyType=2&notifyNo=3&notifyMsg=789456123

image.png

請求成功:
image.png

訪問接口查詢上次保存的數(shù)據(jù):

接口類型為GET請求


image.png

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


image.png
image.png

副本集 為網(wǎng)絡(luò)故障或是其他的系統(tǒng)故障依然可以訪問到原始保存的數(shù)據(jù)。

需要注意問題:

1:在建立dbpath數(shù)據(jù)文件存儲路徑的時候,該路徑下必須為空文件夾
2:創(chuàng)建副本集腳本執(zhí)行的時候,確保和副本集名稱保持一致
3:盡量使用默認標準的MongoDB端口 27017

歡迎關(guān)注微信公眾號:
摘星族.jpg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容