Sleuth
- 产生链路跟踪日志
- A --> B --> C
A的id会被当做整条链路的id 默认只有10%的日志会发到Zipkin
A, USFHSAJFGVDMJ, USFHSAJFGVDMJ ,true
B, USFHSAJFGVDMJ ,FGRJEGNTHYJN5 ,false
C, USFHSAJFGVDMJ ,GJREG98GEWU87 ,false
使用Sleuth
- 添加Sleuth依赖
- 修改2,3,4,6,有自动配置类
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
链路日志发送到Zipkin处理
两种方式
1.直接连接,向Zipkin提交日志 2.通过消息服务转发日志 解耦、流量削峰
通过消息服务实现步骤
1. 添加Zipkin client依赖至2.3.4.6
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
2. 在06项目添加rabiitmq依赖
(2.3.4已经加过了)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
3. 四个模块中,配置发送方式
- rabbit(还有activemq、kafka、web发送方式)
- 在config目录修改,再推送到远程仓库
06 02.03.04
5.下载jar文件
6. 启动zipkin服务器
java -jar z.jar --zipkin.collector.rabbitmq.uri=amqp://admin:admin@192.168.64.140:5672
访问http://localhost:3001/order-service/u56uy454y
Rabbitmq 订单流量削峰案例
1.导入商城项目 2.修改pom.xml拖拽到idea 把springboot版本改成2.3.2RELEASE 3.右键pom.xml编辑器 4.导入sql脚本 5.yml配置查看
订单发送到rabbitmq
- 添加 rabbitmq依赖连接配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
server:
port: 80
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/pd_store?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
rabbitmq:
host: 192.168.64.140
port: 5672
username: admin
password: admin
virtual-host: /
mybatis:
mapperLocations: classpath:com.pd.mapper/*.xml
logging:
level:
cn.tedu.ssm.mapper: debug
resources:
static-locations: classpath:/
cache-period: 0
- 在启动类(或者自定义自动配置类)中设置队列的参数:orderQueue,true,false,false
package com.pd;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.core.Queue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@MapperScan("com.pd.mapper")
public class RunPdAPP{
public static void main(String[] args) {
SpringApplication.run(RunPdAPP.class, args);
}
@Bean
public Queue orderQueue(){
return new Queue("orderQueue",true,false,false);
}
}
- 修改OrderserviceImpl
注入对象:AmqpTemplate 用来封装消息发送的API工具 发送消息
订单的消费者 1.rabbitmq基础配置,准备队列参数 2.新建消费者类:OrderConsumer 3.用注解配置接收消息 4.收到的订单通过原来的业务代码,存储到数据库
package com.pd.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.pd.mapper.PdCartItemMapper;
import com.pd.mapper.PdItemMapper;
import com.pd.mapper.PdItemParamItemMapper;
import com.pd.mapper.PdOrderItemMapper;
import com.pd.mapper.PdOrderMapper;
import com.pd.mapper.PdShippingMapper;
import com.pd.pojo.PdCartItem;
import com.pd.pojo.PdCartItemExample;
import com.pd.pojo.PdItem;
import com.pd.pojo.PdItemParamItem;
import com.pd.pojo.PdItemParamItemExample;
import com.pd.pojo.PdOrder;
import com.pd.pojo.PdOrderExample;
import com.pd.pojo.PdOrderItem;
import com.pd.pojo.PdOrderItemExample;
import com.pd.pojo.PdShipping;
import com.pd.pojo.ItemVO;
import com.pd.pojo.OrderVO;
import com.pd.pojo.paramData.PdItemParamData;
import com.pd.pojo.paramData.Params;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pd.common.utils.JsonUtils;
import com.pd.service.OrderService;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
PdOrderMapper pdOrderMapper;
@Autowired
PdCartItemMapper pdCartItemMapper;
@Autowired
PdItemMapper pdItemMapper;
@Autowired
PdItemParamItemMapper pdItemParamItemMapper;
@Autowired
PdShippingMapper pdShippingMapper;
@Autowired
PdOrderItemMapper pdOrderItemMapper;
public String saveOrder(PdOrder pdOrder) throws Exception {
String orderId =pdOrder.getOrderId();
PdShipping pdShipping = pdShippingMapper.selectByPrimaryKey(pdOrder.getAddId());
pdOrder.setShippingName(pdShipping.getReceiverName());
pdOrder.setShippingCode(pdShipping.getReceiverAddress());
pdOrder.setStatus(1);
pdOrder.setPaymentType(1);
pdOrder.setPostFee(10D);
pdOrder.setCreateTime(new Date());
double payment = 0;
List<ItemVO> itemVOs = selectCartItemByUseridAndItemIds(pdOrder.getUserId(), pdOrder.getItemIdList());
for (ItemVO itemVO : itemVOs) {
PdOrderItem pdOrderItem = new PdOrderItem();
String id = generateId();
pdOrderItem.setId(id);
pdOrderItem.setOrderId(orderId);
pdOrderItem.setItemId("" + itemVO.getPdItem().getId());
pdOrderItem.setTitle(itemVO.getPdItem().getTitle());
pdOrderItem.setPrice(itemVO.getPdItem().getPrice());
pdOrderItem.setNum(itemVO.getPdCartItem().getNum());
payment = payment + itemVO.getPdCartItem().getNum() * itemVO.getPdItem().getPrice();
pdOrderItemMapper.insert(pdOrderItem);
}
pdOrder.setPayment(payment);
pdOrderMapper.insert(pdOrder);
return orderId;
}
public synchronized String generateId() {
Random random = new Random();
int number = random.nextInt(9000000) + 1000000;
return "" + System.currentTimeMillis() + number;
}
public List<ItemVO> selectCartItemByUseridAndItemIds(Long userId, List<Long> itemIds) throws Exception {
PdCartItemExample cartItemExample = new PdCartItemExample();
PdCartItemExample.Criteria criteria = cartItemExample.or();
criteria.andUserIdEqualTo(userId);
criteria.andItemIdIn(itemIds);
criteria.andStatusEqualTo(1);
List<PdCartItem> cartItems = pdCartItemMapper.selectByExample(cartItemExample);
List<ItemVO> itemVOs = new ArrayList<>();
for (PdCartItem pdCartItem : cartItems) {
Long itemId = pdCartItem.getItemId();
PdItem pdItem = pdItemMapper.selectByPrimaryKey(itemId);
PdItemParamItemExample paramExample = new PdItemParamItemExample();
PdItemParamItemExample.Criteria paramCriteria = paramExample.or();
paramCriteria.andItemIdEqualTo(itemId);
List<PdItemParamItem> items = pdItemParamItemMapper.selectByExampleWithBLOBs(paramExample);
List<Params> paramsList = new ArrayList<>();
if (items != null && items.size() >= 1) {
PdItemParamItem item = items.get(0);
String paramData = item.getParamData();
List<PdItemParamData> list = JsonUtils.jsonToList(paramData, PdItemParamData.class);
paramsList = list.get(0).getParams();
}
ItemVO itemVO = new ItemVO();
itemVO.setPdCartItem(pdCartItem);
itemVO.setPdItem(pdItem);
itemVO.setParamsList(paramsList);
itemVOs.add(itemVO);
}
return itemVOs;
}
public PdOrder selectById(String orderId) throws Exception {
PdOrder pdOrder = pdOrderMapper.selectByPrimaryKey(orderId);
return pdOrder;
}
public List<OrderVO> selectByUserIdAndStatus
(Long userId, int status) throws Exception {
PdOrderExample orderExample=new PdOrderExample();
PdOrderExample.Criteria criteria=orderExample.or();
criteria.andUserIdEqualTo(userId);
criteria.andStatusNotEqualTo(9);
if (status!=0)
{
criteria.andStatusEqualTo(status);
}
orderExample.setOrderByClause("create_time desc");
List<PdOrder> orders=pdOrderMapper
.selectByExample(orderExample);
List<OrderVO> orderVOs=new ArrayList<>();
for (PdOrder pdOrder:orders)
{
PdOrderItemExample itemExample=new PdOrderItemExample();
PdOrderItemExample.Criteria itemCriteria=itemExample.or();
itemCriteria.andOrderIdEqualTo(pdOrder.getOrderId());
List<PdOrderItem> orderItems=
pdOrderItemMapper
.selectByExample(itemExample);
for (PdOrderItem pdOrderItem:orderItems)
{
PdItemParamItemExample example=
new PdItemParamItemExample();
PdItemParamItemExample.Criteria paramCriteria=
example.or();
long itemId=Long.parseLong(pdOrderItem
.getItemId());
paramCriteria.andItemIdEqualTo(itemId);
List<PdItemParamItem> paramItemList=pdItemParamItemMapper
.selectByExampleWithBLOBs(example);
List<Params> paramsList=new ArrayList<>();
if (paramItemList.size()>=1)
{
PdItemParamItem pdItemParamItem=
paramItemList.get(0);
String paramData=pdItemParamItem
.getParamData();
List<PdItemParamData> paramDataList=JsonUtils
.jsonToList(paramData,
PdItemParamData.class);
paramsList=paramDataList.get(0).getParams();
}
pdOrderItem.setParamsList(paramsList);
}
OrderVO orderVO=new OrderVO();
orderVO.setPdOrder(pdOrder);
orderVO.setPdOrderItems(orderItems);
orderVOs.add(orderVO);
}
return orderVOs;
}
public PdOrder findOrderByOrderid(String orderId) throws Exception {
PdOrder pdOrder=pdOrderMapper
.selectByPrimaryKey(orderId);
return pdOrder;
}
@Override
public int updateOrderStatus(String orderId, int status) throws Exception {
PdOrder pdOrder=new PdOrder();
pdOrder.setStatus(status);
PdOrderExample example=new PdOrderExample();
PdOrderExample.Criteria criteria=example.or();
criteria.andOrderIdEqualTo(orderId);
int row=pdOrderMapper
.updateByExampleSelective
(pdOrder, example);
return row;
}
}
- 订单的流量削峰解释:购物系统产生的定展,不直接存储到数据库,而是发送到rabbitmq
后台消费者模块接收订单,再向数据库存储,短时间瞬间产生大量订单并发送存储,变成顺序存储 使用模式为简单模式,可以该称工作模式
|