redis.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. package util
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "log"
  6. "runtime"
  7. "strings"
  8. "time"
  9. redigo "github.com/garyburd/redigo/redis"
  10. )
  11. var RedisPool = make(map[string]*redigo.Pool, 0)
  12. func InitRedisPool(modules, address string, maxPoolSize, maxPoolIdle, idleTimeOut int) error {
  13. var e error
  14. if !IsEmpty(modules) && !IsEmpty(address) {
  15. a := strings.Split(address, ",")
  16. m := strings.Split(modules, ",")
  17. if len(a) == len(m) {
  18. for i, val := range a {
  19. e = InitModuleRedis(val, m[i], maxPoolSize, maxPoolIdle, idleTimeOut)
  20. }
  21. }
  22. }
  23. return e
  24. }
  25. func IsEmpty(str string) bool {
  26. if strings.TrimSpace(str) == "" {
  27. return true
  28. }
  29. return false
  30. }
  31. func InitModuleRedis(addr string, module string, maxSize, maxIdle, timeout int) error {
  32. var e error
  33. RedisPool[module] = &redigo.Pool{
  34. MaxActive: maxSize,
  35. MaxIdle: maxIdle,
  36. IdleTimeout: time.Duration(timeout) * time.Second,
  37. Dial: func() (redigo.Conn, error) {
  38. c, err := redigo.Dial("tcp", addr)
  39. if err != nil {
  40. log.Printf("redis addr:[%s],module:[%s] dial error:[%v]", addr, err)
  41. e = err
  42. return nil, err
  43. }
  44. return c, nil
  45. }}
  46. return e
  47. }
  48. /*func InitRedisBySize(addrs string, maxSize, maxIdle, timeout int) {
  49. RedisPool = map[string]*redigo.Pool{}
  50. addr := strings.Split(addrs, ",")
  51. for _, v := range addr {
  52. saddr := strings.Split(v, "=")
  53. RedisPool[saddr[0]] = &redigo.Pool{MaxActive: maxSize, MaxIdle: maxIdle,
  54. IdleTimeout: time.Duration(timeout) * time.Second, Dial: func() (redigo.Conn, error) {
  55. c, err := redigo.Dial("tcp", saddr[1])
  56. if err != nil {
  57. return nil, err
  58. }
  59. return c, nil
  60. }}
  61. }
  62. }*/
  63. //分流redis
  64. //并存入字符串缓存
  65. func PutKV(key string, obj interface{}) bool {
  66. return Put("other", key, obj, -1)
  67. }
  68. func PutCKV(code, key string, obj interface{}) bool {
  69. return Put(code, key, obj, -1)
  70. }
  71. func Put(code, key string, obj interface{}, timeout int) bool {
  72. b := false
  73. defer catch()
  74. conn := RedisPool[code].Get()
  75. defer conn.Close()
  76. var err error
  77. _obj, _err := json.Marshal(obj)
  78. if _err != nil {
  79. log.Println("redisutil-SET-序列化出错Error", _err)
  80. return b
  81. }
  82. if timeout < 1 {
  83. _, err = conn.Do("SET", key, _obj)
  84. } else {
  85. _, err = conn.Do("SET", key, _obj, "EX", timeout)
  86. }
  87. if nil != err {
  88. log.Println("redisutil-SETError-put", err)
  89. } else {
  90. b = true
  91. }
  92. return b
  93. }
  94. func BulkPut(code string, timeout int, obj ...interface{}) bool {
  95. b := false
  96. defer catch()
  97. conn := RedisPool[code].Get()
  98. defer conn.Close()
  99. var err error
  100. for _, _tmp := range obj {
  101. tmp, ok := _tmp.([]interface{})
  102. if ok && len(tmp) == 2 {
  103. key, kok := tmp[0].(string)
  104. if kok && key != "" {
  105. _obj, _err := json.Marshal(tmp[1])
  106. if _err != nil {
  107. log.Println("redisutil-SET-序列化出错Error", _err)
  108. return b
  109. }
  110. if timeout < 1 {
  111. _, err = conn.Do("SET", key, _obj)
  112. } else {
  113. _, err = conn.Do("SET", key, _obj, "EX", timeout)
  114. }
  115. }
  116. }
  117. }
  118. if nil != err {
  119. b = false
  120. log.Println("redisutil-SETError-put", err)
  121. } else {
  122. b = b && true
  123. }
  124. return b
  125. }
  126. //直接存字节流
  127. func PutBytes(code, key string, data *[]byte, timeout int) (err error) {
  128. defer catch()
  129. conn := RedisPool[code].Get()
  130. defer conn.Close()
  131. if timeout < 1 {
  132. _, err = conn.Do("SET", key, *data)
  133. } else {
  134. _, err = conn.Do("SET", key, *data, "EX", timeout)
  135. }
  136. if nil != err {
  137. log.Println("redisutil-SETError", err)
  138. }
  139. return
  140. }
  141. //设置超时时间,单位秒
  142. func SetExpire(code, key string, expire int) error {
  143. defer catch()
  144. conn := RedisPool[code].Get()
  145. defer conn.Close()
  146. _, err := conn.Do("expire", key, expire)
  147. return err
  148. }
  149. //判断一个key是否存在
  150. func Exists(code, key string) (bool, error) {
  151. defer catch()
  152. conn := RedisPool[code].Get()
  153. defer conn.Close()
  154. repl, err := conn.Do("exists", key)
  155. ret, _ := redigo.Int(repl, err)
  156. return ret == 1, err
  157. }
  158. //获取string
  159. func GetStr(code, key string) string {
  160. res := Get(code, key)
  161. str, _ := res.(string)
  162. return str
  163. }
  164. //获取int
  165. func GetInt(code, key string) int {
  166. res := Get(code, key)
  167. var result int
  168. if str, ok := res.(float64); ok {
  169. result = int(str)
  170. }
  171. return result
  172. }
  173. //取得字符串,支持变参,2个 (key,code),返回后自己断言
  174. func Get(code, key string) (result interface{}) {
  175. GetInterface(code, key, &result)
  176. return
  177. }
  178. func GetInterface(code, key string, result interface{}) {
  179. defer catch()
  180. conn := RedisPool[code].Get()
  181. defer conn.Close()
  182. ret, err := conn.Do("GET", key)
  183. if nil != err {
  184. log.Println("redisutil-GetError", err)
  185. } else {
  186. var ok bool
  187. var res []byte
  188. if res, ok = ret.([]byte); ok {
  189. err = json.Unmarshal(res, result)
  190. if err != nil {
  191. log.Println("Get ERROR:", err.Error())
  192. }
  193. }
  194. }
  195. }
  196. //直接返回字节流
  197. func GetBytes(code, key string) (ret *[]byte, err error) {
  198. defer catch()
  199. conn := RedisPool[code].Get()
  200. defer conn.Close()
  201. var r interface{}
  202. r, err = conn.Do("GET", key)
  203. if err != nil {
  204. log.Println("redisutil-GetBytesError", err)
  205. } else {
  206. if tmp, ok := r.([]byte); ok {
  207. ret = &tmp
  208. } else {
  209. err = errors.New("redis返回数据格式不对")
  210. }
  211. }
  212. return
  213. }
  214. func GetNewBytes(code, key string) (ret *[]byte, err error) {
  215. defer catch()
  216. redisPool := RedisPool[code]
  217. if redisPool == nil {
  218. err = errors.New("redis code " + code + " is nil")
  219. log.Println("redisutil-GetNewBytesError", err)
  220. return
  221. }
  222. conn := redisPool.Get()
  223. defer conn.Close()
  224. var r interface{}
  225. r, err = conn.Do("GET", key)
  226. if err != nil {
  227. log.Println("redisutil-GetNewBytesError", err)
  228. } else if r != nil {
  229. if tmp, ok := r.([]byte); ok {
  230. ret = &tmp
  231. }
  232. }
  233. return
  234. }
  235. //删所有key
  236. func FlushDB(code string) bool {
  237. b := false
  238. defer catch()
  239. conn := RedisPool[code].Get()
  240. defer conn.Close()
  241. var err error
  242. _, err = conn.Do("FLUSHDB")
  243. if nil != err {
  244. log.Println("redisutil-FLUSHDBError", err)
  245. } else {
  246. b = true
  247. }
  248. return b
  249. }
  250. //支持删除多个key
  251. func Del(code string, key ...interface{}) bool {
  252. defer catch()
  253. b := false
  254. conn := RedisPool[code].Get()
  255. defer conn.Close()
  256. var err error
  257. _, err = conn.Do("DEL", key...)
  258. if nil != err {
  259. log.Println("redisutil-DELError", err)
  260. } else {
  261. b = true
  262. }
  263. return b
  264. }
  265. /**
  266. func DelKey(key ...interface{}) {
  267. defer func() {
  268. if r := recover(); r != nil {
  269. log.Println("[E]", r)
  270. for skip := 1; ; skip++ {
  271. _, file, line, ok := runtime.Caller(skip)
  272. if !ok {
  273. break
  274. }
  275. go log.Printf("%v,%v\n", file, line)
  276. }
  277. }
  278. }()
  279. for i := 0; i < len(RedisPool); i++ {
  280. delByNum(i, key...)
  281. }
  282. }
  283. **/
  284. /**
  285. func delByNum(n int, key ...interface{}) {
  286. defer func() {
  287. if r := recover(); r != nil {
  288. log.Println("[E]", r)
  289. for skip := 1; ; skip++ {
  290. _, file, line, ok := runtime.Caller(skip)
  291. if !ok {
  292. break
  293. }
  294. go log.Printf("%v,%v\n", file, line)
  295. }
  296. }
  297. }()
  298. i := 0
  299. for _, v := range RedisPool {
  300. if i == n {
  301. conn := v.Get()
  302. defer conn.Close()
  303. conn.Do("DEL", key...)
  304. break
  305. }
  306. i++
  307. }
  308. }
  309. //根据代码和前辍key删除多个
  310. func DelByCodePattern(code, key string) {
  311. defer catch()
  312. conn := RedisPool[code].Get()
  313. defer conn.Close()
  314. ret, err := conn.Do("KEYS", key)
  315. var result []interface{}
  316. if nil != err {
  317. log.Println("redisutil-GetError", err)
  318. } else {
  319. result = ret.([]interface{})
  320. for k := 0; k < len(result); k++ {
  321. conn.Do("DEL", string(result[k].([]uint8)))
  322. }
  323. }
  324. }
  325. /**
  326. func DelByPattern(key string) {
  327. defer func() {
  328. if r := recover(); r != nil {
  329. log.Println("[E]", r)
  330. for skip := 1; ; skip++ {
  331. _, file, line, ok := runtime.Caller(skip)
  332. if !ok {
  333. break
  334. }
  335. go log.Printf("%v,%v\n", file, line)
  336. }
  337. }
  338. }()
  339. i := 0
  340. for _, v := range RedisPool {
  341. conn := v.Get()
  342. defer conn.Close()
  343. ret, err := conn.Do("KEYS", key)
  344. var result []interface{}
  345. if nil != err {
  346. log.Println("redisutil-GetError", err)
  347. } else {
  348. result = ret.([]interface{})
  349. for k := 0; k < len(result); k++ {
  350. delByNum(i, string(result[k].([]uint8)))
  351. }
  352. }
  353. i++
  354. }
  355. }
  356. **/
  357. //自增计数器
  358. func Incr(code, key string) int64 {
  359. defer catch()
  360. conn := RedisPool[code].Get()
  361. defer conn.Close()
  362. ret, err := conn.Do("INCR", key)
  363. if nil != err {
  364. log.Println("redisutil-INCR-Error", err)
  365. } else {
  366. if res, ok := ret.(int64); ok {
  367. return res
  368. } else {
  369. return 0
  370. }
  371. }
  372. return 0
  373. }
  374. //自减
  375. func Decrby(code, key string, val int) int64 {
  376. defer catch()
  377. conn := RedisPool[code].Get()
  378. defer conn.Close()
  379. ret, err := conn.Do("DECRBY", key, val)
  380. if nil != err {
  381. log.Println("redisutil-DECR-Error", err)
  382. } else {
  383. if res, ok := ret.(int64); ok {
  384. return res
  385. } else {
  386. return 0
  387. }
  388. }
  389. return 0
  390. }
  391. //根据正则去取
  392. func GetKeysByPattern(code, key string) []interface{} {
  393. defer catch()
  394. conn := RedisPool[code].Get()
  395. defer conn.Close()
  396. ret, err := conn.Do("KEYS", key)
  397. if nil != err {
  398. log.Println("redisutil-GetKeysError", err)
  399. return nil
  400. } else {
  401. res, _ := ret.([]interface{})
  402. return res
  403. }
  404. }
  405. //批量取多个key
  406. func Mget(code string, key []string) []interface{} {
  407. defer catch()
  408. conn := RedisPool[code].Get()
  409. defer conn.Close()
  410. interfaceKeys := make([]interface{}, len(key))
  411. for n, k := range key {
  412. interfaceKeys[n] = k
  413. }
  414. ret, err := conn.Do("MGET", interfaceKeys...)
  415. if nil != err {
  416. log.Println("redisutil-MgetError", err)
  417. return nil
  418. } else {
  419. res, _ := ret.([]interface{})
  420. return res
  421. }
  422. }
  423. //取出并删除Key
  424. func Pop(code string, key string) (result interface{}) {
  425. defer catch()
  426. conn := RedisPool[code].Get()
  427. defer conn.Close()
  428. ret, err := conn.Do("GET", key)
  429. if nil != err {
  430. log.Println("redisutil-PopError", err)
  431. } else {
  432. var ok bool
  433. var res []byte
  434. if res, ok = ret.([]byte); ok {
  435. err = json.Unmarshal(res, &result)
  436. if err != nil {
  437. log.Println("Poperr", err)
  438. }
  439. }
  440. conn.Do("DEL", key)
  441. }
  442. return
  443. }
  444. //list操作
  445. func LPOP(code, list string) (result interface{}) {
  446. defer catch()
  447. conn := RedisPool[code].Get()
  448. defer conn.Close()
  449. ret, err := conn.Do("LPOP", list)
  450. if nil != err {
  451. log.Println("redisutil-LPopError", err)
  452. } else {
  453. if res, ok := ret.([]byte); ok {
  454. err = json.Unmarshal(res, &result)
  455. log.Println(err)
  456. }
  457. }
  458. return
  459. }
  460. func RPUSH(code, list string, val interface{}) bool {
  461. defer catch()
  462. conn := RedisPool[code].Get()
  463. defer conn.Close()
  464. _obj, _ := json.Marshal(val)
  465. _, err := conn.Do("RPUSH", list, _obj)
  466. if nil != err {
  467. log.Println("redisutil-RPUSHError", err)
  468. return false
  469. }
  470. return true
  471. }
  472. func LLEN(code, list string) int64 {
  473. defer catch()
  474. conn := RedisPool[code].Get()
  475. defer conn.Close()
  476. ret, err := conn.Do("LLEN", list)
  477. if nil != err {
  478. log.Println("redisutil-LLENError", err)
  479. return 0
  480. }
  481. if res, ok := ret.(int64); ok {
  482. return res
  483. } else {
  484. return 0
  485. }
  486. }
  487. func catch() {
  488. if r := recover(); r != nil {
  489. log.Println(r)
  490. for skip := 0; ; skip++ {
  491. _, file, line, ok := runtime.Caller(skip)
  492. if !ok {
  493. break
  494. }
  495. go log.Printf("%v,%v\n", file, line)
  496. }
  497. }
  498. }