redis.go 10 KB

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