Para projetos de alta concorrência, a fim de melhorar a capacidade de carga de pressão e velocidade de resposta do sistema, redis pode ser usado para armazenar dados e páginas estáticas Este artigo é para registrar o processo de otimização do projeto.
1. Cache de página
Para páginas gerais , o cache de página geralmente é usado, e as páginas que precisam ser retornadas ao usuário são armazenadas diretamente no redis e, quando alguém visita novamente, são retiradas diretamente do redis e devolvidas ao usuário sem realizar outras operações para economizar recursos do sistema.
/* 做页面缓存
* */
@GetMapping(value = "/product_list",produces = "text/html")
@ResponseBody
public String product_list(Model model, User user,
HttpServletResponse response,
HttpServletRequest request,
@RequestParam(value = "pageNo",defaultValue = "1")int pageNo,
@RequestParam(value = "pageSize",defaultValue = "6")int pageSize){
model.addAttribute("user",user);
PageInfo<ProductVo> page = productService.listProcuctVo(pageNo,pageSize);
model.addAttribute("pageInfo",page);
//取缓存
String html = (String) redisService.get("product_list");
System.out.println(html);
if(!StringUtils.isEmpty(html)){
return html;
}
//手动渲染
IWebContext ctx = new WebContext(request,response,request.getServletContext(),
request.getLocale(),model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("product_list",ctx);
if(!StringUtils.isEmpty(html)){
redisService.set_Time("product_list",html,60);
}
return html;
}
Em segundo lugar, url cache
url cache é um cache de página especial, o motivo é que ele tem informações de parâmetros especiais, correspondendo a páginas diferentes, como uma página de detalhes do produto, você precisa de url cache, porque produtos diferentes têm informações diferentes, use o cache de página não cumprir esta função.
/* 商品详情页
* 做url缓存
* */
@RequestMapping(value = "/product_detail/{productId}",produces = "text/html")
@ResponseBody
public String product_detail(Model model, User user,
@PathVariable("productId") long productId,
HttpServletRequest request,
HttpServletResponse response){
//取缓存
String html = (String) redisService.get("product_detail"+productId);
if(!StringUtils.isEmpty(html)){
return html;
}
model.addAttribute("user",user);
ProductVo productVo = productService.selectProductById(productId);
model.addAttribute("product",productVo);
long startTime = productVo.getStart_date().getTime();
long endTime = productVo.getEnd_date().getTime();
long nowTime = System.currentTimeMillis();
int miaoshaStatus = 0;
int remainSeconds = 0;
if( nowTime < startTime){
//秒杀未开始
miaoshaStatus = 0;
remainSeconds = (int)((startTime-nowTime)/1000);
}else if(nowTime > endTime){
//秒杀结束
miaoshaStatus = 2;
remainSeconds = -1;
}else {
//正在进行
miaoshaStatus = 1;
remainSeconds = 0;
}
model.addAttribute("miaoshaStatus",miaoshaStatus);
model.addAttribute("remainSeconds",remainSeconds);
//手动渲染
IWebContext ctx = new WebContext(request,response,request.getServletContext(),
request.getLocale(),model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("product_detail",ctx);
if(!StringUtils.isEmpty(html)){
redisService.set_Time("product_detail"+productId,html,60);
}
return html;
}
3. Cache de objetos O cache de
objetos é uma unidade de cache relativamente pequena entre todos os caches.O mais comumente usado é o cache de informações do usuário frequentemente usadas, que acelera a leitura do sistema de informações comuns do usuário e acelera a velocidade de resposta do sistema.
Quarto, página estática A página estática
também é uma grande vantagem da separação de front-ends e back-ends, que é usar o navegador para armazenar dados em cache para reduzir a interação com o servidor. Alguns frameworks front-end, como VUE.JS, são frameworks que resolvem esse problema muito bem, mas precisam ser estudados com cuidado. Para simplificar, usamos o ajax de JQuery para implementação.
Camada de controlador de back-end:
@RestController
public class MiaoshaController {
@Autowired
ProductService productService;
@Autowired
OrderService orderService;
@Autowired
MiaoshaService miaoshaService;
private static Logger logger = Logger.getLogger("MiaoshaController.class");
@PostMapping(value = "/do_miaosha")
public ResponseResult domiaosha(Model model, User user,
@RequestParam("productId") long productId){
if(user == null){
return ResponseResult.error(ResponseCode.NO_LOGIN);
}
//判断库存
ProductVo productVo = productService.selectProductById(productId);
if(productVo.getStock_count()<=0){
return ResponseResult.error(ResponseCode.PRODUCT_MIAOSHA_OVER);
}
//判断是否已经秒杀
MiaoshaOrder miaoshaOrder = orderService.getMiaoshaOrderByUserIdAndProductId(user.getId(),productId);
if(miaoshaOrder!=null){
return ResponseResult.error(ResponseCode.MIAOSHA_NO_AGAIN);
}
//秒杀开始 减库存-》下订单 -》写入秒杀订单
Order order = miaoshaService.miaosha(user,productVo);
return ResponseResult.success(order);
}
}
js: Use o ajax de JQuery para processar dados para conseguir a separação de front-ends e back-ends
function domiaosha() {
var productId = $("#productId").val();
$.ajax({
url: "/do_miaosha",
type: "POST",
data:{
productId:productId},
dataType:"json",
success:function (data) {
if(data.data != null){
window.location.href="/product_miaosha_detail.htm?orderId="+data.data.id;
}else {
alert(data.msg);
}
},
error:function () {
alert("客户端请求错误!");
}
});
}
5. Otimização de recursos estáticos
(1) compressão JS / CSS, reduzindo o tráfego
(2) Múltiplas combinações JS / CSS, reduzindo o número de conexões
(3) CDN nas proximidades de acesso