项目介绍

简单的Go微服务和Redis的示例代码,实现了对用户信息的添加、查询和删除功能。

关于Redis

Redis是一种基于内存的NoSQL数据库,其主要特点是快速的读写速度和高并发性能。它常用于以下场景:

  • 缓存:Redis支持数据的缓存,可以将经常使用的数据缓存在内存中,加速访问速度。

  • 分布式锁:由于Redis的高性能和原子性操作,它可以用来实现分布式锁,防止多个进程同时修改同一资源。

  • 计数器:Redis支持原子性的操作,可以用来实现计数器,比如网站的访问次数统计。

  • 消息队列:Redis支持发布/订阅模式和列表结构,可以用来实现简单的消息队列。

项目代码
package main

import (
	"encoding/json"
	"log"
	"net/http"

	"github.com/gomodule/redigo/redis"
	"github.com/gorilla/mux"
)

func RedisPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:   80,
		MaxActive: 12000,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", ":6379")
			if err != nil {
				panic(err.Error())
			}
			return c, err
		},
	}
}

func GetUserFromRedis(id string) (string, error) {
	conn := RedisPool().Get()
	defer conn.Close()

	data, err := redis.String(conn.Do("GET", id))
	if err != nil {
		return "", err
	}

	return data, nil
}

func SetUserToRedis(id string, data interface{}) error {
	conn := RedisPool().Get()
	defer conn.Close()

	value, err := json.Marshal(data)
	if err != nil {
		return err
	}

	_, err = conn.Do("SET", id, value)
	if err != nil {
		return err
	}

	return nil
}

func DeleteUserFromRedis(id string) error {
	conn := RedisPool().Get()
	defer conn.Close()

	_, err := conn.Do("DEL", id)
	if err != nil {
		return err
	}

	return nil
}

type User struct {
	ID    string `json:"id"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

func GetUser(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

	data, err := GetUserFromRedis(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if data == "" {
		http.Error(w, "User not found", http.StatusNotFound)
		return
	}

	user := &User{}
	if err := json.Unmarshal([]byte(data), user); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(user)
}

func CreateUser(w http.ResponseWriter, r *http.Request) {
	user := &User{}
	if err := json.NewDecoder(r.Body).Decode(user); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if user.ID == "" {
		http.Error(w, "Missing user ID", http.StatusBadRequest)
		return
	}

	if user.Name == "" {
		http.Error(w, "Missing user name", http.StatusBadRequest)
		return
	}

	if user.Email == "" {
		http.Error(w, "Missing user email", http.StatusBadRequest)
		return
	}

	if err := SetUserToRedis(user.ID, user); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusCreated)
}

func DeleteUser(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

	if err := DeleteUserFromRedis(id); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
}
func main() {
	router := mux.NewRouter()

	router.HandleFunc("/users/{id}", GetUser).Methods("GET")
	router.HandleFunc("/users", CreateUser).Methods("POST")
	router.HandleFunc("/users/{id}", DeleteUser).Methods("DELETE")

	log.Fatal(http.ListenAndServe(":8080", router))
}