中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Golang的memcache怎么實現(xiàn)

這篇文章將為大家詳細講解有關(guān)Golang的memcache怎么實現(xiàn),小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:空間域名、網(wǎng)絡(luò)空間、營銷軟件、網(wǎng)站建設(shè)、王益網(wǎng)站維護、網(wǎng)站推廣。

這兩天在做項目的過程中遇到了一個訪問全局變量的問題場景:編寫一個方法,獲取id對應(yīng)的token值,token需要緩存起來(全局變量內(nèi)存緩存),如果獲取不到或者token的時間過期,那么發(fā)送http請求到其他端去取,然后緩存起來,然后再返回,那么代碼如下:

code.go:

package person

import (
	"time"
)

var gAccId2Token map[int]interface{} = make(map[int]interface{})

func GetTokenByAccountId(accountId uint, acl string) (map[string]interface{}, error) {
	//get token from cache
	if token, ok := gAccId2Token[accountId]; ok {
		if token != nil {
			now := time.Now().Unix()
			if int(now) < int(token.(map[string]interface{})["expireDate"].(float64)) {
				return token.(map[string]interface{}), nil
			}
		}
	}

	token, err := getTokenByHttpUrl(apiUrl)
	if err != nil {
		return map[string]interface{}{}, err
	}

	gAccId2Token[accountId] = token

	return token.(map[string]interface{}), nil
}

那么問題來了:

1.由于gAccId2Token變量是全局變量,那么會出現(xiàn)同時讀寫的情況,則會可能出現(xiàn)讀寫不一致的情況。

2.就本例來看,獲取id=2的token,而緩存的token已經(jīng)過期了,那么就會發(fā)送http請求去獲取,之后寫緩存,假設(shè)寫緩存的時間很長,而在這段時間內(nèi),又恰好有大量請求來獲取id=2的token,由于token都過期了,就會出現(xiàn)大量請求http服務(wù)端的問題,不僅沒有起到獲取緩存的目的,又增大了后端的壓力,同時又有多個寫緩存的操作,而golang的map應(yīng)該不是原子的,那么大量寫內(nèi)存也可能會造成crash的問題。

因此,我們需要對讀寫操作進行加鎖:

memcache.go:

package person

import (
	"sync"
	"time"
)

type memoryCache struct {
	lock  *sync.RWMutex
	items map[interface{}]interface{}
}

func (mc *memoryCache) set(key interface{}, value interface{}) error {
	mc.lock.Lock()
	defer mc.lock.Unlock()
	mc.items[key] = value
	return nil
}

func (mc *memoryCache) get(key interface{}) interface{} {
	mc.lock.RLock()
	defer mc.lock.RUnlock()

	if val, ok := mc.items[key]; ok {
		return val
	}
	return nil
}

var gAccId2Token *memoryCache = &memoryCache{
		lock:  new(sync.RWMutex),
		items: make(map[interface{}]interface{}),
	}

func GetTokenByAccountId(accountId uint, acl string) (map[string]interface{}, error) {
	//get token from cache
	token := gAccId2Token.get(accountId)
	if token != nil {
		now := time.Now().Unix()
		if int(now) < int(token.(map[string]interface{})["expireDate"].(float64)) {
			return token.(map[string]interface{}), nil
		}
	}

	token, err := getTokenByHttpUrl(apiUrl)
	if err != nil {
		return map[string]interface{}{}, err
	}

	gAccId2Token.set(accountId, token)

	return token.(map[string]interface{}), nil
}

幾點說明:

1.為寫操作上了全局鎖,一旦Lock()之后,其他lock便不能上鎖,直到釋放鎖Unlock()之后才行,也就是說保證寫操作的原子性。

2.而為讀操作上了讀鎖,那么可以有多個線程Rlock()對一個區(qū)域枷鎖,從而保證區(qū)域是可讀的,直到所有讀鎖都RUnlock()之后,才可以上寫鎖。

3.將map的key和value的類型都定義成為interface{}類型,interface{}可以接收任何類型,就像是Java中的Object。

4.interface{}類型轉(zhuǎn)換的方法,value.(type),即將value轉(zhuǎn)換成為type類型,例如:value.(int),value.(map[string]interface{})等等。

關(guān)于“Golang的memcache怎么實現(xiàn)”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

當前標題:Golang的memcache怎么實現(xiàn)
文章位置:http://www.rwnh.cn/article40/peoieo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、網(wǎng)站排名、做網(wǎng)站、App設(shè)計、軟件開發(fā)網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化
调兵山市| 白朗县| 师宗县| 丰原市| 静安区| 房产| 曲麻莱县| 临桂县| 石景山区| 沂南县| 简阳市| 乐至县| 邵阳县| 延安市| 长丰县| 乌鲁木齐市| 西华县| 衢州市| 洪洞县| 石阡县| 屏山县| 江西省| 灵台县| 牡丹江市| 乌兰县| 沽源县| 昌邑市| 万州区| 益阳市| 前郭尔| 吴忠市| 潞城市| 武强县| 巴塘县| 沧源| 天峻县| 南澳县| 乐清市| 怀宁县| 永平县| 玉田县|