哪个网站上做ppt比较好看的图片江都城乡建设局网站

当前位置: 首页 > news >正文

哪个网站上做ppt比较好看的图片,江都城乡建设局网站,启东市建设局网站,我的世界怎么做赞助网站web项目中请求线程到service层的时候远程调用服务之前是串行化执行每个任务都要get阻塞等待任务完成#xff0c;举例当用户在购物车页面点击去结算就会请求后台toTrade请求获取订单确认的详情数据并渲染到订单详情页#xff0c;现在在toTrade请求中使用异步任务编排Completab…web项目中请求线程到service层的时候远程调用服务之前是串行化执行每个任务都要get阻塞等待任务完成举例当用户在购物车页面点击去结算就会请求后台toTrade请求获取订单确认的详情数据并渲染到订单详情页现在在toTrade请求中使用异步任务编排CompletableFuture.runAsync(来使用线程池并提交任务这导致远程请求时需要利用当前的请求线程中放在ThreadLocal的共享数据无法在CompletableFuture.runAsync提交的异步任务中获取到主请求线程的共享数据如请求会员服务获取用户的地址请求购物车服务获取选中的购物车项在远程feign调用的时候需要实现拦截器为新的request设置上cookie在拦截器中要获取到旧的request这时不在同一个线程获取到的request就是null理论的当前线程中 RequestContextHolder.getRequestAttributes();会保存controller中接收的request原理是ThreadLocal共享变量现在解决方法在异步线程编排前获取到 RequestAttributes requestAttributes RequestContextHolder.getRequestAttributes();在异步编排的任务中 为当前线程的RequestContextHolder重新设置上原来的请求数据让每一个线程都来共享之前的请求数据RequestContextHolder.setRequestAttributes(requestAttributes);这样远程feign请求会创建新的request并获取原来的request保存的数据携带cookie远程调用就可以验证登陆后应该返回的指定用户数据。 幂等性问题解决 使用token使用方式和验证码相同有服务器存储一份前端发送一份订单提交时携带token验证通过后删除token并创建订单当多次提交token无法验证通过。token设及的问题有先删除token还是后删除token问题后删除token可能重复提交后创建相同的订单破坏幂等如果是先删除token在微服务中token不可能单独存储在一个服务中所以它和分布式session一样需要储存在redis中当多个服务订单携带token时需要竞争获取服务端的token服务端需要从redis中拿当两个服务同时从redis中拿token成功同时删除令牌同时创建订单幂等性失效。 解决方式获取getToken判断相等getTokentoken 删除delToken这三个要是原子性的保证只有一个服务执行完整操作。可以在redis的lua脚本完成操作 if redis.call(get,KYES[1]ARGV[1] return redis.call(del.KEYS[2])else return 0 end) 2 解决方式使用各种锁机制 1数据库悲观锁 select * from xx where id1 for update(行锁) 悲观锁使用一般随事务一起使用数据锁定时间可能很长需要更具实际情况选用id字段一定是主键或者唯一索引不然可能造成锁表的结果处理起来会麻烦。 数据库乐观锁 数据库更新的时候加上version字段比如订单下单成功减库存操作可能feign触发重试机制 3 业务层使用分布式锁 各种唯一约束 1数据可唯一约束 主键唯一索引举例下订单的订单号是唯一的索引重复下订单只有一次是有效的 2 使用redis set防重拿百度网盘的妙功能如果这个文件之前有人上传过就计算它的MD5值放在set中每一个独立存在的文件只有一个MD5值拿订单为例如果这个订单得到处理了就生成一个该订单好号的MD5值如果重复提交就检测set中是否有该订单的MD5值如果有表明订单已经处理成功重复提交就失败。 3 防重表 使用订单号 orderNo 做为去重表的唯一索引把唯一索引插入去重表再进行业务操作且 他们在同一个事务中。这个保证了重复请求时因为去重表有唯一约束导致请求失败避 免了幂等问题。这里要注意的是去重表和业务表应该在同一库中这样就保证了在同一个 事务即使业务操作失败了也会把去重表的数据回滚。这个很好的保证了数据一致性。 之前说的 redis 防重也算。 4、全局请求唯一 id 调用接口时生成一个唯一 idredis 将数据保存到集合中去重存在即处理过。 可以使用 nginx 设置每一个请求的唯一 id proxy_set_header X-Request-Id $request_id; 最终实现 本项目通过token解决幂等性在订单确认页面的请求中返回一个token给前端并在后端统一存储token到redis中由于是分布式系统并不像传统单点服务一样保存在当前服务中而是通过原子性获取redis的token确保每个竞争token的服务在获取比较删除都是原子性的来保证多个服务不相互干扰引发数据混乱。下订单验证token的lua脚本实现如下 Overridepublic SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {confirmVoThreadLocal.set(vo);SubmitOrderResponseVo responseVo new SubmitOrderResponseVo();//去创建、下订单、验令牌、验价格、锁定库存…//获取当前用户登录的信息MemberResponseVo memberResponseVo LoginUserInterceptor.loginUser.get();responseVo.setCode(0);//1、验证令牌是否合法【令牌的对比和删除必须保证原子性】String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end;String orderToken vo.getOrderToken();//通过lure脚本原子验证令牌和删除令牌Long result redisTemplate.execute(new DefaultRedisScriptLong(script, Long.class),Arrays.asList(USER_ORDER_TOKEN_PREFIX memberResponseVo.getId()),orderToken);if (result 0L) {//令牌验证失败responseVo.setCode(1);return responseVo;} else {//令牌验证成功//1、创建订单、订单项等信息OrderCreateTo order createOrder();//2、验证价格BigDecimal payAmount order.getOrder().getPayAmount();BigDecimal payPrice vo.getPayPrice();if (Math.abs(payAmount.subtract(payPrice).doubleValue()) 0.01) {//金额对比//TODO 3、保存订单saveOrder(order);//4、库存锁定,只要有异常回滚订单数据//订单号、所有订单项信息(skuId,skuNum,skuName)WareSkuLockVo lockVo new WareSkuLockVo();lockVo.setOrderSn(order.getOrder().getOrderSn());//获取出要锁定的商品数据信息ListOrderItemVo orderItemVos order.getOrderItems().stream().map((item) - {OrderItemVo orderItemVo new OrderItemVo();orderItemVo.setSkuId(item.getSkuId());orderItemVo.setCount(item.getSkuQuantity());orderItemVo.setTitle(item.getSkuName());return orderItemVo;}).collect(Collectors.toList());lockVo.setLocks(orderItemVos);//TODO 调用远程锁定库存的方法//出现的问题扣减库存成功了但是由于网络原因超时出现异常导致订单事务回滚库存事务不回滚(解决方案seata)//为了保证高并发不推荐使用seata因为是加锁并行化提升不了效率,可以发消息给库存服务R r wmsFeignService.orderLockStock(lockVo);if (r.getCode() 0) {//锁定成功responseVo.setOrder(order.getOrder());// int i 100;//TODO 订单创建成功发送消息给MQrabbitTemplate.convertAndSend(order-event-exchange,order.create.order,order.getOrder());//删除购物车里的数据redisTemplate.delete(CART_PREFIXmemberResponseVo.getId());return responseVo;} else {//锁定失败String msg (String) r.get(msg);throw new NoStockException(msg);// responseVo.setCode(3);// return responseVo;}} else {responseVo.setCode(2);return responseVo;}}} 大致内容 //1、验证令牌是否合法【令牌的对比和删除必须保证原子性】         String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end;         String orderToken vo.getOrderToken(); //通过lure脚本原子验证令牌和删除令牌         Long result redisTemplate.execute(new DefaultRedisScriptLong(script, Long.class),                 Arrays.asList(USER_ORDER_TOKEN_PREFIX memberResponseVo.getId()),                 orderToken); if (result 0L) //令牌验证失败