go~在阿里mse上使用redis.call

张占岭發表於2024-04-06

相關依賴

  • github.com/higress-group/proxy-wasm-go-sdk
  • github.com/alibaba/higress/plugins/wasm-go

標準的redis

下面是一個讀取redis指定key的方法,使用了higress的wasm-go元件實現的

	err := config.Client.SMembers("online", func(response resp.Value) {
		for _, item := range response.Array() {
			str := item.String()
			if strings.HasPrefix(str, "\"") {
				str = str[1:]
			}
			if strings.HasSuffix(str, "\"") {
				str = str[:len(str)-1]
			}
			if str == val {
				msg := fmt.Sprintf("your %v (%v) is illegality.", blackType, val)
				fmt.Println(msg)
				ctx.SetContext("X-Blacklist-Reason", msg)
				proxywasm.SendHttpResponse(ERROR_CODE, nil, []byte(msg), -1)
				break
			}
		}
		proxywasm.ResumeHttpRequest() // 恢復
	})

擴充套件的Lua方式

在Redis的Lua指令碼中,可以使用redis.call來執行Redis命令。如果需要在Lua指令碼中設定鍵的過期時間,可以透過呼叫EXPIRE命令來實現。

下面是一個示例,演示如何在Lua指令碼中使用redis.call執行EXPIRE命令來設定鍵的過期時間:

local key = KEYS[1]
local ttl = ARGV[1]

redis.call('SET', key, 'value')
redis.call('EXPIRE', key, ttl)

return 'Key set with expiration time'

在上面的示例中,首先透過KEYS[1]獲取傳入的鍵名,透過ARGV[1]獲取傳入的過期時間(以秒為單位)。然後使用redis.call('SET', key, 'value')設定鍵值對,並使用redis.call('EXPIRE', key, ttl)設定鍵的過期時間為ttl秒。最後返回一個提示資訊。

透過這種方式,你可以在Lua指令碼中使用redis.call執行EXPIRE命令來設定鍵的過期時間。

github.com/alibaba/higress/plugins/wasm-go中的Eval

阿里封裝的wasm-go外掛,在2024-03-18這一天支援了redis,同時也支援使用redis.call,你可以呼叫wasm-go中的Eval方法

  • 方法原型
Eval(script string, numkeys int, keys, args []interface{}, callback RedisResponseCallback) error
  • 開發人員呼叫它
	redisKey := "business:username"
	redisKey2 := "business:session_state"
	var keyArr []interface{}
	keyArr = append(keyArr, redisKey, redisKey2)
	var valueArr []interface{}
	valueArr = append(valueArr, logger.Username, logger.Username+"_"+logger.SessionState, 60*60*24*30)
	err2 := config.Client.Eval("redis.call('ZINCRBY', KEYS[1], 1, ARGV[1]) redis.call('ZINCRBY', KEYS[2], 1, ARGV[2]) redis.call('EXPIRE', KEYS[1], ARGV[3]) redis.call('EXPIRE', KEYS[2], ARGV[3]) return 1", 2, keyArr, valueArr, func(response resp.Value) {
		if response.Integer() == 1 {
			proxywasm.ResumeHttpRequest()
		}
	})
	if err2 != nil {
		return types.ActionContinue
    }
   return types.ActionPause

相關文章