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

一个购物交易网站怎么做推广手段和渠道有哪些

一个购物交易网站怎么做,推广手段和渠道有哪些,计算机网站开发毕业论文,去什么网站做推广第一步:添加缓存 以若依岗位代码为例 一:首先从redis中查询岗位信息,如果查询到了则直接返回。 二:如果redis中没有数据,则直接从数据库中查询。查询后放到redis并返回 package com.ruoyi.system.service.impl;imp…

第一步:添加缓存

以若依岗位代码为例

一:首先从redis中查询岗位信息,如果查询到了则直接返回。

二:如果redis中没有数据,则直接从数据库中查询。查询后放到redis并返回

package com.ruoyi.system.service.impl;import java.util.List;import com.alibaba.fastjson2.JSON;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.service.ISysPostService;/*** 岗位信息 服务层处理* * @author ruoyi*/
@Service
@RequiredArgsConstructor
public class SysPostServiceImpl implements ISysPostService
{private final SysPostMapper postMapper;private final SysUserPostMapper userPostMapper;private final StringRedisTemplate redisTemplate;/*** 岗位前缀*/private static final String POST_KEY = "sys:post:";/*** 查询岗位信息集合* * @param post 岗位信息* @return 岗位信息集合*/@Overridepublic List<SysPost> selectPostList(SysPost post){return postMapper.selectPostList(post);}/*** 查询所有岗位* * @return 岗位列表*/@Overridepublic List<SysPost> selectPostAll(){return postMapper.selectPostAll();}/*** 通过岗位ID查询岗位信息* * @param postId 岗位ID* @return 角色对象信息*/@Overridepublic SysPost selectPostById(Long postId){// 一:从redis中查询缓存是否存在String postInfo = redisTemplate.opsForValue().get(POST_KEY + postId);// 二:判定是否存在if (StringUtils.isNotEmpty(postInfo)){// 转换为beanSysPost sysPost = JSON.parseObject(postInfo, SysPost.class);return sysPost;}// 三:如果存在直接返回SysPost post = postMapper.selectPostById(postId);// 四:不存在则查询数据库判定数据中是否存在if (StringUtils.isNull(post)){return null;}redisTemplate.opsForValue().set(POST_KEY + postId, JSON.toJSONString(post));// 五:如果存在则放到redis中,并返回return post;}/*** 根据用户ID获取岗位选择框列表* * @param userId 用户ID* @return 选中岗位ID列表*/@Overridepublic List<Long> selectPostListByUserId(Long userId){return postMapper.selectPostListByUserId(userId);}/*** 校验岗位名称是否唯一* * @param post 岗位信息* @return 结果*/@Overridepublic boolean checkPostNameUnique(SysPost post){Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();SysPost info = postMapper.checkPostNameUnique(post.getPostName());if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()){return UserConstants.NOT_UNIQUE;}return UserConstants.UNIQUE;}/*** 校验岗位编码是否唯一* * @param post 岗位信息* @return 结果*/@Overridepublic boolean checkPostCodeUnique(SysPost post){Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();SysPost info = postMapper.checkPostCodeUnique(post.getPostCode());if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()){return UserConstants.NOT_UNIQUE;}return UserConstants.UNIQUE;}/*** 通过岗位ID查询岗位使用数量* * @param postId 岗位ID* @return 结果*/@Overridepublic int countUserPostById(Long postId){return userPostMapper.countUserPostById(postId);}/*** 删除岗位信息* * @param postId 岗位ID* @return 结果*/@Overridepublic int deletePostById(Long postId){return postMapper.deletePostById(postId);}/*** 批量删除岗位信息* * @param postIds 需要删除的岗位ID* @return 结果*/@Overridepublic int deletePostByIds(Long[] postIds){for (Long postId : postIds){SysPost post = selectPostById(postId);if (countUserPostById(postId) > 0){throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName()));}}return postMapper.deletePostByIds(postIds);}/*** 新增保存岗位信息* * @param post 岗位信息* @return 结果*/@Overridepublic int insertPost(SysPost post){return postMapper.insertPost(post);}/*** 修改保存岗位信息* * @param post 岗位信息* @return 结果*/@Overridepublic int updatePost(SysPost post){return postMapper.updatePost(post);}
}

这是一个简单的添加缓存功能。

第二步:缓存更新策略

主动更新有几种方式?

第一种是常用的

第二种市面上三方的工具少

第三种感觉有点不靠谱。一致性和可靠性都会存在问题,如果redis挂了就出现了一些问题

第三种有疑问其中2种都可以。但是需要具体的分析一下?

先删除缓存,在操作数据库

分析下正常情况:

线程1代表业务人员:业务人员先删除缓存,然后更新数据库

线程2代表客户:客户人员查询缓存未命中,然后写入缓存

非正常情况:

线程1代表业务人员:业务人员先删除缓存。但是由于更新数据库业务复杂,没有更新完。因为没                                    有加锁的原因

线程2代表客户:在数据库未更新完的情况下,客户点击查询结果缓存中没有直接查询到数据库,

                           但是数据库还是10,造成了缓存也是10。最终出现了数据库是20,缓存10。

先操作数据库,在删除缓存

正常情况下:

线程2代表业务人员:业务人员更新数据库,然后删除缓存

线程1代表客户:客户查询缓存未命中,在查询数据库写入缓存

非正常业务:这种情况是在

这种情况是线程1查询缓存,缓存正好过期,然后他在查询玩数据库后,准备写入缓存

恰好有一个在更新数据库为20,然后删除缓存,但是那个写入缓存还没开始执行,等他删除缓存后开始执行了。这就造成了脏数据。但是这种情况是在毫秒级别发生的,太需要巧合了。

第三步:案例实现

之前做了岗位的缓存机制:现在实现一个缓存超时剔除和主动更新的策略

1:根据id查询岗位,如果未命中查询数据库,将数据库数据放到缓存里面,并添加超时时间

2:根据id修改岗位是,先修改数据库,在删除缓存

实现超时剔除

 /*** 通过岗位ID查询岗位信息** @param postId 岗位ID* @return 角色对象信息*/@Overridepublic SysPost selectPostById(Long postId) {// 一:从redis中查询缓存是否存在String postInfo = redisTemplate.opsForValue().get(POST_KEY + postId);// 二:判定是否存在if (StringUtils.isNotEmpty(postInfo)) {// 转换为beanSysPost sysPost = JSON.parseObject(postInfo, SysPost.class);return sysPost;}// 三:如果存在直接返回SysPost post = postMapper.selectPostById(postId);// 四:不存在则查询数据库判定数据中是否存在if (StringUtils.isNull(post)) {return null;}redisTemplate.opsForValue().set(POST_KEY + postId, JSON.toJSONString(post),RedisConstants.THIRTY_MINUTES,TimeUnit.MINUTES);// 五:如果存在则放到redis中,并返回return post;}

直接设置过期时间,并且设置为分钟就可以实现缓存自动剔除了。

实现主动更新策略

   /*** 修改保存岗位信息** @param post 岗位信息* @return 结果*/@Overridepublic int updatePost(SysPost post) {if (StringUtils.isNull(post.getPostId())) {throw new ServiceException("id不存在");}// 修改岗位信息int count = postMapper.updatePost(post);if (count > 0) {redisTemplate.delete(POST_KEY + post.getPostId());return count;}return 0;}

这种直接可以实现主动更新策略

结果点击岗位详情,可以看到已经

更新信息的时候则删除缓存了。

第四步:缓存穿透

缓存穿透:当redis和数据库都没有请求的数据时,这样缓存会不生效,所有请求都会打到redis中

解决方案:。2:布隆过滤。

1:缓存空对象

      优点:实现简单。可以设置一个时间短的TTL。能解决占内存

      缺点:可能站内存。可能会一直给你一个不存在id

2:布隆过滤

      优点:内存占用少,少量key。

      缺点:不一定准确。

给岗位查询解决缓存穿透的方案:流程图

代码修改:

 /*** 通过岗位ID查询岗位信息** @param postId 岗位ID* @return 角色对象信息*/@Overridepublic SysPost selectPostById(Long postId) {// 一:从redis中查询缓存是否存在String postInfo = redisTemplate.opsForValue().get(POST_KEY + postId);// 二:判定是否存在if (StringUtils.isNotEmpty(postInfo)) {// 转换为beanSysPost sysPost = JSON.parseObject(postInfo, SysPost.class);return sysPost;}// 这边还有点绕,不是空的,直接返回数据,但是如果不是null说明里面是空字符串就直接返回错误信息if (StringUtils.isNotNull(postInfo)) {throw new ServiceException("数据不存在");}// 三:如果存在直接返回SysPost post = postMapper.selectPostById(postId);// 四:不存在则查询数据库判定数据中是否存在if (StringUtils.isNull(post)) {// 然后给控制写入redisredisTemplate.opsForValue().set(POST_KEY + postId, StringUtils.EMPTY,RedisConstants.THIRTY_MINUTES,TimeUnit.MINUTES);return null;}redisTemplate.opsForValue().set(POST_KEY + postId, JSON.toJSONString(post),RedisConstants.THIRTY_MINUTES,TimeUnit.MINUTES);// 五:如果存在则放到redis中,并返回return post;}

第五步:缓存雪崩

第六步:缓存击穿

2种方案:互斥锁方案和逻辑删除方案

方案对比:

第七种:利用互斥锁来解决岗位缓存击穿的问题

 /*** 通过岗位ID查询岗位信息** @param postId 岗位ID* @return 角色对象信息*/@Overridepublic SysPost selectPostById(Long postId) {// 缓存穿透解决方案// queryWithPost(postId);// 缓存击穿return queryWithMutex(postId);}
  /*** 缓存击穿问题* @param postId id* @return 返回值*/@SneakyThrowsprivate SysPost queryWithMutex(Long postId) {// 一:从redis中查询缓存是否存在String postInfo = redisTemplate.opsForValue().get(POST_KEY + postId);// 二:判定是否存在if (StringUtils.isNotEmpty(postInfo)) {// 转换为beanSysPost sysPost = JSON.parseObject(postInfo, SysPost.class);return sysPost;}// 这边还有点绕,不是空的,直接返回数据,但是如果不是null说明里面是空字符串就直接返回错误信息if (StringUtils.isNotNull(postInfo)) {throw new ServiceException("数据不存在");}// 尝试获取互斥锁String lockKey = "lock:post:" + postId;// 如果失败了,说明可能其他线程在获取取,所以需要休眠一下Boolean lock = getLock(lockKey);if (!lock) {Thread.sleep(NUMBER_1000);// 递归 在此查询,如果有数据,直接返回return queryWithMutex(postId);}// 三:如果存在直接返回SysPost post = postMapper.selectPostById(postId);// 四:不存在则查询数据库判定数据中是否存在if (StringUtils.isNull(post)) {// 然后给控制写入redisredisTemplate.opsForValue().set(POST_KEY + postId, StringUtils.EMPTY,THIRTY_MINUTES,TimeUnit.MINUTES);return null;}redisTemplate.opsForValue().set(POST_KEY + postId, JSON.toJSONString(post),THIRTY_MINUTES,TimeUnit.MINUTES);// 五:如果存在则放到redis中,并返回// 释放锁deleteLock(lockKey);return post;}
/*** 获取锁** @param key 值* @return 成功失败*/private Boolean getLock(String key) {return redisTemplate.opsForValue().setIfAbsent(key, String.valueOf(UUID.randomUUID()), THIRTY_MINUTES, TimeUnit.SECONDS);}/*** 是否锁** @param key 值* @return 成功失败*/private Boolean deleteLock(String key) {return redisTemplate.delete(key);}

第八种:利用逻辑处理处理岗位缓存击穿问题

这种方案感觉不太好,保证不了数据一致性。

http://www.dtcms.com/wzjs/295600.html

相关文章:

  • 金华农村网站建设河北seo公司
  • 池州网站公司线上营销的优势
  • 网站描述多个词怎么分隔淘宝客seo推广教程
  • 农产品价格实时价格网seo是谁
  • 小企业网站建设怎么做好免费友情链接网页
  • 做网站怎么收费的怎么创造自己的网站
  • 安徽动漫公司 网站制作 安徽网新app广告联盟平台
  • 开淘宝的店铺网站怎么做百度购物平台客服电话
  • 做网站样式模板seo关键词排名价格
  • 教育培训类网站建设模板视频互联网推广选择隐迅推
  • 创业开网站建设公司营销策划书范文1000字
  • 外发加工网是真的吗杭州seo网站
  • 用dw做淘宝网站武汉seo优化公司
  • 用阿里云和大淘客做网站凡科建站的免费使用
  • diy网站建设关联词有哪些五年级
  • 适合个人做的网站有哪些东西吗公司推广方法有哪些
  • 做网站宽度和长度布局长春网站优化咨询
  • 大学学风建设专题网站网站建设策划书
  • 环境建设公司属于什么企业外贸seo建站
  • 临沭县住房和城乡建设局网站什么软件可以排名次
  • 南昌网站建设公司cps广告是什么意思
  • 江苏网站建设定制奶茶店营销软文
  • 360摄像头海澳門地区限制解除宿州百度seo排名软件
  • 网站建设基本常识seo薪酬水平
  • 玉田网站制作公司网络推广方案
  • 做钢材的网站有哪些安徽360优化
  • php网站开发代做百度软件优化排名
  • 长沙市建设网站深圳竞价托管公司
  • 企业软件解决方案网站seo文章
  • 什么网站是做电机控制的114外链