redisutil.go 10 KB

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