# Request: method: GET url: api/v1.0/areas # data: no input data # Response: # 返回成功 { "errno": 0, "errmsg": "ok", "data": [ {"aid": 1, "aname": "東城區"}, {"aid": 2, "aname": "西城區"}, ... ] } # 返回失敗 { "errno": "400x", // 狀態碼 "errmsg": "狀態錯誤信息" }
$ micro new --type "srv" ihome/GetArea
修更名稱 example.proto
爲 getarea.proto
,上一級文件夾名稱也由 example
改成 getarea
前端
lpgit@lpgit-virtual-machine:~/go/src/ihome/GetArea/proto$ tree . └── getarea └── getarea.proto 1 directory, 1 files
具體 Redis 的安裝與使用, 請查看此文章: Redis 簡介與安裝mysql
下載git
$ wget http://download.redis.io/releases/redis-6.0.5.tar.gz
或者進入網址下載指定版本: http://download.redis.io/releases/github
解壓web
$ tar xzf redis-6.0.5.tar.gz
進入redis
$ cd redis-6.0.5
編譯sql
$ make
安裝shell
$ sudo make install
驗證json
$ redis-cli Could not connect to Redis at 127.0.0.1:6379: Connection refused not connected>
將 redis 安裝包中的 redis.conf
文件複製到項目中 ihome 服務的 conf 文件夾當中vim
而後, 修改 redis.conf
文件
# 69 行左右 bind 127.0.0.1 當前主機ip # 136 行左右修改成 yes,表示守護進程啓動 daemonize yes
在 ihome 服務中建立一個啓動文件
$ sudo vim server.sh
文件內容
redis-server ./conf/redis.conf
給文件賦予啓動權限
$ chmod 777 server.sh
$ go get -v -u github.com/gomodule/redigo/redis $ go get -v -u github.com/garyburd/redigo
$ go get -v -u github.com/astaxie/beego/cache
syntax = "proto3"; package go.micro.srv.GetArea; service Example { rpc GetArea(Request) returns (Response) {} } message Request { } message Response { // 返回錯誤碼 string ErrNo = 1; // 返回錯誤信息 string ErrMsg = 2; // 返回數據類型 message Area { int32 Aid = 1; string Aname = 2; } // 用自定義類型返回的數組 repeated Area Data = 3; }
$ cd /home/lpgit/go/src/ihome/GetArea $ protoc --proto_path=. --go_out=. --micro_out=. proto/getarea/getarea.proto
修改 main.go 文件:添加路由
// 獲取地區信息 rou.GET("/api/v1.0/areas", handler.GetArea)
handler.go
增長 GetArea
函數
package handler import ( "context" "encoding/json" "github.com/julienschmidt/httprouter" "github.com/micro/go-grpc" getarea "ihome/GetArea/proto/getarea" "ihome/ihomeWeb/models" "ihome/ihomeWeb/utils" "net/http" ) // 獲取地區信息 func GetArea(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { // 建立新的 gRPC 返回句柄 server := grpc.NewService() // 服務初始化 server.Init() // 建立獲取地區的服務而且返回句柄 exampleClient := getarea.NewExampleService("go.micro.srv.GetArea", server.Client()) // 調用函數而且返回數據 rsp, err := exampleClient.GetArea(context.TODO(), &getarea.Request{}) if err != nil { return } // 建立返回類型的切片 var areas []models.Area // 循環讀取服務返回的數據 for _, value := range rsp.Data { areas = append(areas, models.Area{Id: int(value.Aid), Name: value.Aname}) } // 建立返回數據 map response := map[string]interface{}{ "errno": rsp.ErrNo, "errmsg": rsp.ErrMsg, "data": areas, } // 注意 w.Header().Set("Content-Type", "application/json") // 將返回的數據 map 發送給前端 if err := json.NewEncoder(w).Encode(response); err != nil { http.Error(w, err.Error(), 503) return } }
修改 main.go
內容,以後每次都和下面同樣進行修改
package main import ( "github.com/micro/go-grpc" "github.com/micro/go-log" "github.com/micro/go-micro" "ihome/GetArea/handler" // 此處修改 getarea "ihome/GetArea/proto/getarea" ) func main() { // New Service // 此處修改:micro 改成 grpc service := grpc.NewService( micro.Name("go.micro.srv.GetArea"), micro.Version("latest"), ) // Initialise service service.Init() // Register Handler // 此處修改 example 改成 getarea // handler.Example 改成 handler.Server getarea.RegisterExampleHandler(service.Server(), new(handler.Server)) // Run service if err := service.Run(); err != nil { log.Fatal(err) } }
handler
下 example.go
文件
package handler import ( "context" "encoding/json" "github.com/astaxie/beego/cache" "github.com/astaxie/beego/orm" "ihome/ihomeWeb/models" "ihome/ihomeWeb/utils" "time" _ "github.com/astaxie/beego/cache/redis" _ "github.com/garyburd/redigo/redis" _ "github.com/gomodule/redigo/redis" getarea "ihome/GetArea/proto/getarea" ) type Server struct{} func (e *Server) GetArea(ctx context.Context, req *getarea.Request, rsp *getarea.Response) error { // 初始化 錯誤碼 rsp.ErrNo = utils.RECODE_OK rsp.ErrMsg = utils.RecodeText(rsp.ErrNo) // 1. 從緩存中獲取數據 // 準備鏈接 redis 信息 redisConf := map[string]string{ "key": utils.G_server_name, "conn": utils.G_redis_addr + ":" + utils.G_redis_port, "dbNum": utils.G_redis_dbnum, } // 將 map 轉化爲 json redisConfJson, _ := json.Marshal(redisConf) // 建立 redis 句柄 bm, err := cache.NewCache("redis", string(redisConfJson)) if err != nil { rsp.ErrNo = utils.RECODE_DBERR rsp.ErrMsg = utils.RecodeText(rsp.ErrNo) return nil } // 獲取數據 areaInfo := bm.Get("areaInfo") if areaInfo != nil { // 緩存中有數據 var areas []map[string]interface{} // 將獲取到的數據解碼 json.Unmarshal(areaInfo.([]byte), &areas) for _, value := range areas { rsp.Data = append(rsp.Data, &getarea.Response_Area{Aid: int32(value["aid"].(float64)), Aname: value["aname"].(string)}) } return nil } // 2. 緩存中沒有數據從 mysql 中查找數據 o := orm.NewOrm() var areas []models.Area num, err := o.QueryTable("Area").All(&areas) if err != nil { rsp.ErrNo = utils.RECODE_DBERR rsp.ErrMsg = utils.RecodeText(rsp.ErrNo) return nil } if num <= 0 { rsp.ErrNo = utils.RECODE_NODATA rsp.ErrMsg = utils.RecodeText(rsp.ErrNo) return nil } // 3. 將查找到的數據存到緩存中 // 將獲取到的數據轉化爲 json 格式 areasJson, _ := json.Marshal(areas) err = bm.Put("areaInfo", areasJson, 3600*time.Second) if err != nil { rsp.ErrNo = utils.RECODE_DBERR rsp.ErrMsg = utils.RecodeText(rsp.ErrNo) return nil } // 4. 將查找到的數據 按照 proto 的格式 發送給前端 for _, value := range areas { rsp.Data = append(rsp.Data, &getarea.Response_Area{Aid: int32(value.Id), Aname: value.Name}) } return nil }
歡迎訪問個人我的網站:
李培冠博客:lpgit.com