package addata import ( "math/rand" "miads/adslib/redis_data" "miads/adslib/utils" ) func CombineOrderBy(adData *AdData, dsp *utils.DspParam) { ads_item, extra_item = yield get_ads_infos(dsp, order_type = 1) if extra_item == None: raise gen.Return(infos) last_target_addition = infos.get('target_addition', []) extra_item_addition = extra_item.get('target_addition', []) if len(extra_item_addition) == 0: raise gen.Return(infos) if len(extra_item_addition) == 1: last_target_addition[0]['urls'].extend(extra_item_addition[0]['urls']) raise gen.Return(infos) else: last_target_addition[0]['urls'].extend(extra_item_addition[0]['urls']) last_target_addition[1]['urls'].extend(extra_item_addition[1]['urls']) infos['target'] = extra_item['target'] infos['js_order_id'] = extra_item['js_order_id'] last_target_addition[1]['type'] = 'CLICK' raise gen.Return(infos) } // 获取一个广告 func GetOneAds(dsp *utils.DspParam, orderType int, fixFlag int) (*redis_data.AdOrderInfo, error){ // 取出广告 orders, err := redis_data.GetOrderInfos(dsp, fixFlag) if err != nil { return nil, err } if len(orders) == 0 { return nil, nil } gotOrders := make([]redis_data.AdOrderInfo, 0, 1000) allKpi := int64(0) for _, order := range orders { if order.OrderType == int64(orderType) { gotOrders = append(gotOrders, order) allKpi += order.ShowKpi } } orderRange := make([]int, 0, 1000) curRateIdx := 0 // orderRange中记录的是当前同索引位置的gotOrders里的order的比例上限, 比如如果有两个order [ShowKpi:40, ShowKpi: 60] // 那么orderRange就是 [rate:400, rate: 1000], 所以要按比例取order, 只需要获得在比例上限里随机取一个数, 然后判断落在那个orderRange里, // 对应去gotOrders取同索引里的order即可, 因为算法里有对小于1的比例做补偿, 所以rate上限可能超出1000, rate乘1000而不是100主要是为了 // 如果showKpi差异过大, 对大量小于1的订单做补偿, 会影响整体流量分布, 这里放到1000倍, 降低补偿1的影响, 算法复杂度是O(n), 只有三个非嵌套循环 for _, order := range gotOrders { rate := int(float32(order.ShowKpi) / float32(allKpi) * 1000) // 防止比例过小, 取int后变为0 if rate < 1 { rate = 1 } curRateIdx = curRateIdx + rate orderRange = append(orderRange, curRateIdx) } randNum := rand.Intn(curRateIdx) for i, rateRange := range orderRange { if randNum <= rateRange { return &gotOrders[i], nil } } return nil, nil } func GetAdsInfos(dsp *utils.DspParam, advertiser string, orderType int, fixFlag int, xiaomiHasFlag int) { ua = dsp.ua_client req_source = dsp.req_source ads_item = getOneAds(dsp, order_type, fix_flag) if ads_item is None: raise gen.Return((None, None)) r = random.randint(0, 100) if xiaomi_has_flag == 1: if ads_item['title'].find("_ios") > 0: raise gen.Return((None, None)) else: r = random.randint(50, 100) a = datetime.now() #获取剩余时间内的值 all_count = get_sub_time_value(ads_item, a) all_count = all_count * 1.0 #已经投放的key show_key = "order_kpi_%s_%d%d%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day) click_key = "order_kpi_%s_%d%d%d_click_kpi" % (ads_item['order_id'], a.year, a.month, a.day) over_kpi = redis_tools.get_key_int_value(show_key) show_kpi = ads_item['show_kpi'] click_kpi = ads_item['click_kpi'] if all_count < 1: raise gen.Return((None, None)) plan_key = "plan_all_kpi_%s_%d%d%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day) redis_common.redis_ads().set(plan_key, all_count, 60*24*60) w_value, rate = get_now_min_value(ads_item, all_count, show_kpi, a) if w_value < 1: w_value = 1 plan_key = "plan_kpi_%s_%d%d%d_%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day, a.hour*60 + a.minute) redis_common.redis_ads().set(plan_key, w_value, 60*24*60) over_key = "order_kpi_%s_%d%d%d_%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day, a.hour*60 + a.minute) o_value = int(redis_tools.get_key_int_value(over_key)) js_order_id = int(ads_item['js_order_id']) if o_value < w_value: order_name = ads_item['title'] data = { "js_order_id":js_order_id, "target":"", "video_url":"", "duration":5, "target_addition":[], "image_url":"", "result":0, "msg":0, "user_agent":ua, "order_name":order_name } #放量 redis_tools.incr_key_value(over_key) redis_tools.incr_key_value(show_key) show_url = ads_item['show_url'] click_url = ads_item['click_url'] target = ads_item['target_url'] if order_name.find("_ios") > 0: ios_imei, ios_ua = get_ios_ua_imei(dsp) if ios_ua: data['user_agent'] = ios_ua if ads_item.get('imei_replace_flag', 0) == 1 and ios_imei: show_url = show_url.replace('__IDFA__', ios_imei) click_url = click_url.replace('__IDFA__', ios_imei) target = target.replace('__IDFA__', ios_imei) if order_name.find("__OS__") > 0: show_url = show_url.replace('__OS__', '1') click_url = click_url.replace('__OS__', '1') target = target.replace('__OS__', '1') elif order_name.find("_android") > 0 : ### 判断是否需要替换imei if ads_item.get('imei_replace_flag', 0) == 1: show_url = show_url.replace('__IMEI__', dsp.real_md5_imei) click_url = click_url.replace('__IMEI__', dsp.real_md5_imei) target = target.replace('__IMEI__', dsp.real_md5_imei) if order_name.find("__OS__") > 0: show_url = show_url.replace('__OS__', '0') click_url = click_url.replace('__OS__', '0') target = target.replace('__OS__', '0') else: if r < 40: ios_imei, ios_ua = get_ios_ua_imei(dsp) if ios_ua: data['user_agent'] = ios_ua if ads_item.get('imei_replace_flag', 0) == 1 and ios_imei: show_url = show_url.replace('__IDFA__', ios_imei) click_url = click_url.replace('__IDFA__', ios_imei) target = target.replace('__IDFA__', ios_imei) if order_name.find("__OS__") > 0: show_url = show_url.replace('__OS__', '1') click_url = click_url.replace('__OS__', '1') target = target.replace('__OS__', '1') else: if ads_item.get('imei_replace_flag', 0) == 1: show_url = show_url.replace('__IMEI__', dsp.real_md5_imei) click_url = click_url.replace('__IMEI__', dsp.real_md5_imei) target = target.replace('__IMEI__', dsp.real_md5_imei) if order_name.find("__OS__") > 0: show_url = show_url.replace('__OS__', '0') click_url = click_url.replace('__OS__', '0') target = target.replace('__OS__', '0') if order_name.find("__IP__") > 0: show_url = show_url.replace('__IP__', dsp.ip) click_url = click_url.replace('__IP__', dsp.ip) target = target.replace('__IP__', dsp.ip) if order_type == 0: addi = get_monitor_url('VIEW', 5, order_name, req_source, show_url) else: addi = get_monitor_url('VIEW', 5, order_name, 'follow', show_url) #addi['urls'].append(show_url) data['target_addition'].append(addi) r = random.randint(0, 1000) c_rate = click_kpi * 1.0 / (ads_item['show_kpi']) * 1000 if r < c_rate: #下发点击 addi = get_monitor_url('CLICK', 1, order_name, req_source, click_url) #addi['urls'].append(click_url) data['target_addition'].append(addi) md5_skip = hashlib.md5(target).hexdigest() redis_tools.incr_key_value(click_key) real_target = ads_config.Host + "?action=LOADING&req_source={0}&advertiser={2}&skip={1}&skip_other={3}".format( req_source, '', order_name, md5_skip) ### 塞入缓存中 redis_tools.set_skip_info(md5_skip, target) data['target'] = real_target raise gen.Return((None, data)) #获取当前已经放出去的次数 raise gen.Return((None, None)) }~