安装Sql server 2008时提示没有安装.net 3.5的解决办法_doyouknowm的专栏-CSDN博客

mikel阅读(1783)

来源: 安装Sql server 2008时提示没有安装.net 3.5的解决办法_doyouknowm的专栏-CSDN博客

将dotNetFx35setup.exe拷贝至对应目录下(由操作系统而定),如下:

x86\redist\DotNetFrameworks\dotNetFx35setup.exe

x64\redist\DotNetFrameworks\dotNetFx35setup.exe

如果还有其他问题,比如WindowsInstaller 4.5的安装失败或者语言包的问题,同样的处理方式。
————————————————
版权声明:本文为CSDN博主「doyouknowm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/doyouknowm/article/details/61617892

Notepad++ 搜索功能学习总结_bcbobo21cn的专栏-CSDN博客

mikel阅读(1662)

来源: Notepad++ 搜索功能学习总结_bcbobo21cn的专栏-CSDN博客

一 实例

先看一下查找菜单;

查找对话框;

 

标记功能;选中 标记所在行;

 

标记后的情况如下图;

 

 

文件查找功能;下图是在 C:\Windows\Microsoft.NET\Framework\v4.0.30319目录下的所有文件(含子目录)中查找字符串”xml”;

 

最后找到的结果如下所示;

 

增量查找;我操作的时候 增量查找 功能应该是默认开启的; 在下部输入框输入查找内容,每输入一个字符就会自动显示文档中匹配的部分,不用全部输入完再打回车才显示,这就是增量查找的含义;

 

列编辑;按住Alt后,即是列编辑模式;按住Alt,再用鼠标选取,可以不用整行的选取;如下图;

 

二 Notepad++查找功能
Notepad++中的高级查找

无论对于哪一种编辑器,基本上都支持正则表达式查找,在Notepad++中也不例外,今天我们一块看下如何使用正则表达式进行查找。

工具/原料
Notepad++
方法/步骤
1
准备以下字符串用来演示
abcdeab
cdeabcde
abcd
eabcde

2
基于扩展的查找
基于扩展的查找不能算是真正的正则表达式搜索,因此这种查找方式仅是提供了支持转义字符。主要常用的转义字符包含了:\r\n\t等。
我们分别使用下面的搜索条件进行查找:
a.*\r\n
abcd\r\n
会发现使用a.*\r\n是无法查找到内容。这也说明了在我们选择“扩展”项时不支持正则条件。

3
使用正则表达式
对于 正则表达式的使用方法我们就不介绍了,这里我们搜索abcd字符串。使用下面的正则进行匹配,为了便于显示,我们使用“标记”功能:
a.+?d
上面的正则表达式的意思是搜索字符串中以a开始,后面有一个或多个字符(.代表除了\n之外的其他字符,+代表匹配一次或多次,?代表非贪婪,即从当前字符开始向后一个一个字符的匹配),最后以d字符结尾。
我们会发现匹配到了4个,可能就会有人问了,那第一行结尾的ab与第二行的cd也应该匹配啊,其实原因就是在于对于正则表达式来说,回车换行代表了一个新的段落开始,如果想匹配那么就涉及到了匹配模式,下面会说明如何进行匹配。

4
匹配新行
为了解决第3步中我们的问题,在Notepad++中提供了“匹配新行”功能,如果我们选中了,那么就会匹配成功第3步所讲的字符串。

关于NotePad++中的查找模式以及符号
Word、Excel、txt等文字编辑文件中有一些平时不可见的符号,如制表符、换行符、软回车等。当我们需要替换或者批量删除这些特殊的符号的时候,NotePad++就是一个很强大的工具了。

\t:制表符。在NotePad++中显示为向右的箭头
\n:换行符。在NotePad++中显示为LF
\r:软回车。在NotePad++中显示为CR
\0:??
\x:??
————————————————
版权声明:本文为CSDN博主「bcbobo21cn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bcbobo21cn/article/details/51803773

sql server 2008 r2 双机热备操作流程_lance_kl的博客-CSDN博客

mikel阅读(733)

来源: sql server 2008 r2 双机热备操作流程_lance_kl的博客-CSDN博客

一、配置步骤:

1.两台服务器,主服务器,从服务器,两台服务器都安装SQL Server 2008R2并且安装相同表结构的数据库(需要实时同步的数据库)

2.主服务器数据库安装完毕,打开SQL Server 配置管理器,把SQL Server 代理服务打开(已打开请忽略)

3.登录主服务器数据库,从数据库左侧菜单栏找到->复制->本地发布,右击新建发布

4.默认主服务器当作分发服务器

5.快照文件夹最好新建一个目录(需要手动在D盘新建目录),默认目录会有权限问题(对于新手权限问题不好解决)

6.选择需要发布的数据库

7.发布类型选择事务发布(发布类型的区别可自行百度,此处不做叙述)

8.选择需要发布的表(需要同步到从服务器数据库表的数据)

9.筛选表行(意思是表中的哪些字段你不需要同步到从服务器)

10.快照代理,选择->立即创建快照并使快照保持可用状态,以初始化订阅

11.代理安全性,点击安全设置,按照红色框中设置即可

12.向导操作,选择->创建发布->下一步

13.完成该向导,填写一个发布名称,点击完成,到此步骤主服务器本地订阅发布已经完成

14.登录从服务器数据库,从数据库左侧菜单栏找到->复制->本地订阅->右击新建订阅->选择查找SQL Server 发布服务器,数据库服务器名称要是主服务器计算机名称,输入登录名和密码

15.选择刚才主服务器发布的订阅

16.选择运行分发代理的位置,勾选第一个,如果选择第二个也需要开启从服务器SQL Server代理服务

17.选择订阅服务器(从服务器),订阅数据库需要同步的数据库(主服务器和从服务器热备份的数据库结构需要一致)

18.分发代理安全性,推荐按红色框中设置,如下图:(注意这里的账号密码,为相应服务器的实际账户密码)

19.同步计划选择连续运行

20.初始化订阅

21.向导操作->创建订阅->下一步->完成

22.刷新从服务器左侧菜单栏下的本地订阅,会出现刚刚创建好的订阅,为了验证设置是否成功,右击创建好的订阅->查看同步状态,如图显示同步正在进行则说明双机热备份设置成功

23.测试配置是否生效,在主服务器数据库通过updata语句修改某个表的字段值,然后查看从服务器数据库是否对应修改即可

 

 

二、SQL Server发布订阅异常处理

1.强制删除发布命令:EXEC SP_REMOVEDBREPLICATION ‘发布数据库名称’;

2.SQL2008发布订阅报错“进程无法在WIN-SERVER 上执行 sp_replcmds”

执行以下SQL脚本

①.首先执行: ALTER AUTHORIZATION ON DATABASE::[数据库名] TO [SQL登录用户名]

②.然后执行:

USE 数据库名

GO

sp_changedbowner ‘SQL登录用户名’

③.最后执行:

EXEC sp_repldone @xactid =NULL, @xact_segno =NULL, @numtrans = 0, @time =0, @reset =1

EXEC sp_replflush

④.如果还是不可以, 重启SQL Server Agent服务。

Log4Net 日志查看工具_随心-CSDN博客

mikel阅读(1158)

来源: Log4Net 日志查看工具_随心-CSDN博客

对于网站开发来说,如果我们采用了log4net来记录日志,那么查看日志最常用的方式就是直接去文件夹下面看,但这样做及其的不方便,于是乎借用log4net的 UdpAppender 开发了下面这样的一个工具用于实时查看日志。

该工具目前支持的功能如下:

支持同时收集多个APP的日志,并且提供筛选功能
支持按照线程ID进行筛选日志
支持通过日志名称筛选日志
支持一键清空显示区域的所有日志
支持自动滚动或者禁止自动滚动
支持置顶或者取消置顶
支持复制配置,复制配置之后粘贴到APP的配置文件中即可使用
支持自定义监听端口
支持调整窗口的透明度
支持调整显示区域的字体大小
界面如下:

 

相关代码已经开源,地址为:https://github.com/cxwl3sxl/LogViewer

程序下载:https://download.csdn.net/download/cxwl3sxl/10330711
————————————————
版权声明:本文为CSDN博主「cxwl3sxl」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cxwl3sxl/article/details/79835851

 SQL Server 2008 R2双机热备_wangqi791975的博客-CSDN博客

mikel阅读(792)

来源: (1条消息) SQL Server 2008 R2双机热备_wangqi791975的博客-CSDN博客

作用:
1、可以实施响应备份事务,备份时间间隔较短
2、当主数据库挂掉时可以切到备份数据库服务器,程序不会挂掉。
3、可以用于读写分离,增删改操作在主数据库服务器上进行,查询在备份数据库服务器上进行。一方面提高软件执行效率,另一方面也减轻主库压力。

操作:
1、需要2台分别安装SQL Server 2008R2的数据库服务器。
2、这里有3个名称需要搞清楚
发布服务器:主库所在的服务器。
分发服务器:用于传递当主库发生变化(增删改)时发送到订阅服务器的
订阅服务器:备份服务器
3、新建发布服务器:

 

 

 

4、新建订阅服务器

 

 

 

 

 

 

————————————————
版权声明:本文为CSDN博主「IngGoer」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangqi791975/article/details/50208071

excel怎么删除指定行?Excel删除指定颜色的行的教程

mikel阅读(1660)

我们在使用Excel的时候,有时候需要删除一些单元格或者行,那么Excel中如何删除指定颜色的行呢?

1、我们在图示空白的单元格输入测试数据和一些带有颜色的行。

2、我们按下CTRL+F打开“找”窗口,或者在菜单栏依次点击“开始-查找/替换”。

3、接着我们在弹出的查找框内点击“选项-设置查找的格式”。

4、依次点击“格式-从单元格选择格式”,用吸管直接吸取黄色单元格。

5、接着我们点“全部查找”后,按ctrl+A即可全选所有黄色单元格。

6、最后右击弹出菜单栏,点击删除,选择整行即可。如图所示,已经删除了所有的黄色单元格。

高并发下的服务器架构演变 - rookie丶 - 博客园

mikel阅读(970)

来源: 高并发下的服务器架构演变 – rookie丶 – 博客园

在如间的网络环境下,高并发的场景无处不在,特别在面试如何解决高并发是一个躲不过的问题,即使生产环境达不到那么高的qps但是也应该给自己留条后路来应对日后可能发生的高并发场景,不用匆忙的加班加点的进行重构。

在应对日常高并发场景常常会有这么几个方法:

  1. 集群&负载均衡SLB
  2. 读写分离&分库分表
  3. 缓存
  4. 异步队列(RebbitMQ)
  5. 分布式系统、微服务

接下来就由浅入深分别来介绍下这几个方法是怎么应用到服务器并且解决高并发的,首先我们先来看下最原始的也是最简单的服务器与应用程序关系。

                                                                      图1

如图1所示在一台服务器上承载了数据库、文件系统、应用程序的所有功能,这就导致即使低qps的情况下服务器的内存或者cpu占比都非常高,用过SQLServer的同僚们都知道为了达到最高效快速的数据查询、存储及运算支持SQL server默认会尽可能的占用内存及CPU来达到自己的目的,从而导致我们的应用程序在处理一些运算或者请求量相对升高时应用程序就会变得非常慢,这时候我们就该考虑升级我们现有的服务器了,当然最高效也是最便捷的方式是升级硬件(cpu、内存、硬盘),这也是最容易达到瓶颈的毕竟一台服务的硬件也是有瓶颈的而且费用也是相当相当高昂的,一般情况下我们会选择我们最开始提到解决高并发方法中分布式来升级我们图1的单一服务器系统架构。

                                                                         图2

如图2所示我们由一台服务器转为三台服务器互相协作的方式来处理每次请求,这也是简单的分布式系统每台服务器各司其职再也不会发生单一应用占用大量cpu或内存的情况导致请求变得缓慢,但是就图2而言的服务器架构的承载能力也是非常有限的,当请求量上升后可能就扛不住宕机了。

一般这时候我们就要分析发生宕机的原因,从图2便知只有服务器A或者服务器B最有可能出现问题,根据以往的经验在请求量升高时数据库会承载绝大部分的压力,如果数据库崩了那么整个应用就会处于不可用的状态,那么为了缓解数据库的压力,我们很自然的就会想到利用缓存,这也是高并发场景下最常用也是最有效最简单的方案,利用好缓存能让你的系统的承载能力提示几倍甚至十几倍几十倍。熟悉二八原则的同僚们都知道80%请求的数据都集中在20%的数据上,虽然有些夸张但是意思就是这么个意思。缓存又分为本地缓存和分布式缓存,本着分布式的原则,我们一般都会选用分布式缓存同时也是为后期做分布式集群打下基础。

                                                                      图3

如图3所示在图2的基础上增加了一台缓存服务器D来储存我们的缓存数据,一般我们会采用redis来存放缓存数据,至于memcache现在应用的频率是非常低的。现在当请求到达应用程序时会优先访问缓存服务器D,若存在缓存数据就直接返回给客户端如果不存在缓存数据才会去数据库获取数据返回给客户端同时将数据保存到缓存服务器D设置缓存失效时间这样下次请求时就不用到数据库查询数据了从而达到减轻数据库压力的目的。虽然缓存能抵挡大部分的请求,但是我们也要做好防止缓存击穿、穿透和雪崩的问题来提升系统的稳定性。

随着业务量的增多和繁多的业务种类图3的系统架构也会慢慢达到瓶颈支撑不住多样化的业务需求,这时候我们就应该采用集群的方式来达到负载均衡的目的,将请求平均的分散到多台服务器来拓展应用程序的承载能力。

                                                                        图4

如图示4所示由服务器A-1、服务器A-2共同承载用户的请求来提高系统的承载能力也就是我们最开始说到集群,出现集群的地方必然少不了负载均衡,图4我们由nginx来实现请求的分发来达到负载均衡的目的。在设计图3的架构的时候我们有说到本地缓存,如果是采用本地缓存而不是分布式缓存那么系统架构就存在一个比较大的缺陷,因为一个请求过来是由nginx区分发的如果我们再用本地缓存那么在在服务器A-1和服务器A-2上可能存在大量相同的本地缓存这样就得不偿失了容易造成服务器资源的浪费严重的还会拖累服务器的性能,利用分布式缓存的好处在于我们不管有多少个应用服务器所有的缓存都是共享的。

图4的服务器架构应该是目前中小型应用中最常用的,而且系统的整体承载能力也相当不错,不过随着业务的发展流量与日俱增,图3的服务器架构也很难保证系统的稳定,特别是日常流量峰值的一些时段图3的系统可能时常会面临奔溃的危险,这时候就要重新分析各服务器的压力承载情况了,显而易见最可能出现问题的就是数据库服务器,终于要对数据库下手了,当下最有效的方法就是就写分离,还是遵循二八原则80%的数据操作都是查询操作。

 

                                                                        图5

如图5所示在图4的基础上由单一的数据库变为主从数据库从库负责数据的查询操作主库负责数据增删改操作,但请求操作主库后主库将操作日志执行到从库达到主从数据一致的目的,但是主从分离后不可能避免的一个问题就是主从数据一致性会有延迟,数据同步延迟的问题只能尽可能的减小数据延迟的时间,但对一些时效性非常高或者不能容忍数据延迟的请求只能做一些妥协,这类操作的crud都在主库上操作这样就避免数据延迟的问题,对一些对于数据时效性不那么严格的请求可以将这部分的查询操作由从库去承载,对于主从数据库个人以为和应用集群是一样的可以理解为集群数据库只不过在请求的分发上制定了规则(主库处理更新、从库处理查询)。

队列下回补充。。。个人对队列的理解不够透彻需要好好组织下再发表。。。

JQuery字符串替换replace方法_王安的博客-CSDN博客_jq字符串替换

mikel阅读(1292)

来源: JQuery字符串替换replace方法_王安的博客-CSDN博客_jq字符串替换

在日常的js开发中,常常会用到JQuery

当要把字符串中的内容替换时,如果使用类似C#的string.replace方法,如下

var str=’aabbccaa’;

str=str.replace(‘aa’,’dd’);

结果是  str=’ddbbccaa’

后面的aa没有被替换,原因是这个写法替换的只有第一次出现的aa,后面的就无效了。

但是,可以使用正则表达式进行替换,模式需要指定为g,表示检索全局。

代码如下:

var str=’aabbccaa’;

var reg=/aa/g;

str=str.replace(reg,’dd’);

结果是  str=’ddbbccdd’

JQuery结合正则表达式,替换的功能会变得更强大。

批量替换多个字符的代码:

var reg=/Q355B|坏|弯|合金|Q55B|Q345B|锈|修不好|短|代|先入|(检尺)/g;
res=spec.replace(reg,”);

Nodejs学习笔记(九)--- 与Redis的交互(mranney/node_redis)入门 - porschev - 博客园

mikel阅读(837)

来源: Nodejs学习笔记(九)— 与Redis的交互(mranney/node_redis)入门 – porschev – 博客园

简介和安装

  • redis简介:
  1. 开源高性能key-value存储;采用内存中(in-memory)数据集的方式,也可以采用磁盘存储方式(前者性能高,但数据可能丢失,后者正好相反)
  2. 支持字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等;支持对复杂数据结构的高速操作。
  3. 特性多,支持主从同步、pub/sub等
  4. 支持多种客户端(http://redis.io/clients

  注:应用场景没有提到,暂时没有太多实际体会,不瞎说,以免误导人,但是从它的简介和特性来说,起码缓存场景是不错的!

Redis下载地址: https://github.com/dmajkic/redis/downloads

node.js客户端:node_redis https://github.com/mranney/node_redis/

  • redis安装(Windows平台)

redis非常方便,直接下载解压就可以使用,因为开发环境是win7 64位,直接下载(示例下载的安装包:redis-2.4.5-win32-win64.zip)

  • redis运行

解压到后运行”64bit”文件夹下的redis-server.exe即可,但是这样运行会出现一个如下警告提示:

#Warning: no config file specified,using the default config. In order to specify a config file use ‘redis-server /path/to/redis.conf’

  提示也比较明显,没有明确的配置文件,使用的是默认配置,请使用‘redis-server /path/to/redis.conf’指定明确的配置文件

   根据提示运行redis成功(如下图)

  在redis-server.exe同级目录下可以看到一个redis.conf文件,这就是配置文件

  • node_redis安装
npm install redis
或者
npm install hiredis redis

我这里采用 npm install hiredis redis 安装

  注:两种都可用,区别在于性能,hiredis是非阻塞的,而且速度更快;如果安装了hiredis,node_redis则会默认以它为解析器,没安装就会用纯JavaScript解释器,对于学习或者开发环境,用哪个都无所谓

redis.createClient()连接到redis服务器

环境都准备好了,就开始写一代简单的代码测试用nodejs连接一下服务器

var redis = require('redis'),
    client = redis.createClient();

client.on('ready',function(err){
    console.log('ready');
});

从上图中可以看到运行结果,输出ready,表示成功!

对代码还是讲一下:

redis.createClient():返回的是一个RedisClient的对象,大家可以输出来看一下此对象的具体信息。

ready:Redis的Connection事件之一,当与redis服务器连接成功后会触发这个事件,此时表示已经准备好接收命令,当这个事件触发之前client命令会存在队列中,当一切准备就绪后按顺序调用

 

对于上面的几句代码就能连接成功redis服务器,原因是当前redis服务器在本地,如果不在本地,怎么连接呢?

复制代码
var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.on('ready',function(res){
    console.log('ready');    
});
复制代码

也是成功!这种方式和上一种在redis.createClient()时分别传入了端口号、服务器IP和设置项

这样就可以用于连接远程的redis服务器,或者利用第三个参数进行一些配置!

redis的默认端口:6379

认证 client.auth(password, callback)

上面试过了,连接到redis服务器,可以看出我们并没有输入密码进行验证的过程就成功连接到了服务器,因为redis服务器默认不需要密码,不过这不太安全,我们肯定要设置一下密码

打开redis.conf文件,找到requirepass,取消注释,设置密码为:porschev

requirepass porschev

然后重启redis服务器;再次利用上面的代码连接到redis服务器,出现错误提示(如下图):ERR operation not permitted

那么如何连接到有密码的redis服务器呢?

简单的试了一下,有两种方法(可能有更多,没试,其实一种完全就够了,多了也没用^_^!)

方式一:通过设置redis.createClient()的第三个参数,也就是设置项来完成

 

复制代码
var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',
    RDS_OPTS = {auth_pass:RDS_PWD},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.on('ready',function(res){
    console.log('ready');    
});
复制代码

上图可以连接成功,通过设置连接设置项中的auth_pass来通过认证!

auth_pass:默认值为null,默认情况下客户端将不通过auth命令连接,如果设置了此项,客户端将调用auth命令连接

方式二:通过client.auth(password, callback)

复制代码
var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('ready',function(res){
    console.log('ready');    
});
复制代码

此方法也可以成功,第一个参数为密码,第二个为回调函数!

单值set和get

复制代码
var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',    //密码    
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('connect',function(){
    client.set('author', 'Wilson',redis.print);
    client.get('author', redis.print);
    console.log('connect');
});

client.on('ready',function(err){
    console.log('ready');
});
复制代码

从输出结果可以看出,set一个值和获取这个值都成功!

代码讲一下:

client.set(key,value,[callback]):设置单个key和value,回调函数可选

client.get(key,[callback]):得到key得到value,回调函数可选(虽然可选,但不写回调函数获取又有什么意义呢^_^!)

connect:Redis的Connection事件之一,在不设置client.options.no_ready_check的情况下,客户端触发connect同时它会发出ready,如果设置了client.options.no_ready_check,当这个stream被连接时会触发connect,

这时候就可以自由尝试发命令

  redis.print:简便的回调函数,测试时显示返回值(从示例的输出结果中可以看出)

 

  其它补充说明:

client.options.no_ready_check:默认值为false,当连接到一台redis服务器时,服务器也许正在从磁盘中加载数据库,当正在加载阶段,redis服务器不会响应任何命令,node_redis会发送一个“准备确认”的INFO命令,

INFO命令得到响应表示此时服务器可以提供服务,这时node_redis会触发”ready”事件,如果该设置项设置为true,则不会有这种检查

  client.set([key,value],callback):与client.set(key,value,[callback]);效果一致(可以自行对上面示例源码进行修改进行测试),必须要有回调函数

多值get和set

复制代码
var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',    //密码    
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('connect',function(){
    client.hmset('short', {'js':'javascript','C#':'C Sharp'}, redis.print);
    client.hmset('short', 'SQL','Structured Query Language','HTML','HyperText Mark-up Language', redis.print);

    client.hgetall("short", function(err,res){
        if(err)
        {
            console.log('Error:'+ err);
            return;
        }            
        console.dir(res);
    });
});

client.on('ready',function(err){
    console.log('ready');
});
复制代码

从输出结果可以看出,set多值和获取都成功!

代码讲一下:

client.hmset(hash, obj, [callback]):赋值操作,第一个参数是hash名称;第二个参数是object对象,其中key1:value1。。,keyn:valuen形式;第三个参数是可选回调函数

client.hmset(hash, key1, val1, … keyn, valn, [callback]):与上面做用一致,第2个参数到可选回调函数之前的参数都是key1, val1, … keyn, valn形式;

client.hgetall(hash, [callback]):获取值操作,返回一个对象

 

  其它补充说明:

  console.dir()用于显示一个对象所有的属性和方法

打包执行多个命令[事务]

复制代码
var redis = require('redis'),
    RDS_PORT = 6379,        //端口号
    RDS_HOST = '127.0.1.1',    //服务器IP
    RDS_PWD = 'porschev',    //密码    
    RDS_OPTS = {},            //设置项
    client = redis.createClient(RDS_PORT,RDS_HOST,RDS_OPTS);

client.auth(RDS_PWD,function(){
    console.log('通过认证');
});

client.on('end',function(err){
    console.log('end');
});

client.on('connect',function(){
    var key = 'skills';
      client.sadd(key, 'C#','java',redis.print);
      client.sadd(key, 'nodejs');
      client.sadd(key, "MySQL");
      
      client.multi()      
      .sismember(key,'C#')
      .smembers(key)
      .exec(function (err, replies) {
            console.log("MULTI got " + replies.length + " replies");
            replies.forEach(function (reply, index) {
                console.log("Reply " + index + ": " + reply.toString());
            });
            client.quit();
    });
});
复制代码

官方有个示例,我修改一下,可能更好理解一些,下面一步步说吧!

先了解一下API再看结果

client.multi([commands]):这个标记一个事务的开始,由Multi.exec原子性的执行;github上描述是可以理解为打包,把要执行的命令存放在队列中,redis服务器会原子性的执行所有命令,node_redis接口返回一个Multi对象

Multi.exec( callback ):执行事务内所有命令;github上描述是client.multi()返回一个Multi对象,它包含了所有命令,直到Multi.exec()被调用;

Multi.exec( callback )回调函数参数err:返回null或者Array,出错则返回对应命令序列链中发生错误的错误信息,这个数组中最后一个元素是源自exec本身的一个EXECABORT类型的错误

  Multi.exec( callback )回调函数参数results:返回null或者Array,返回命令链中每个命令的返回信息

  end:redis已建立的连接被关闭时触发

client.sadd(key,value1,…valuen,[callback]):集合操作,向集合key中添加N个元素,已存在元素的将忽略;redis2.4版本前只能添加一个值

sismember(key,value,[callback]):元素value是否存在于集合key中,存在返回1,不存在返回0

smembers(key,[callback]):返回集合 key 中的所有成员,不存在的集合key也不会报错,而是当作空集返回

client.quit():与之对应的还有一个client.end()方法,相对比较暴力;client.quit方法会接收到所有响应后发送quit命令,而client.end则是直接关闭;都是触发end事件

 

再看结果应该就比较简单了,client.multi打包了sismember和smembers两个命令,执行exec方法后,回调函数得到两个回应,分别输出两个回应的结果!

其它…

redis.Debug_mode:这个在开发中可能有用,大家自行设置试一下,设置为true后,看输出

Publish / Subscribe:这个官方示例比较简单清晰,大家运行起来看一下就能理解,深入的网上还有很多用它实现的聊天、监控示例,大家看一下,如果以后觉得有必要就再做个示例分享一下

client.monitor:监控,可能以后会用到,有需要的深入研究一下,入门可以略过

 

其它redis命令还有不少,能讲到的非常有限,深入练习可以对照:http://redis.readthedocs.org/en/latest/index.html

 

参数资料:

https://github.com/mranney/node_redis/

http://redis.readthedocs.org/en/latest/index.html

http://dumbee.net/archives/114

作   者:   Porschev[钟慰]
出   处:   http://www.cnblogs.com/zhongweiv/
微   博:     http://weibo.com/porschev
欢迎任何形式的转载,但请务必注明原文详细链接

【由浅至深】redis 实现发布订阅的几种方式 - nicye - 博客园

mikel阅读(842)

来源: 【由浅至深】redis 实现发布订阅的几种方式 – nicye – 博客园

非常感谢依乐祝发表文章《.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐》,对csredis作了一次完整的诠释。

1|0前言

提到消息队列,最熟悉无疑是 rabbitmq,它基本是业界标准的解决方案。本文详细介绍 redis 多种实现轻订阅方法,作者认为非常有趣并加以总结,希望对有需要的朋友学习 redis 功能有一定的带入作用。

2|0方法一:SUBSCRIBE + PUBLISH

//程序1:使用代码实现订阅端 var sub = RedisHelper.Subscribe((“chan1”, msg => Console.WriteLine(msg.Body))); //sub.Disponse(); //停止订阅 //程序2:使用代码实现发布端 RedisHelper.Publish(“chan1”, “111”);

优势:支持多端订阅、简单、性能高;
缺点:数据会丢失;

参考资料:http://doc.redisfans.com/pub_sub/subscribe.html

3|0方法二:BLPOP + LPUSH(争抢)

//程序1:使用代码实现订阅端 while (running) { try { var msg = RedisHelper.BLPop(5, “list1”); if (string.IsNullOrEmpty(msg) == false) { Console.WriteLine(msg); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } //程序2:使用代码实现发布端 RedisHelper.LPush(“list1”, “111”);

优势:数据不会丢失、简单、性能高;
缺点:不支持多端(存在资源争抢);

总结:为了解决方法一的痛点,我们实现了本方法,并且很漂亮的制造了一个新问题(不支持多端订阅)。

3|1学习使用 BLPOP

BLPOP key [key …] timeout

BLPOP 是列表的阻塞式(blocking)弹出原语。

它是 LPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止。

当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。

非阻塞行为

当 BLPOP 被调用时,如果给定 key 内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。

当存在多个给定 key 时, BLPOP 按给定 key 参数排列的先后顺序,依次检查各个列表。

假设现在有 job 、 command 和 request 三个列表,其中 job 不存在, command 和 request 都持有非空列表。考虑以下命令:

BLPOP job command request 0

BLPOP 保证返回的元素来自 command ,因为它是按”查找 job -> 查找 command -> 查找 request “这样的顺序,第一个找到的非空列表。

redis> DEL job command request # 确保key都被删除 (integer) 0 redis> LPUSH command “update system…” # 为command列表增加一个值 (integer) 1 redis> LPUSH request “visit page” # 为request列表增加一个值 (integer) 1 redis> BLPOP job command request 0 # job 列表为空,被跳过,紧接着 command 列表的第一个元素被弹出。 1) “command” # 弹出元素所属的列表 2) “update system…” # 弹出元素所属的值

阻塞行为

如果所有给定 key 都不存在或包含空列表,那么 BLPOP 命令将阻塞连接,直到等待超时,或有另一个客户端对给定 key 的任意一个执行 LPUSH 或 RPUSH 命令为止。

超时参数 timeout 接受一个以秒为单位的数字作为值。超时参数设为 0 表示阻塞时间可以无限期延长(block indefinitely) 。

redis> EXISTS job # 确保两个 key 都不存在 (integer) 0 redis> EXISTS command (integer) 0 redis> BLPOP job command 300 # 因为key一开始不存在,所以操作会被阻塞,直到另一客户端对 job 或者 command 列表进行 PUSH 操作。 1) “job” # 这里被 push 的是 job 2) “do my home work” # 被弹出的值 (26.26s) # 等待的秒数 redis> BLPOP job command 5 # 等待超时的情况 (nil) (5.66s) # 等待的秒数

更多学习资料:http://doc.redisfans.com/list/blpop.html

4|0方法三:BLPOP + LPUSH(非争抢)

本方法根据方法二演变而来,设计图如下:

如何实现三端订阅,都可收到消息,三端分别为 sub3, sub4, sub5:

1、sub3, sub4, sub5 使用【方法二】订阅 listkey:list1_sub3,list1_sub4,list1_sub5;

2、总订阅端订阅 listkey:list1,总订阅端收到消息后,执行 lpush list1_sub1 msg, lpush list1_sub2 msg, lpush list1_sub3 msg;

总订阅端订阅原始消息,随后将消息分发给其他订阅端,从而解决【方法二】不支持多端同时订阅的缺点。

最终实现的逻辑为:多端先争抢 list1 消息,抢到者再向其他端转发消息。

5|0测试代码

nuget Install-Package CSRedisCore

var rds = new CSRedis.CSRedisClient(“127.0.0.1:6379,password=,poolsize=50,ssl=false,writeBuffer=10240”); //sub1, sub2 争抢订阅(只可一端收到消息) var sub1 = rds.SubscribeList(“list1”, msg => Console.WriteLine($”sub1 -> list1 : {msg})); var sub2 = rds.SubscribeList(“list1”, msg => Console.WriteLine($”sub2 -> list1 : {msg})); //sub3, sub4, sub5 非争抢订阅(多端都可收到消息) var sub3 = rds.SubscribeListBroadcast(“list2”, “sub3”, msg => Console.WriteLine($”sub3 -> list2 : {msg})); var sub4 = rds.SubscribeListBroadcast(“list2”, “sub4”, msg => Console.WriteLine($”sub4 -> list2 : {msg})); var sub5 = rds.SubscribeListBroadcast(“list2”, “sub5”, msg => Console.WriteLine($”sub5 -> list2 : {msg})); //sub6 是redis自带的普通订阅 var sub6 = rds.Subscribe((“chan1”, msg => Console.WriteLine(msg.Body))); Console.ReadKey(); sub1.Dispose(); sub2.Dispose(); sub3.Dispose(); sub4.Dispose(); sub5.Dispose(); sub6.Dispose(); rds.Dispose(); return;

测试功能时,发布端可以使用 redis-cli 工具。

6|0结语

redis 功能何其多且相当好玩有趣 ,大家应尽可能多带着兴趣爱好去学习它。

若文中有不好的地方,请提出批评与改正方法,谢谢观赏。

本文使用到 CSRedisCore 的开源地址:https://github.com/2881099/csredis