发表于: 2018-03-18 23:57:42

2 665


今日完成:

1.       redis实现抢红包

红包类:参考微信随机红包

@Component
public class ReadPackage {
   
private double remainMoney = 1000000000;
    private int
remainSize = 1000;

   
public double getRemainMoney() {
       
return this.remainMoney;
   
}

   
public int getRemainSize() {
       
return this.remainSize;
   
}

   
public boolean isEmpty() {
       
return 0 == remainSize;
   
}

   
public double getRandomMoney() {
       
if (1 == this.remainSize) {
           
this.remainSize--;
            return
(double) Math.floor(this.remainMoney * 100) / 100;
       
}

        Random random =
new Random();
        double
min = 0.01;
        double
max = this.remainMoney / this.remainSize * 2;
        double
money = random.nextDouble() * max;
       
money = money <= min ? min : money;
       
money = (double) Math.floor(money * 100) / 100;
        this
.remainSize--;
        this
.remainMoney -= money;
        return
money;
   
}

将生成的红包缓存到redis中,并设置抢红包方法

@Component
public class RedisReadPackage {

   
@Autowired
   
private ReadPackage readPackage;

   
@Autowired
   
private RedisTemplate redisTemplate;

    public static
String UNUSEDLIST = "unusedReadPackage";
    public static
String USEDLIST = "usedReadPackage";
    public static
String CUSTOMERLIST = "customer";

    public void
init(){
       
redisTemplate.delete(UNUSEDLIST);
       
redisTemplate.delete(USEDLIST);
       
redisTemplate.delete(CUSTOMERLIST);
   
}

   
public void setUnusedReadPackageList(){
       
while (!readPackage.isEmpty()){
           
redisTemplate.opsForList().leftPush(UNUSEDLIST, readPackage.getRandomMoney());
       
}
    }

   
public String grabReadPackage(int id){
       
if(0 != redisTemplate.opsForList().size(UNUSEDLIST ) && !redisTemplate.opsForSet().isMember(CUSTOMERLIST, id)){
           
double money = (double)redisTemplate.opsForList().rightPop(UNUSEDLIST);
           
redisTemplate.opsForSet().add(CUSTOMERLIST, id);
           
redisTemplate.opsForList().leftPush(USEDLIST, id + "_" + money);
//            System.out.println(redisTemplate.opsForSet().pop(CUSTOMERLIST));
//            System.out.println(redisTemplate.opsForList().range(USEDLIST, 0 ,-1));
           
return "恭喜" + id + "用户抽到" + money + "元红包!";
       
}
       
return "错亿";
   
}
}

controller中初始化红包,重定向到抢红包页面

@RequestMapping(value = "/grabReadPackageIndex")
public String grabReadPackageIndex(){
   
redisReadPackage.init();
   
redisReadPackage.setUnusedReadPackageList();
    return
"redirect:/itschool/grabReadPackage";
}

@RequestMapping(value = "/grabReadPackage", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
public @ResponseBody String grabReadPackage(){
    JSONObject object =
new JSONObject();
   
Random random = new Random();
   
String msg = redisReadPackage.grabReadPackage(random.nextInt(1000));
   
object.put("meg", msg);
    return
object.toString();
}

结果页面:

                                             

本地压测情况:

2.       xml读取多个配置文件方法

方法一(测试成功):

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property
name="locations">
        <list>
           
<!-- 这里支持多种寻址方式:classpathfile -->
           
<value>classpath:datasource/mysql.properties</value>
            <value>
classpath:cache/redis.properties</value>
           
<!-- 推荐使用file的方式引入,这样可以将配置和代码分离 -->
            <!--<value>file:/opt/demo/config/demo-remote.properties</value>-->
       
</list>
    </property>
</bean>

方法二:(测试成功)

方法一的变换,使用List

<!-- 将多个配置文件位置放到列表中 -->
<bean id="propertyResources" class="java.util.ArrayList">
    <constructor-arg>
        <list>
       
<!-- 这里支持多种寻址方式:classpathfile -->
       
<value>classpath:datasource/mysql.properties</value>
        <value>
classpath:cache/redis.properties</value>
       
<!-- 推荐使用file的方式引入,这样可以将配置和代码分离 -->
        <!--<value>file:/opt/demo/config/demo-remote.properties</value>-->
       
</list>
    </constructor-arg>
</bean>

<!-- 将配置文件读取到容器中,交给Spring管理 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property
name="locations" ref="propertyResources" />
</bean>

方法三:(测试失败)

ignore-resource-not-found="是否忽略找不到的属性文件"   

    ignore-unresolvable="是否忽略解析不到的属性,如果不忽略,找不到将抛出异常"

<!--或者这样 引入配置文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:datasource/mysql.properties, classpath:cache/redis.properties"/>

ps:配置文件依次加载,如果后一个文件中有和前面某一个文件中属性名是相同的,最终取的值是后加载的值

psSpring容器是采用反射扫描的发现机制,通过标签的命名空间实例化实例,当Spring探测到容器中有一个org.springframework.beans.factory.config.PropertyPlaceholderCVonfigurerBean就会停止对剩余PropertyPlaceholderConfigurer的扫描,即只能存在一个实例

报错:

方法四:(测试成功)

分散到不同xml分别加载,每个xml配置文件如下(也可以放置在同一个xml中)

<!-- redis属性配置文件位置放到列表中 -->
<bean id="redisResources" class="java.util.ArrayList">
    <constructor-arg>
        <list>
            <value>
classpath:cache/redis.properties</value>
        </list>
    </constructor-arg>
</bean>

<!-- Spring加载和管理redis属性配置文件 -->
<bean id="redisPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property
name="order" value="2" />
    <property
name="ignoreUnresolvablePlaceholders" value="true" />
    <property
name="locations" ref="redisResources" />
</bean>

注意:其中order属性代表其加载顺序,而ignoreUnresolvablePlaceholders为是否忽略不可解析的 Placeholder,如配置了多个PropertyPlaceholderConfigurer,则需设置为true。这里一定需要按照这种方式设置这两个参数。

ps:另外一种方法使用注解引用配置@Value

方法五:(测试失败)

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
    <property
name="location" value="classpath:datasource/mysql.properties, classpath:cache/redis.properties"/>
</bean>

报错:

明日计划:

1.       redis分布式

2.       redis实现抢红包(锁,同步异步)

3.       整理

遇到的问题:

1.       在做单元测试中,使用@ Autowired会显示空指针异常

2.       抢红包是否要设计一个存放抢到红包的用户与红包金额的类,然后使用这个类存放抢红包结果,在添加到redisList缓存中?

收获:

1.       简单使用redis实现抢红包

2.       多个properties文件引用方法



返回列表 返回列表
评论

    分享到