irpas技术客

Spring Cloud--Sleuth+Zipkin 链路跟踪/订单的流量削峰_利威尔兵短

未知 4760

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服务器 在jar包地址cmd 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); } //新建SpringQueue实例 用来封装队列的参数 //rabbitmq的自动配置类会自动发现这个queue实例 根据参数创建队列 @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; // @Autowired // private AmqpTemplate amqpTemplate; public String saveOrder(PdOrder pdOrder) throws Exception { // String orderId = generateId();//生成订单id // pdOrder.setOrderId(orderId);//订单id放入订单对象 // //转换并发送 先把数据转成byte数组在发送 // amqpTemplate.convertAndSend("orderQueue",pdOrder); 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(); //String id="2"; 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 { //where user_id=14 and status!=9 order by create_time desc PdOrderExample orderExample=new PdOrderExample(); PdOrderExample.Criteria criteria=orderExample.or(); criteria.andUserIdEqualTo(userId); criteria.andStatusNotEqualTo(9);//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) { //from pd_order_item where order_id=30; PdOrderItemExample itemExample=new PdOrderItemExample(); PdOrderItemExample.Criteria itemCriteria=itemExample.or(); itemCriteria.andOrderIdEqualTo(pdOrder.getOrderId()); List<PdOrderItem> orderItems= pdOrderItemMapper .selectByExample(itemExample); for (PdOrderItem pdOrderItem:orderItems) { //3.3.1 example,criteria 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) { //3.3.3 鍙杙aram_data 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 { //update pd_order set status=8 where orderId=100 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 后台消费者模块接收订单,再向数据库存储,短时间瞬间产生大量订单并发送存储,变成顺序存储 使用模式为简单模式,可以该称工作模式


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Spring #链路跟踪订单的流量削峰 #Sleuth产生链路跟踪日志A #ampgt #b