redis.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  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 Incrby(code, key string, val int) int64 {
  198. defer catch()
  199. conn := RedisPool[code].Get()
  200. defer conn.Close()
  201. ret, err := conn.Do("INCRBY", key, val)
  202. if nil != err {
  203. log.Println("redisutil-INCRBY-Error", err)
  204. } else {
  205. if res, ok := ret.(int64); ok {
  206. return res
  207. } else {
  208. return 0
  209. }
  210. }
  211. return 0
  212. }
  213. //自减(带限制的)
  214. func DecrbyLimit(code, key string, val int, limit int64) bool {
  215. defer catch()
  216. conn := RedisPool[code].Get()
  217. defer conn.Close()
  218. ret, err := conn.Do("DECRBY", key, val)
  219. if nil != err {
  220. log.Println("redisutil-DECR-Error", err)
  221. return false
  222. } else {
  223. if res, ok := ret.(int64); ok {
  224. if res < limit {
  225. Incrby(code, key, val)
  226. return false
  227. }
  228. return true
  229. } else {
  230. return false
  231. }
  232. }
  233. }
  234. //直接返回字节流
  235. func GetBytes(code, key string) (ret *[]byte, err error) {
  236. defer catch()
  237. conn := RedisPool[code].Get()
  238. defer conn.Close()
  239. var r interface{}
  240. r, err = conn.Do("GET", key)
  241. if err != nil {
  242. log.Println("redisutil-GetBytesError", err)
  243. } else {
  244. if tmp, ok := r.([]byte); ok {
  245. ret = &tmp
  246. } else {
  247. err = errors.New("redis返回数据格式不对")
  248. }
  249. }
  250. return
  251. }
  252. func GetNewBytes(code, key string) (ret *[]byte, err error) {
  253. defer catch()
  254. redisPool := RedisPool[code]
  255. if redisPool == nil {
  256. err = errors.New("redis code " + code + " is nil")
  257. log.Println("redisutil-GetNewBytesError", err)
  258. return
  259. }
  260. conn := redisPool.Get()
  261. defer conn.Close()
  262. var r interface{}
  263. r, err = conn.Do("GET", key)
  264. if err != nil {
  265. log.Println("redisutil-GetNewBytesError", err)
  266. } else if r != nil {
  267. if tmp, ok := r.([]byte); ok {
  268. ret = &tmp
  269. }
  270. }
  271. return
  272. }
  273. //删所有key
  274. func FlushDB(code string) bool {
  275. b := false
  276. defer catch()
  277. conn := RedisPool[code].Get()
  278. defer conn.Close()
  279. var err error
  280. _, err = conn.Do("FLUSHDB")
  281. if nil != err {
  282. log.Println("redisutil-FLUSHDBError", err)
  283. } else {
  284. b = true
  285. }
  286. return b
  287. }
  288. //支持删除多个key
  289. func Del(code string, key ...interface{}) bool {
  290. defer catch()
  291. b := false
  292. conn := RedisPool[code].Get()
  293. defer conn.Close()
  294. var err error
  295. _, err = conn.Do("DEL", key...)
  296. if nil != err {
  297. log.Println("redisutil-DELError", err)
  298. } else {
  299. b = true
  300. }
  301. return b
  302. }
  303. /**
  304. func DelKey(key ...interface{}) {
  305. defer func() {
  306. if r := recover(); r != nil {
  307. log.Println("[E]", r)
  308. for skip := 1; ; skip++ {
  309. _, file, line, ok := runtime.Caller(skip)
  310. if !ok {
  311. break
  312. }
  313. go log.Printf("%v,%v\n", file, line)
  314. }
  315. }
  316. }()
  317. for i := 0; i < len(RedisPool); i++ {
  318. delByNum(i, key...)
  319. }
  320. }
  321. **/
  322. /**
  323. func delByNum(n int, key ...interface{}) {
  324. defer func() {
  325. if r := recover(); r != nil {
  326. log.Println("[E]", r)
  327. for skip := 1; ; skip++ {
  328. _, file, line, ok := runtime.Caller(skip)
  329. if !ok {
  330. break
  331. }
  332. go log.Printf("%v,%v\n", file, line)
  333. }
  334. }
  335. }()
  336. i := 0
  337. for _, v := range RedisPool {
  338. if i == n {
  339. conn := v.Get()
  340. defer conn.Close()
  341. conn.Do("DEL", key...)
  342. break
  343. }
  344. i++
  345. }
  346. }
  347. //根据代码和前辍key删除多个
  348. func DelByCodePattern(code, key string) {
  349. defer catch()
  350. conn := RedisPool[code].Get()
  351. defer conn.Close()
  352. ret, err := conn.Do("KEYS", key)
  353. var result []interface{}
  354. if nil != err {
  355. log.Println("redisutil-GetError", err)
  356. } else {
  357. result = ret.([]interface{})
  358. for k := 0; k < len(result); k++ {
  359. conn.Do("DEL", string(result[k].([]uint8)))
  360. }
  361. }
  362. }
  363. /**
  364. func DelByPattern(key string) {
  365. defer func() {
  366. if r := recover(); r != nil {
  367. log.Println("[E]", r)
  368. for skip := 1; ; skip++ {
  369. _, file, line, ok := runtime.Caller(skip)
  370. if !ok {
  371. break
  372. }
  373. go log.Printf("%v,%v\n", file, line)
  374. }
  375. }
  376. }()
  377. i := 0
  378. for _, v := range RedisPool {
  379. conn := v.Get()
  380. defer conn.Close()
  381. ret, err := conn.Do("KEYS", key)
  382. var result []interface{}
  383. if nil != err {
  384. log.Println("redisutil-GetError", err)
  385. } else {
  386. result = ret.([]interface{})
  387. for k := 0; k < len(result); k++ {
  388. delByNum(i, string(result[k].([]uint8)))
  389. }
  390. }
  391. i++
  392. }
  393. }
  394. **/
  395. //自增计数器
  396. func Incr(code, key string) int64 {
  397. defer catch()
  398. conn := RedisPool[code].Get()
  399. defer conn.Close()
  400. ret, err := conn.Do("INCR", key)
  401. if nil != err {
  402. log.Println("redisutil-INCR-Error", err)
  403. } else {
  404. if res, ok := ret.(int64); ok {
  405. return res
  406. } else {
  407. return 0
  408. }
  409. }
  410. return 0
  411. }
  412. //自减
  413. func Decrby(code, key string, val int) int64 {
  414. defer catch()
  415. conn := RedisPool[code].Get()
  416. defer conn.Close()
  417. ret, err := conn.Do("DECRBY", key, val)
  418. if nil != err {
  419. log.Println("redisutil-DECR-Error", err)
  420. } else {
  421. if res, ok := ret.(int64); ok {
  422. return res
  423. } else {
  424. return 0
  425. }
  426. }
  427. return 0
  428. }
  429. //根据正则去取
  430. func GetKeysByPattern(code, key string) []interface{} {
  431. defer catch()
  432. conn := RedisPool[code].Get()
  433. defer conn.Close()
  434. ret, err := conn.Do("KEYS", key)
  435. if nil != err {
  436. log.Println("redisutil-GetKeysError", err)
  437. return nil
  438. } else {
  439. res, _ := ret.([]interface{})
  440. return res
  441. }
  442. }
  443. //批量取多个key
  444. func Mget(code string, key []string) []interface{} {
  445. defer catch()
  446. conn := RedisPool[code].Get()
  447. defer conn.Close()
  448. interfaceKeys := make([]interface{}, len(key))
  449. for n, k := range key {
  450. interfaceKeys[n] = k
  451. }
  452. ret, err := conn.Do("MGET", interfaceKeys...)
  453. if nil != err {
  454. log.Println("redisutil-MgetError", err)
  455. return nil
  456. } else {
  457. res, _ := ret.([]interface{})
  458. return res
  459. }
  460. }
  461. //取出并删除Key
  462. func Pop(code string, key string) (result interface{}) {
  463. defer catch()
  464. conn := RedisPool[code].Get()
  465. defer conn.Close()
  466. ret, err := conn.Do("GET", key)
  467. if nil != err {
  468. log.Println("redisutil-PopError", err)
  469. } else {
  470. var ok bool
  471. var res []byte
  472. if res, ok = ret.([]byte); ok {
  473. err = json.Unmarshal(res, &result)
  474. if err != nil {
  475. log.Println("Poperr", err)
  476. }
  477. }
  478. conn.Do("DEL", key)
  479. }
  480. return
  481. }
  482. //list操作
  483. func LPOP(code, list string) (result interface{}) {
  484. defer catch()
  485. conn := RedisPool[code].Get()
  486. defer conn.Close()
  487. ret, err := conn.Do("LPOP", list)
  488. if nil != err {
  489. log.Println("redisutil-LPopError", err)
  490. } else {
  491. if res, ok := ret.([]byte); ok {
  492. err = json.Unmarshal(res, &result)
  493. log.Println(err)
  494. }
  495. }
  496. return
  497. }
  498. func RPUSH(code, list string, val interface{}) bool {
  499. defer catch()
  500. conn := RedisPool[code].Get()
  501. defer conn.Close()
  502. _obj, _ := json.Marshal(val)
  503. _, err := conn.Do("RPUSH", list, _obj)
  504. if nil != err {
  505. log.Println("redisutil-RPUSHError", err)
  506. return false
  507. }
  508. return true
  509. }
  510. func LLEN(code, list string) int64 {
  511. defer catch()
  512. conn := RedisPool[code].Get()
  513. defer conn.Close()
  514. ret, err := conn.Do("LLEN", list)
  515. if nil != err {
  516. log.Println("redisutil-LLENError", err)
  517. return 0
  518. }
  519. if res, ok := ret.(int64); ok {
  520. return res
  521. } else {
  522. return 0
  523. }
  524. }
  525. func catch() {
  526. if r := recover(); r != nil {
  527. log.Println(r)
  528. for skip := 0; ; skip++ {
  529. _, file, line, ok := runtime.Caller(skip)
  530. if !ok {
  531. break
  532. }
  533. go log.Printf("%v,%v\n", file, line)
  534. }
  535. }
  536. }