关于领号活动总结

关于某彩票活动的总结
具体需求,每个用户进活动页面,领取一个号码,1000中的一个;
活动要求
1,随机性,一定要有随机性;
2,最少中奖概率,如果注数为3200注,则最多中4注
3,效率问题,(不能每个人来都产生一个随机数,这样效率不高);
4,支持断电(仍然从下一个开始),重启服务;(存数据库有点大材小用,因此不能存放在数据库)

解决方案
1,事先产生随机数1000个,并打乱数据(initHaoPool)
2,算法采用,计数,从1开始,领到1000个,又重新从1开始
3,不能存放数据库,
第一想法,那就存放在action里;action在struts2中不是安全的,有多个实例,否定
第二想法,放在service里,由于service是单例,可以保证线程安全;
(因此我以service的领号顺序为主,memcahe中的当备份使用,当主站重启时,memcahe还可以获取)

后来第二个方法也出问题了,3G站的领号不按顺序,为什么呢
原来我们的服务器采用双IP,2套代码服务,通过切换IP达到临时换包的效果;
假设线上服务器为A,由于3G站的HOST指到了B上,因此2套代码中的service都是独立的;

第三想法,放在memcache中,以memcache为主,service的为备份,这样就保证了代码的正确性;

但是后来又出问题了,早上10点13分,领号的数据又重复了,原因是当时同事切换了服务器,2台服务器代码都是不一致的,又导致了错误。

总结一下;在分布式环境下,要保持数据的一致性,放代码实在不可靠,
第一选择 是数据库
第二选择 是cache
最后才是 action,但这个保存不住,实在有问题;

下面是代码






/**
     * 初始化号码池
     *
     * @return
     */
    public  void  initHaoPool() {
    //如果action中的结果集和缓存中的结果集都为空,则初始化;
    if(hl==null&&CacheDataService.getCacheObject("<webactivityList>hl")==null){

    hl = new ArrayList<String>();
    //生成1000个号码
    for (int i = 0; i < 1000; i++)
        {
        String randomNo="";
        if (i < 10) {
        randomNo= "00" + i;
        }
        else if (i < 100 && i >= 10) {
        randomNo= "0" + i;
        }else{
        randomNo=Integer.valueOf(i).toString();
        }
        hl.add(randomNo);
        }
//打乱顺序
Collections.shuffle(hl);

//初始lhkey为0; 
lhkey=0;

CacheDataService.setCacheObject("<webactivityList>hl", hl,  60*60*24);
CacheDataService.setCacheObject("<webactivityInteger>lhkey", lhkey,  60*60*24);


    }

    }
   
    /**
     * 清除号码池和缓存
     *
     * @return
     */
    public   void  clearPoolCache() {
    hl=null;
    lhkey=0;
   
    //清除缓存;
CacheDataService.deleteCacheObject("<webactivityList>hl");
    CacheDataService.deleteCacheObject("<webactivityInteger>lhkey");
   
    }
   
   
   
   
   
    /**
     * 随机领取号码
     *
     * @return
     */
   
    public synchronized String getMyNumber(){
   String myno="";
  
//   如果丢失,从cache中取;
//   if(hl==null){
//   hl= (List)CacheDataService.getCacheObject("<webactivityList>hl");
//   lhkey= (Integer)CacheDataService.getCacheObject("<webactivityInteger>lhkey");
//   }
  
//如果丢失,从memcache中取;
if((List)CacheDataService.getCacheObject("<webactivityList>hl")!=null){
hl= (List)CacheDataService.getCacheObject("<webactivityList>hl");
lhkey= (Integer)CacheDataService.getCacheObject("<webactivityInteger>lhkey");
}
  
  
   if(lhkey<1000){
   myno=(String)hl.get(lhkey);
   lhkey=lhkey+1;
}else{
     //System.out.println("从0开始循环--------------");
     myno=(String)hl.get(0);
     lhkey=1;
     }
       
   //更新缓存信息
    CacheDataService.setCacheObject("<webactivityList>hl", hl,  60*60*24);
    CacheDataService.setCacheObject("<webactivityInteger>lhkey", lhkey,  60*60*24);
   
    return myno;
   }

你可能感兴趣的:(活动)