Redis se da cuenta de la función de pico

En la vida real, la función de aumento es más común, como la toma de boletos 12306, las actividades de aumento del sistema de comercio electrónico, etc. El llamado pico, desde la perspectiva del negocio de las aplicaciones, significa que varios usuarios "compiten" por un determinado recurso en un corto período de tiempo. El recurso aquí es una mercancía en la mayoría de los escenarios de pico; desde un punto de vista técnico, es una combinación de múltiples subprocesos Recursos para operar. Por lo tanto, para realizar la función de pico, es necesario controlar la competencia del subproceso por los recursos, no solo para garantizar una alta eficiencia y concurrencia, sino también para garantizar la corrección de la operación y satisfacer las necesidades comerciales reales.

Las ideas de optimización para spike son:

  • Escribe en la memoria.
  • Realice el procesamiento asincrónico de subprocesos múltiples.
  • Realice el procesamiento distribuido.

[Ejemplo] Un ejemplo de uso de subprocesos múltiples para lograr que 1000 personas maten a 100 teléfonos móviles en segundos.

(1) En el archivo de información de configuración pom.xml, agregue las dependencias del lanzador Redis y el cliente Jedis:

<!-- Redis启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.4.0</version>
</dependency>

<!-- Jedis客户端依赖 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.3.0</version>
</dependency>

(2) Implementación de SecondKill (SecondKill.java): cree múltiples subprocesos y use la función de transacción de Redis para realizar la segunda función de eliminación.

package com.pjb.seckill;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;

/**
 * 秒杀抢购
 * @author pan_junbiao
 **/
public class SecondKill implements Runnable
{
    String key = "iphone";
    Jedis jedis = new Jedis("127.0.0.1",6379);
    String userInfo;

    public SecondKill(String userInfo)
    {
        this.userInfo = userInfo;
    }

    @Override
    public void run()
    {
        try
        {
            jedis.watch(key); //watchkeys

            String val = jedis.get(key);
            int valint = Integer.valueOf(val);

            if(valint<=100 && valint>=1)
            {
                //1、使用MULTI命令开启事务
                Transaction tx = jedis.multi();

                //2、事务命令入队
                tx.incrBy(key,-1);

                //3、使用EXEC命令执行事务
                //提交事务。如果此时watchkeys被改动了,则返回null
                List<Object> list = tx.exec();

                if(list==null || list.size()==0)
                {
                    String failuserinfo = "fail_" + userInfo;
                    String failinfo = "用户:" + failuserinfo + "商品争抢失败,抢购失败";
                    System.out.println(failinfo);
                    //抢购失败业务逻辑
                    jedis.setnx(failuserinfo,failinfo);
                }
                else
                {
                    for(Object succ : list)
                    {
                        String succuserinfo = "succ_" + succ.toString() + "_" + userInfo;
                        String succinfo = "用户:" + succuserinfo + " 抢购成功,当前抢购成功人数:" + (1 -(valint -100));
                        System.out.println(succinfo);
                        //抢购成功业务逻辑
                        jedis.setnx(succuserinfo,succinfo);
                    }
                }
            }
            else
            {
                String failuserinfo = "kcfail_" + userInfo;
                String failinfo1 = "用户:" + failuserinfo + " 商品被抢购完毕,抢购失败";
                System.out.println(failinfo1);
                jedis.setnx(failuserinfo,failinfo1);
                return;
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            jedis.close();
        }
    }
}

(3) El programa principal (SecondKillTest.java): el programa de entrada de la función spike, que se utiliza para crear un grupo de subprocesos, al mismo tiempo, generar una ID de usuario, llamar al código de la función spike y completar la tarea spike.

package com.pjb.seckill;

import com.pjb.util.RedisHelper;
import redis.clients.jedis.Jedis;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Redis秒杀功能的实现,1000人抢购100部手机
 * @author pan_junbiao
 **/
public class SecondKillTest
{
    public static void main(String[] args)
    {
        final String key = "iphone";
        //20个线程池并发数
        ExecutorService executor = Executors.newFixedThreadPool(20);

        final Jedis jedis = new Jedis("127.0.0.1",6379);
        jedis.del(key); //先删除
        jedis.set(key,"100"); //设置起始的抢购数
        jedis.close();

        for(int i=0; i<1000; i++)
        {
            String userInfo = "pan_junbiao的博客" + i;
            executor.execute(new SecondKill(userInfo));
        }
        executor.shutdown();
    }
}

Resultados del:

 

Supongo que te gusta

Origin blog.csdn.net/pan_junbiao/article/details/111478937
Recomendado
Clasificación