直接贴出代码,实现执行lua脚本的方法,用到的第三方类库是 StackExchange.Redis(nuget上有)
注:下面的代码是简化后的,实际使用要修改,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using StackExchange.Redis; namespace TL.Cloud.KV
{
public class Kv:IKv
{ private ConfigurationOptions _redisConfig;// = new ConfigurationOptions
private IDatabaseAsync _db;//=Connection.GetDatabase();
private IServer _server;// = GetServer();
private string _keyPrefix;// 区分前缀 /// <summary>
/// 每个微服务一个kv云实例,或共享云实例中(无独立前缀,服务间Key取名需要自行防止冲突)
/// </summary>
/// <param name="hostServiceName">宿主微服务</param>
public Kv(PublicCloudKvConfig config)
{
Init(config);
} private void Init(PublicCloudKvConfig config)
{
//独特的区分dev/100前缀,online可以没有
_keyPrefix = string.IsNullOrWhiteSpace(config.KeyPrefix)
?null
:config.KeyPrefix.Trim().ToLower()+':';//小写带冒号分割
//ali kv
var kvUrl = config.KvUrl; _redisConfig = ConfigurationOptions.Parse(kvUrl); _redisConfig.Password = config.KvPassword;
_redisConfig.SetDefaultPorts(); //自动填充默认端口
var connection = ConnectionMultiplexer.Connect(_redisConfig);
_db = connection.GetDatabase();
_server = GetServer(); } private IServer GetServer()
{
var config = new ConfigurationOptions
{
KeepAlive = ,
EndPoints = { _redisConfig.EndPoints[]},
AbortOnConnectFail = false,
AllowAdmin = true
};
var conn = ConnectionMultiplexer.Connect(config);
return conn.GetServer(config.EndPoints[]);
} public Task<RedisResult> EvalLua(string lua, IList<RedisKey> keys, IList<RedisValue> values)
{
if (_keyPrefix != null)
keys = keys.Select(p => p.Prepend(_keyPrefix)).ToList();//加上前缀
return _db.ScriptEvaluateAsync(lua, keys.ToArray(), values.ToArray());
} public async Task<RedisResult> EvalLua(byte[] luaSha1, IList<RedisKey> keys, IList<RedisValue> values)
{
if (_keyPrefix != null)
keys = keys.Select(p => p.Prepend(_keyPrefix)).ToList();//加上前缀
return await _db.ScriptEvaluateAsync(luaSha1, keys.ToArray(), values.ToArray());
} public async Task<byte[]> LoadLuaToServerAsync(string lua)
{
var sha1 = lua.CalcLuaSha1();//本地计算
if(!await _server.ScriptExistsAsync(sha1))//服务器上不存在
sha1 = await _server.ScriptLoadAsync(lua);//应该和计算的相同 return sha1;
}
}
}

下面是测试代码段

//下面是测试代码
[Test]
public async Task LoadLuaToServerAsync()
{
var key = "TestEvalLua10010";
var fieldContent = "testlua10011";
const string lua =
"redis.call('SET', KEYS[1], ARGV[1])\n" +
"return redis.call('GET', KEYS[1])\n"; var sha2 = lua.CalcLuaSha1();
var sha1 = await _kv.LoadLuaToServerAsync(lua);
Assert.AreEqual(, sha1.Length);
for (var i = ; i < ; i++)
Assert.AreEqual(sha1[i],sha2[i]); var keys = new List<RedisKey> { key };
var values = new List<RedisValue> { fieldContent };
var result = await _kv.EvalLua(sha1, keys, values);
Assert.AreEqual(fieldContent, (string)result);
}

计算sha1用到的方法

//计算lua的sha1结果,作为执行lua的参数
public static byte[] CalcLuaSha1(this string lua)
{
SHA1 sha1 = new SHA1CryptoServiceProvider();
var bytesSha1In = Encoding.Default.GetBytes(lua);
return sha1.ComputeHash(bytesSha1In);
}

c#中用lua脚本执行redis命令的更多相关文章

  1. Redis进阶之使用Lua脚本自定义Redis命令

    [本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 1.在Redis ...

  2. Lua脚本在redis分布式锁场景的运用

    目录 锁和分布式锁 锁是什么? 为什么需要锁? Java中的锁 分布式锁 redis 如何实现加锁 锁超时 retry redis 如何释放锁 不该释放的锁 通过Lua脚本实现锁释放 用redis做分 ...

  3. Lua脚本在Redis事务中的应用实践

    使用过Redis事务的应该清楚,Redis事务实现是通过打包多条命令,单独的隔离操作,事务中的所有命令都会按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断.事务中的命令要么全部 ...

  4. 运维实践-最新Nginx二进制构建编译lua-nginx-module动态链接Lua脚本访问Redis数据库读取静态资源隐式展现

    关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 本章目录 目录 0x0n 前言 ...

  5. nginx插入lua脚本访问redis

    目标:收集用户日志 流程: 浏览器端get方法将数据传到nginx服务 nginx收集到数据,执行内嵌lua脚本,访问redis,根据token获得用户id 将日志信息存入文件 1.nginx安装,参 ...

  6. 使用Lua 脚本实现redis 分布式锁,报错:ERR Error running script (call to f_8ea1e266485534d17ddba5af05c1b61273c30467): @user_script:10: @user_script: 10: Lua redis() command arguments must be strings or integers .

    在使用SpringBoot开发时,使用RedisTemplate执行 redisTemplate.execute(lockScript, redisList); 发现报错: ERR Error run ...

  7. redis如何执行redis命令

    Redis 命令 Redis 命令用于在 redis 服务上执行操作.所以我们必须要启动Redis服务程序,也就是redis安装目录下的redis-server.exe,你可以双击执行,也可以打开cm ...

  8. shell基础之脚本执行,命令别名以及快捷键等

    脚本执行方式 比如我们在/root/下编写了一个脚本,名字为hello.sh.那么怎么调用执行它呢?有两种办法: (1)直接通过bash,如下: bash  hello.sh 注:采用bash执行脚本 ...

  9. 脚本批量执行Redis命令

    1.将命令写在文件中 数据量比较大的话,建议用程序去生成文件.例如: List<String> planIdList = planDao.findAll().parallelStream( ...

随机推荐

  1. oracle如何导出和导入数据库/表

    oracle如何导出和导入数据库/表 oracle如何将项目中的表导出后在导入自己的数据库中,这是一个完整的操作,对于数据库备份或在本地查看数据验证数据进场用到,一般情况下我都用dos黑窗口进行操作, ...

  2. 有道云笔记导入txt文件的方法

    有道云笔记pc版迷之不能导入txt文件 尝试很多方法后发现 通过网页版 有道云 可以直接上传 但是pc版不能查看而移动端可以查看 很迷~

  3. BZOJ3782 上学路线

    设障碍个数为,\(obs\)则一般的容斥复杂度为\(O(2^{obs})\).但因为这个题是网格图,我们可以用DP解.设\(f[i]\)表示不经过任何障碍到达第\(i\)个障碍的方案数,转移时枚举可以 ...

  4. B. Heaters Div3

    链接 [http://codeforces.com/contest/1066/problem/B] 分析 具体看代码,贪就完事了 代码 #include<bits/stdc++.h> us ...

  5. 《Metasploit渗透测试魔鬼训练营》第一章读书笔记

    第1章 魔鬼训练营--初识Metasploit 20135301 1.1 什么是渗透测试 1.1.1 渗透测试的起源与定义 如果大家对军事感兴趣,会知道各国军队每年都会组织一些军事演习来锻炼军队的攻防 ...

  6. Linux课题实践一

    Linux课题实践一 20135318 刘浩晨 1.1应用安装 (1)掌握软件源的维护方法,配置系统使用软件源镜像  删除过期或者重复的软件包:进入”系统设置“-”软件和更新”-”ubuntu软件“- ...

  7. ☆C++学习心得

    C++是我进大学的学的第一种编程语言,在高中的时候有电脑课,有教过部分的VB语言,所以其实对编程也并不是非常的陌生,刚开是上课也觉得感觉不难,都懂,没多少课后,恍了个神..居然听不懂了!老师经常让我们 ...

  8. Oracle系列(二): Oracle表的外键查询

    在执行数据库删除操作时,外键关联是令我们最烦的一个东西,有了外键关联,就不允许随意删除数据,那么怎知道这个外键关联度的外键属于那个表? select * from user_cons_columns ...

  9. 第二个spring,第五天

    陈志棚:成绩的统筹 李天麟:界面音乐 徐侃:代码算法 完成进度百分之70...会继续努力的!

  10. Microsoft Orleans构建高并发、分布式的大型应用程序框架

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...