成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot與ZooKeeper整合,實現智能停車計費系統

開發 前端
在多臺服務器同時處理車輛進出記錄的情況下,使用ZooKeeper的分布式鎖可以確保同一輛車的計費操作在同一時間只能由一臺服務器處理。這避免了并發問題,保證了計費的準確性和一致性。

智能停車計費系統通過分布式鎖技術確保在多臺服務器環境下,同一輛車的計費操作不會發生沖突,從而保證計費的準確性和一致性。

關鍵點

1. 高并發處理

  • 需求: 停車場可能有大量的車輛同時進出,尤其是在高峰時段。
  • 解決方案: 使用分布式架構和高效的數據庫管理來處理高并發請求。

2. 數據一致性

  • 需求: 確保在多臺服務器環境下,同一輛車的計費操作不會發生沖突。
  • 解決方案: 使用分布式鎖(如ZooKeeper)來保證數據的一致性和準確性。

3. 實時性

  • 需求: 需要快速響應車輛的進出事件,并及時計算費用。
  • 解決方案: 優化算法和數據庫查詢,確保低延遲。

使用ZooKeeper的好處

1. 分布式鎖

  • 保證數據一致性: 在多臺服務器同時處理車輛進出記錄的情況下,使用ZooKeeper的分布式鎖可以確保同一輛車的計費操作在同一時間只能由一臺服務器處理。這避免了并發問題,保證了計費的準確性和一致性。
  • 防止重復計費: 如果沒有分布式鎖,可能會出現同一輛車多次被不同服務器計費的情況,導致重復收費或計費錯誤。

2. 高可用性

  • 容錯能力: ZooKeeper本身是一個高可用的服務,即使某一臺ZooKeeper節點故障,其他節點仍然可以繼續提供服務。這提高了整個系統的穩定性和可靠性。
  • 負載均衡: 分布式鎖機制可以幫助均勻分配任務到不同的服務器上,提高系統的整體性能和響應速度。

3. 易于擴展

  • 動態增加服務器: 隨著業務的增長,可以通過簡單地增加更多的服務器來處理更多的請求。ZooKeeper可以輕松管理這些新增的服務器,并確保它們能夠正確協同工作。
  • 靈活性: 添加新的功能或調整現有邏輯時,ZooKeeper的分布式特性使得這些更改更容易實現和部署。

4. 簡化協調過程

  • 統一協調: ZooKeeper提供了一種集中式的協調機制,使得多個服務器之間的通信和同步變得簡單和高效。不再需要復雜的自定義協議或手動協調邏輯。
  • 輕量級: ZooKeeper的設計目標是輕量級且高性能,適合在各種規模的應用中使用。

5. 監控和日志

  • 實時監控: ZooKeeper提供了豐富的監控工具和API,可以實時監控集群的狀態和健康狀況。
  • 審計日志: 可以通過ZooKeeper的日志功能跟蹤所有對共享資源的操作,便于審計和故障排查。

代碼實操

<!-- Spring Boot Starter Web for RESTful services -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Apache Curator for ZooKeeper interaction -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${curator.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>${curator.version}</version>
        </dependency>

        <!-- Lombok for reducing boilerplate code -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

application.properties

zookeeper.connect-string=localhost:2181

ZookeeperConfig.java

package com.example.parking.config;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置ZooKeeper連接。
 */
@Configuration
publicclass ZookeeperConfig {

    @Value("${zookeeper.connect-string}")
    private String zkConnectString;

    /**
     * 創建并返回一個CuratorFramework實例。
     * @return CuratorFramework實例
     */
    @Bean(initMethod = "start", destroyMethod = "close")
    public CuratorFramework curatorFramework() {
        return CuratorFrameworkFactory.newClient(zkConnectString, new ExponentialBackoffRetry(1000, 3));
    }
}

ParkingController.java

package com.example.parking.controller;

import com.example.parking.model.ParkingRequest;
import com.example.parking.service.ParkingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
 * 提供HTTP接口用于車輛進入和離開停車場的操作。
 */
@RestController
@RequestMapping("/parking")
publicclass ParkingController {

    @Autowired
    private ParkingService parkingService;

    /**
     * 車輛進入停車場。
     * @param request 包含車輛ID的請求對象
     * @return 成功或失敗的消息
     */
    @PostMapping("/enter")
    public ResponseEntity<String> enterParkingLot(@RequestBody ParkingRequest request) {
        boolean success = parkingService.enterParkingLot(request.getCarId());
        if (success) {
            return ResponseEntity.ok("Vehicle entered parking lot.");
        } else {
            return ResponseEntity.badRequest().body("Failed to enter parking lot.");
        }
    }

    /**
     * 車輛離開停車場。
     * @param request 包含車輛ID和停留時間的請求對象
     * @return 成功或失敗的消息
     */
    @PostMapping("/leave")
    public ResponseEntity<String> leaveParkingLot(@RequestBody ParkingRequest request) {
        long durationInMinutes = request.getDurationInMinutes();
        boolean success = parkingService.leaveParkingLot(request.getCarId(), durationInMinutes);
        if (success) {
            return ResponseEntity.ok("Vehicle left parking lot. Fee calculated and stored.");
        } else {
            return ResponseEntity.badRequest().body("Failed to leave parking lot.");
        }
    }
}

ParkingDao.java

package com.example.parking.dao;

import com.example.parking.entity.ParkingRecord;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.Map;

/**
 * 數據訪問對象,負責存儲和檢索停車記錄。
 */
@Repository
publicclass ParkingDao {

    privatefinal Map<String, ParkingRecord> records = new HashMap<>();

    /**
     * 記錄車輛進入停車場的時間。
     * @param carId 車輛ID
     * @return 是否成功記錄
     */
    public boolean saveEntry(String carId) {
        if (!records.containsKey(carId)) {
            records.put(carId, new ParkingRecord(carId));
            returntrue;
        }
        returnfalse;
    }

    /**
     * 獲取指定車輛的停車記錄。
     * @param carId 車輛ID
     * @return 停車記錄
     */
    public ParkingRecord getRecord(String carId) {
        return records.get(carId);
    }

    /**
     * 移除指定車輛的停車記錄。
     * @param carId 車輛ID
     * @return 是否成功移除
     */
    public boolean removeRecord(String carId) {
        return records.remove(carId) != null;
    }
}

ParkingRecord.java

package com.example.parking.entity;

import java.time.LocalDateTime;

/**
 * 實體類,表示一輛車的停車記錄。
 */
publicclass ParkingRecord {

    private String carId;
    private LocalDateTime entryTime;

    /**
     * 構造函數,初始化停車記錄。
     * @param carId 車輛ID
     */
    public ParkingRecord(String carId) {
        this.carId = carId;
        this.entryTime = LocalDateTime.now();
    }

    /**
     * 獲取車輛ID。
     * @return 車輛ID
     */
    public String getCarId() {
        return carId;
    }

    /**
     * 獲取車輛進入停車場的時間。
     * @return 進入時間
     */
    public LocalDateTime getEntryTime() {
        return entryTime;
    }
}

ParkingRequest.java

package com.example.parking.model;

/**
 * 請求模型,包含車輛ID和停留時間。
 */
publicclass ParkingRequest {

    private String carId;
    privatelong durationInMinutes;

    // Getters and Setters
    /**
     * 獲取車輛ID。
     * @return 車輛ID
     */
    public String getCarId() {
        return carId;
    }

    /**
     * 設置車輛ID。
     * @param carId 車輛ID
     */
    public void setCarId(String carId) {
        this.carId = carId;
    }

    /**
     * 獲取停留時間(分鐘)。
     * @return 停留時間
     */
    public long getDurationInMinutes() {
        return durationInMinutes;
    }

    /**
     * 設置停留時間(分鐘)。
     * @param durationInMinutes 停留時間
     */
    public void setDurationInMinutes(long durationInMinutes) {
        this.durationInMinutes = durationInMinutes;
    }
}

ParkingService.java

package com.example.parking.service;

/**
 * 接口定義了進入和離開停車場的方法。
 */
public interface ParkingService {

    /**
     * 車輛進入停車場。
     * @param carId 車輛ID
     * @return 是否成功進入
     */
    boolean enterParkingLot(String carId);

    /**
     * 車輛離開停車場。
     * @param carId 車輛ID
     * @param durationInMinutes 停留時間(分鐘)
     * @return 是否成功離開
     */
    boolean leaveParkingLot(String carId, long durationInMinutes);
}

ParkingServiceImpl.java

package com.example.parking.service.impl;

import com.example.parking.dao.ParkingDao;
import com.example.parking.entity.ParkingRecord;
import com.example.parking.service.ParkingService;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 實現了ParkingService接口的具體邏輯,并使用ZooKeeper的互斥鎖來保證同一輛車的計費操作不會被并發執行。
 */
@Service
publicclass ParkingServiceImpl implements ParkingService {

    privatefinal CuratorFramework client;
    privatefinal ParkingDao parkingDao;

    @Autowired
    public ParkingServiceImpl(CuratorFramework client, ParkingDao parkingDao) {
        this.client = client;
        this.parkingDao = parkingDao;
    }

    /**
     * 車輛進入停車場。
     * @param carId 車輛ID
     * @return 是否成功進入
     */
    @Override
    public boolean enterParkingLot(String carId) {
        return parkingDao.saveEntry(carId);
    }

    /**
     * 車輛離開停車場。
     * @param carId 車輛ID
     * @param durationInMinutes 停留時間(分鐘)
     * @return 是否成功離開
     */
    @Override
    public boolean leaveParkingLot(String carId, long durationInMinutes) {
        InterProcessMutex lock = new InterProcessMutex(client, "/locks/" + carId);

        try {
            if (lock.acquire(10, TimeUnit.SECONDS)) {
                try {
                    if (!enterParkingLot(carId)) {
                        returnfalse;
                    }

                    ParkingRecord record = parkingDao.getRecord(carId);
                    double fee = calculateFee(record, durationInMinutes);
                    System.out.println("Calculated fee for " + carId + ": $" + fee);
                    // Logic to store the fee in a database or other storage system
                    parkingDao.removeRecord(carId);
                    returntrue;
                } finally {
                    lock.release();
                }
            } else {
                System.err.println("Could not acquire lock for " + carId);
                returnfalse;
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnfalse;
        }
    }

    /**
     * 計算停車費用。
     * @param record 停車記錄
     * @param durationInMinutes 停留時間(分鐘)
     * @return 停車費用
     */
    private double calculateFee(ParkingRecord record, long durationInMinutes) {
        double ratePerMinute = 0.5;
        return durationInMinutes * ratePerMinute;
    }
}

ParkingApplication.java

package com.example.parking;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Spring Boot應用的主類。
 */
@SpringBootApplication
public class ParkingApplication {

    public static void main(String[] args) {
        SpringApplication.run(ParkingApplication.class, args);
    }
}

測試結果

確保ZooKeeper服務器正在運行。

車輛進入停車場

http://localhost:8080/parking/enter   
     {
       "carId": "A123"
     }
  • 響應:
Vehicle entered parking lot.

車輛離開停車場

http://localhost:8080/parking/leave
     {
       "carId": "A123",
       "durationInMinutes": 60
     }
  • 響應:
Vehicle left parking lot. Fee calculated and stored.
  • 控制臺輸出:
Calculated fee for A123: $30.0


責任編輯:武曉燕 來源: Java知識日歷
相關推薦

2025-05-06 08:40:21

SpringPostGIS系統

2025-06-03 02:10:00

SpringInfluxDB數據

2025-04-23 08:50:00

SpringBootCurator分布式鎖

2021-07-20 15:20:53

物聯網IoT智能停車

2020-05-21 21:15:35

智能停車物聯網IOT

2025-04-08 08:50:37

SpringCamel系統

2025-05-09 08:34:57

RSocketSpringBoot聊天系統

2025-03-31 08:43:34

SpringTika優化

2025-03-03 07:30:00

SpringBootJGraphT網絡建模

2025-03-13 08:37:58

Spring智能條款系統

2025-03-11 09:28:34

2017-05-09 10:07:34

SpringbootDubboZooKeeper

2025-04-21 03:00:00

2025-02-26 09:24:54

SpringMySQLMyBatis

2025-03-26 01:55:00

Spring協議物聯網

2025-03-20 08:57:54

Spring日志存儲系統

2025-04-25 08:34:52

2025-03-21 08:55:36

SpringOpenFeignAPI

2025-04-01 08:38:41

2025-04-18 08:54:30

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜久久久久久久久久一区二区 | 国产av毛片 | 成人国产在线视频 | 五月天天丁香婷婷在线中 | 91欧美激情一区二区三区成人 | 野狼在线社区2017入口 | 欧美亚洲高清 | 亚欧精品一区 | 成人欧美日韩一区二区三区 | 国产精品久久影院 | 午夜在线影院 | 免费欧美视频 | 国产乱码精品一区二区三区忘忧草 | 性色av一区二区三区 | 国产精品视频www | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 国产精品日产欧美久久久久 | 国产精品日日做人人爱 | 97视频成人 | 二区三区在线观看 | 欧美二区在线 | 2019天天干夜夜操 | 久久久91 | 狠狠色狠狠色综合日日92 | 97精品一区二区 | 国产日韩精品久久 | 欧美成人a∨高清免费观看 色999日韩 | 亚洲成人高清 | 久久久高清 | 日韩国产一区二区三区 | 国产精品中文字幕在线 | 黄色三级毛片 | www国产精品 | av天天看| 久久69精品久久久久久久电影好 | 国产日韩一区二区三区 | 欧美一二三四成人免费视频 | 麻豆精品一区二区三区在线观看 | 毛片久久久 | 天天艹 | 一级毛片视频 |