# 无忧出行网约车项目
**Repository Path**: workBase/worry-free-travel
## Basic Information
- **Project Name**: 无忧出行网约车项目
- **Description**: 基于分布式微服务架构的网约车项目。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 26
- **Created**: 2024-07-03
- **Last Updated**: 2024-07-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 无忧出行网约车项目
## 介绍
基于分布式微服务架构的网约车项目,分为乘客端,司机端以及运营端,实现了登录,乘客预估,乘客发单,司机接单,司乘同显,订单状态变更,支付等完整打车业务流程。
## 技术架构
SpringBoot+ OpenFeign+ Kafka + Redis + MySQL+ Nacos + Seate + Mybatis + Mybatis-plus + Docker + UniApp + Vue 等。
 |
分布式微服务中台架构 |
## 主要功能
1. 账号系统:乘客司机注册登录以及信息变更,使用JWT生成双Token,使用Redis存储Token实现身份验证以及权限校验。
2. 订单系统:订单创建,取消订单,订单状态变更等功能,使用Seate AT模式实现分布式事务保证订单状态更改和司机完单数的数据一致性。
3. 派单引擎:使用Kafka多分区机制,批量拉取和线程池实现订单的快速消费,使用CountDownLatch计数等待异步提交offset;使用Redisson分布式锁保证一司机一单;使用贪心策略实现最优匹配,部分地区使用匈牙利算法实现全局最优匹配。
4. 地图模块:使用高德猎鹰服务实现车辆调度,坐标上传,轨迹查询,路径规划等;使用高德地图服务实现定位点标记,轨迹绘制,车辆运动。
5. 消息模块:使用服务端推送技术SSE实现消息通知,对乘客和司机进行订单消息和订单状态变更的通知,同时通过实时推送司机坐标给乘客实现司乘同显;使用CurrentHashMap保存SSE对象,解决线程安全问题。
6. 计价系统:提供开城服务,即添加计价规则,使用版本号机制保证预估和行程中计价规则的统一;使用BigDecimal 计算价格。
7. 支付系统:接入支付宝沙箱支付,完成同步回调和异步回调。
## 司乘业务流程图
 |
乘客端业务流程图 |
 |
司机端业务流程图 |
## 部分订单消费逻辑
```java
@Component
@Slf4j
public class KafkaConsumer {
@Autowired
private DispatchService dispatchService;
@Autowired
private KafkaProducer kafkaProducer;
/**
* 高度 io 任务,核心线程数设置为cpu核数的2倍
*/
private int coreSize = 2*Runtime.getRuntime().availableProcessors();
private final ExecutorService executorService = Executors.newFixedThreadPool(coreSize);
/**
* 消费者
* @param records
* @param acknowledgment
* @return
* @describute concurrency = "2" 表示开启两个消费者线程消费两个分区
*/
@KafkaListener(topics = {"travel-topic"}, concurrency = "2")
public void consumer(List> records, Acknowledgment acknowledgment) {
// 倒计时锁,取一半,防止线程池溢出,当不减少时,说明出现了严重的司乘供需不平衡,此时不再从kafka马上拉取
// 直到一半任务完成,说明线程池有一半空余线程了,可以继续拉取订单
CountDownLatch latch = new CountDownLatch(records.size()/2);
for (ConsumerRecord record : records) {
executorService.execute(() -> {
log.info("consumer, topic:{}, partition:{}, value: {}",
record.topic(), record.partition(), record.value());
// 消费消息,订单匹配
consumeMsg(record.value());
latch.countDown(); // 任务提交,计数器减一
});
}
try {
latch.await(); // 等待一半任务执行完成就可以提交拉取下一批了,说明至少空出了一半线程
} catch (InterruptedException e) {
e.printStackTrace();
}
// 手动异步提交偏移量
acknowledgment.acknowledge();
}
/**
* 消费消息
* @param msg
*/
public void consumeMsg(String msg){
ObjectMapper objectMapper = new ObjectMapper();
try {
OrderInfo orderInfo = objectMapper.readValue(msg, OrderInfo.class);
// 订单匹配
dispatchService.disPatch(orderInfo);
} catch (Exception e) {
e.printStackTrace();
// 将消费失败的消息放到另一个专门处理失败消息的主题 "errOrderHandle-topic"
kafkaProducer.sendMessage("errOrderHandle-topic",msg);
}
}
}
```
## 项目展示
### 乘客端
### 司机端
## 交流与赞助
### 全栈学习交流1群:[799160455](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=jj15fOLBvm5U97kuj-Jgvvld2eDACl2o&authKey=fcll1nLa0V9wFMPkJGurdv%2FX%2FHlasFVHpS9vmtuFLofiqBD%2Fgl5fcjXBmg4E3Ovc&noverify=0&group_code=799160455) (已满员)
### 全栈学习交流2群:[879763865](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=mVTtPhPE_-BUOEbNu_IuO-4FZoMR6m43&authKey=heN7%2BG%2FFLoPj1tZ%2Blg%2FWS11WrzYkHkMTVgv9qg9aPGlR5pbEOmzvTBv7npYU1d56&noverify=0&group_code=879763865)
 |
 |
联系我 |
支持本项目 |