redisutil.go 11 KB

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