redis.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "strconv"
  6. "time"
  7. "go-common/library/cache/redis"
  8. "go-common/library/log"
  9. farm "github.com/dgryski/go-farm"
  10. )
  11. const (
  12. // aid_ip
  13. _anonymousePlayedKey = "nm:%d"
  14. // aid bvid
  15. _anonymouseBvIDKey = "nb:%d"
  16. // bvid's last played aid
  17. _bvIDLastPlayedKey = "bv:%d"
  18. // Mid last played key
  19. _midHashKey = "mid:%d"
  20. _buvidToDidKey = "%d:bdid"
  21. // 改短成6分钟
  22. _hkeyExpire = 600
  23. )
  24. func (s *Service) midKey(mid int64) (key string) {
  25. key = fmt.Sprintf(_midHashKey, mid%s.c.HashNum)
  26. return
  27. }
  28. func (s *Service) bvKey(bvID string) (key string) {
  29. num := int64(farm.Hash32([]byte(bvID)))
  30. key = fmt.Sprintf(_bvIDLastPlayedKey, num%s.c.HashNum)
  31. return
  32. }
  33. func (s *Service) buvidToDidKey(buvid string, aid int64) (key string) {
  34. num := int64(farm.Hash32([]byte(fmt.Sprintf("%s_%d", buvid, aid))))
  35. key = fmt.Sprintf(_buvidToDidKey, num%s.c.HashNum)
  36. return
  37. }
  38. func (s *Service) anonymouseKey(aid, epID int64, ip string) (key string) {
  39. var str string
  40. if epID == 0 {
  41. str = strconv.Itoa(int(aid)) + ip
  42. } else {
  43. str = strconv.Itoa(int(aid)) + ip + strconv.Itoa(int(epID))
  44. }
  45. num := int64(farm.Hash32([]byte(str)))
  46. key = fmt.Sprintf(_anonymousePlayedKey, num%s.c.HashNum)
  47. return
  48. }
  49. func (s *Service) anonymouseBvIDKey(aid int64, bvid string) (key string) {
  50. str := strconv.Itoa(int(aid)) + bvid
  51. num := int64(farm.Hash32([]byte(str)))
  52. key = fmt.Sprintf(_anonymouseBvIDKey, num%s.c.HashNum)
  53. return
  54. }
  55. // canCount 同一个IP一分钟,同一个bvid五分钟
  56. func (s *Service) canCount(c context.Context, aid, epID int64, ip string, stime int64, bvid string) (can bool) {
  57. var (
  58. err error
  59. lastPlayTime int64
  60. bvLastPlayTime int64
  61. hKey = s.anonymouseKey(aid, epID, ip)
  62. hbvKey = s.anonymouseBvIDKey(aid, bvid)
  63. conn = s.redis.Get(c)
  64. pTime = stime + s.c.CacheConf.NewAnonymousCacheTime
  65. now = time.Now().Unix()
  66. ipCan bool
  67. bvCan bool
  68. )
  69. var field = aid
  70. if epID > 0 {
  71. field = epID
  72. }
  73. defer conn.Close()
  74. if lastPlayTime, err = redis.Int64(conn.Do("HGET", hKey, field)); err != nil {
  75. if err == redis.ErrNil {
  76. if _, err = conn.Do("HSET", hKey, field, pTime); err != nil {
  77. log.Error("conn.Do(HSET, %s, %d, %d) error(%v)", hKey, field, pTime, err)
  78. return
  79. }
  80. ipCan = true
  81. } else {
  82. log.Error("conn.Do(HGET, %s, %d) error(%v)", hKey, field, err)
  83. return
  84. }
  85. }
  86. if bvLastPlayTime, err = redis.Int64(conn.Do("HGET", hbvKey, field)); err != nil {
  87. if err == redis.ErrNil {
  88. if _, err = conn.Do("HSET", hbvKey, field, pTime); err != nil {
  89. log.Error("conn.Do(HSET, %s, %d, %d)", hbvKey, field, pTime)
  90. return
  91. }
  92. bvCan = true
  93. } else {
  94. log.Error("conn.Do(HGET, %s, %d) error(%v)", hbvKey, field, err)
  95. return
  96. }
  97. }
  98. if ipCan && bvCan {
  99. can = true
  100. return
  101. }
  102. if now > lastPlayTime && now > bvLastPlayTime {
  103. if err = conn.Send("HSET", hKey, field, now+s.c.CacheConf.NewAnonymousCacheTime); err != nil {
  104. log.Error("conn.Send(HSET, %s, %s, %d) error(%v)", hKey, field, now+s.c.CacheConf.NewAnonymousCacheTime, err)
  105. return
  106. }
  107. if err = conn.Send("EXPIRE", hKey, _hkeyExpire); err != nil {
  108. log.Error("conn.Do(EXPIRE, %s, %d) error(%v)", hKey, _hkeyExpire, err)
  109. return
  110. }
  111. if err = conn.Send("HSET", hbvKey, field, now+s.c.CacheConf.NewAnonymousBvCacheTime); err != nil {
  112. log.Error("conn.Send(HSET, %s, %d, %d) error(%v)", hbvKey, field, now+s.c.CacheConf.NewAnonymousBvCacheTime, err)
  113. return
  114. }
  115. if err = conn.Send("EXPIRE", hbvKey, _hkeyExpire); err != nil {
  116. log.Error("conn.Do(EXPIRE, %s, %d) error(%v)", hbvKey, _hkeyExpire, err)
  117. return
  118. }
  119. if err = conn.Flush(); err != nil {
  120. log.Error("conn.Flush error(%v)")
  121. return
  122. }
  123. for i := 0; i < 4; i++ {
  124. if _, err = conn.Receive(); err != nil {
  125. log.Error("conn.Receive error(%v)", err)
  126. return
  127. }
  128. }
  129. can = true
  130. }
  131. return
  132. }
  133. func (s *Service) isReplay(c context.Context, mid, aid int64, bvID string, gapTime int64) (is bool) {
  134. var (
  135. hKey string
  136. field string
  137. conn = s.redis.Get(c)
  138. value int64
  139. err error
  140. now = time.Now().Unix()
  141. )
  142. defer conn.Close()
  143. if mid > 0 {
  144. hKey = s.midKey(mid)
  145. field = strconv.Itoa(int(mid))
  146. } else {
  147. hKey = s.bvKey(bvID)
  148. field = bvID
  149. }
  150. // aid << 32 | ptime
  151. if value, err = redis.Int64(conn.Do("HGET", hKey, field)); err != nil {
  152. if err != redis.ErrNil {
  153. log.Error("conn.Do(HGET, %s, %s) error(%s)", hKey, field, err)
  154. return
  155. }
  156. err = nil
  157. }
  158. if value != 0 {
  159. rOid := value >> 32
  160. rNow := value & 0xffffffff
  161. if rOid == aid && now-rNow < gapTime {
  162. is = true
  163. return
  164. }
  165. }
  166. value = aid<<32 | now
  167. if err = conn.Send("HSET", hKey, field, value); err != nil {
  168. log.Error("conn.Do(HSET, %s, %s, %s) error(%v)", hKey, field, value, err)
  169. return
  170. }
  171. if err = conn.Send("EXPIRE", hKey, _hkeyExpire); err != nil {
  172. log.Error("conn.Do(EXPIRE, %s, %d)", hKey, _hkeyExpire)
  173. return
  174. }
  175. if err = conn.Flush(); err != nil {
  176. log.Error("conn.Flush error(%v)")
  177. return
  178. }
  179. for i := 0; i < 2; i++ {
  180. if _, err = conn.Receive(); err != nil {
  181. log.Error("conn.Receive error(%v)", err)
  182. return
  183. }
  184. }
  185. return
  186. }
  187. func (s *Service) getRealDid(c context.Context, buvid string, aid int64) (did string, err error) {
  188. var (
  189. conn = s.redis.Get(c)
  190. key = s.buvidToDidKey(buvid, aid)
  191. )
  192. defer conn.Close()
  193. if did, err = redis.String(conn.Do("HGET", key, buvid)); err != nil {
  194. if err != redis.ErrNil {
  195. log.Error("redis.String(conn.Do(HGET, %s, %s)) error(%v)", key, buvid, err)
  196. return
  197. }
  198. err = nil
  199. }
  200. return
  201. }
  202. func (s *Service) setRealDid(c context.Context, buvid string, aid int64, did string) (err error) {
  203. var (
  204. conn = s.redis.Get(c)
  205. key = s.buvidToDidKey(buvid, aid)
  206. )
  207. defer conn.Close()
  208. if err = conn.Send("HSET", key, buvid, did); err != nil {
  209. log.Error("conn.Do(HSET, %s, %s, %s) error(%v)", key, buvid, did, err)
  210. return
  211. }
  212. if err = conn.Send("EXPIRE", key, _hkeyExpire); err != nil {
  213. log.Error("conn.Send(EXPIRE, %s, %d) error(%v)", key, _hkeyExpire, err)
  214. return
  215. }
  216. if err = conn.Flush(); err != nil {
  217. log.Error("conn.Flush error(%v)", err)
  218. return
  219. }
  220. for i := 0; i < 2; i++ {
  221. if _, err = conn.Receive(); err != nil {
  222. log.Error("conn.Receive error(%v)", err)
  223. return
  224. }
  225. }
  226. return
  227. }