首页 > 数据库 >CSRedis用于Redis哨兵模式,NetCore

CSRedis用于Redis哨兵模式,NetCore

时间:2024-06-04 14:11:38浏览次数:17  
标签:string NetCore redis Redis CSRedis new using Configuration public

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

上一节通过两台windowsServer服务器部署了Redis的哨兵模式,详情参考:两台windowserver服务器配置Redis哨兵集群----一主二从

redis通过主从复制来实现高可用,但是发生故障时需要人工进行主从切换,效率低下。哨兵机制实现了redis主从的自动切换,提高了redis集群的可用性,提高了redis集群的故障转移效率。 我们可以看到哨兵机制是有缺点的:   

1.主从服务器的数据要经常进行主从复制,这样造成性能下降。   

2.当主服务器宕机后,从服务器切换成主服务器的那段时间,服务是不能用的。

3.为了保证redis的真真的高可用官方推荐使用redis-cluster集群。 一般的项目我们采用redis的哨兵模式架构(推荐采用一主二从三哨兵)就可以满足业务要求了

 1、新建控制台应用程序

引用如下:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
      
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="CSRedisCore" Version="3.8.803" />
      <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" />
      <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.9" />
      <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="3.1.9" />
      <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.11" />
      <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.9" />
      <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
      <PackageReference Include="NLog.Extensions.Logging" Version="5.0.4" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Common\Common.csproj" />
  </ItemGroup>
    <ItemGroup>
        <None Update="appsettings.json">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </None>
        <None Update="nlog.config">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </None>
    </ItemGroup>
</Project>
View Code

代码如下:

using Common;
using CSRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace CSRedisCoreTEST
{
    class Program
    {
        static void Main(string[] args)
        {
            ConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddJsonFile("appsettings.json", true, true);
            var ConfigRoot = builder.Build();//根节点
            IServiceCollection Services = new ServiceCollection();
         
            Services.AddLogging(log => { log.AddConsole(); log.AddNLog(); log.SetMinimumLevel(LogLevel.Error); });
            string sentinelConnectString = ConfigRoot.GetSection("CsRedisConfig:SentinelConnectString").Value;
 
            string[] sentinelValues = ConfigRoot.GetSection("CsRedisConfig:Sentinel").Get<string[]>();

            //  创建redis哨兵访问类(Redis Sentinel)
            var csredis = new CSRedis.CSRedisClient(connectionString: sentinelConnectString, sentinels: sentinelValues);

            // 初始化 RedisHelper
            RedisHelper.Initialization(csredis);

            // 将csredis实例注册到管道中
            Services.AddSingleton<CSRedis.CSRedisClient>(RedisHelper.Instance);
            Services.AddScoped<RdsTestService>();
            using (ServiceProvider provider = Services.BuildServiceProvider())
            {
                var der = provider.GetService<RdsTestService>();
                der.TestSet(); der.TestGet();
            }  
            CreateHostBuilder(args).Run();
        }

        public static IHost CreateHostBuilder(string[] args)
        {
            var builder = Host.CreateDefaultBuilder(args)
                 .ConfigureServices((hostContext, services) =>
                 {
                     services.AddHostedService<BeatService>();

                 }).UseWindowsService();
            var host = builder.Build();

            return host;
        }
    }

    public class RdsTestService
    {
        private readonly CSRedis.CSRedisClient cSRedisClient;

        public RdsTestService(CSRedis.CSRedisClient cSRedisClient)
        {
            this.cSRedisClient = cSRedisClient;
        } 

        public void TestSet()
        {
            this.cSRedisClient.Set("testDF","我是一只小小小奥鸟",TimeSpan.FromMinutes(4));
        }
        public void TestGet()
        {
            var result = this.cSRedisClient.Get("testDF"); 
        }

    }

    public class BeatService : BackgroundService
    {
        private readonly ILogger<BeatService> _logger; 
        public BeatService( 
        ILogger<BeatService> logger)
        { 
            _logger = logger;
        }
        public override Task StartAsync(CancellationToken cancellationToken)
        {
            return base.StartAsync(cancellationToken);
        }

        /// <summary>
        ///  每一秒执行一次
        /// </summary>
        /// <param name="stoppingToken"></param>
        /// <returns></returns>
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            { 
                var result = CSRedisHelper.GetInstance().Get("testDF");
                Console.WriteLine("BackgroundService通过单例模式获取到的值为:" + result);
                await Task.Delay(1000, stoppingToken);
            }
               
        } 
    }
}
View Code

配置文件如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "CsRedisConfig": {
    "SentinelConnectString": "mymaster,defaultDatabase=3,poolsize=1000",
    "Sentinel": [
      "172.27.40.27:26379",
      "172.27.40.29:26379",
      "172.27.40.29:26380"
    ]
  }
}

nlog.config如下

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="logs/internal-nlog-AspNetCore.txt">

    <!-- enable asp.net core layout renderers -->
    <extensions>
        <add assembly="NLog.Web.AspNetCore"/>
    </extensions>

    <!-- the targets to write to -->
    <targets>
        <!-- File Target for all log messages with basic details -->
        <target xsi:type="File" name="allfile" fileName="logs/log-${shortdate}.log"
                layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" archiveAboveSize="10000" maxArchiveFiles="3"/>

        <!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
        <target xsi:type="File" name="ownFile-web" fileName="logs/nlog-AspNetCore-own-${shortdate}.log"
                layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" archiveAboveSize="10000" maxArchiveFiles="3" />

        <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
        <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
    </targets>

    <!-- rules to map from logger name to target -->
    <rules>
        <!--All logs, including from Microsoft-->
        <logger name="*" minlevel="Trace" writeTo="allfile" />

        <!--Output hosting lifetime messages to console target for faster startup detection -->
        <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />

        <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
        <logger name="Microsoft.*" maxlevel="Info" final="true" />
        <logger name="System.Net.Http.*" maxlevel="Info" final="true" />

        <logger name="*" minlevel="Trace" writeTo="ownFile-web" />
    </rules>
</nlog>
View Code

 

2、新建公共类库,用于Csredis单例模式

引用如下:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="CSRedisCore" Version="3.8.803" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" />
      <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
      <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.9" />
  </ItemGroup>

</Project>

公共类如下:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using System;
using CSRedis;  

namespace Common
{
    public class ConfigCommon
    {
        public static IConfiguration Configuration { get; set; }
        static ConfigCommon()
        {
            //#if DEBUG
            //            Configuration = new ConfigurationBuilder()
            //           .Add(new JsonConfigurationSource { Path = "appsettings.Development.json", ReloadOnChange = true })
            //           .Build();
            //#else     
            //            Configuration = new ConfigurationBuilder()
            //            .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true })
            //            .Build();
            //#endif

            Configuration = new ConfigurationBuilder()
            .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true })
            .Build();
        }

        public static string GetConfig(string key, string defaultValue = "")
        {
            string settingValue = Configuration[key];
            return string.IsNullOrEmpty(settingValue) ? defaultValue : settingValue;
        }

    } 
    /// <summary>
    /// 单例模式的实现
    /// </summary>
    public class CSRedisHelper
    {
        // 定义一个静态变量来保存类的实例
        private static CSRedisClient Instance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        // 定义私有构造函数,使外界不能创建该类实例
        private CSRedisHelper()
        {
        }

        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static CSRedisClient GetInstance()
        {
            // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
            // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (Instance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (Instance == null)
                    {
                        Console.WriteLine(DateTime.Now.ToString("HHmmss") + "开始获取实例");
                        string sentinelConnectString = ConfigCommon.GetConfig("CsRedisConfig:SentinelConnectString");

                        string[] sentinelValues = ConfigCommon.Configuration.GetSection("CsRedisConfig:Sentinel").Get<string[]>();

                        //  创建redis哨兵访问类(Redis Sentinel)
                        Instance = new CSRedis.CSRedisClient(connectionString: sentinelConnectString, sentinels: sentinelValues);

                        // 初始化 RedisHelper
                        RedisHelper.Initialization(Instance);
                    }
                }
            }
            return Instance;
        }
    }
}
View Code

 

标签:string,NetCore,redis,Redis,CSRedis,new,using,Configuration,public
From: https://www.cnblogs.com/chenwolong/p/18230595

相关文章

  • Conts7 安装Redis教程
    1.添加软件安装源yuminstalleple-release2.安装Redisyuminstallredis-y3.启动redissystemctlstartredis4.允许开机启动systemctlenableredis5.修改redis配置文件vim/ect/redis.conf修改2处文件(虚拟机)6.重启redissystemctlrestartredis7.登陆redis数......
  • redis - [03] 配置&命令
    题记部分 一、配置(Config)  二、命令(Command)(1)启动redis服务:redis-server.exeredis.windows.conf(2)连接redis-server:redis-cli-hhost-pport-apassword(3)查看key是否存在:existsmyKey(4)查看key的值:getmyKey(5)序列化给定key,返回序列化的值(不会改变key的值):dumpmy......
  • Redis之set
    SetRedis的Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。(无序不重复)集合对象的编码可以是intset或者hashtable。Redis中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。案例127.0.0.1:6379>SADDmysethe......
  • Redis之list
    Redis列表(List)Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含2^32-1个元素(4294967295,每个列表超过40亿个元素)。list可以定义一些规则,使它作为栈、队列或双端队列。案例LPUSH&RPUSH127.......
  • 面试必会->Redis篇
    01-你们项目中哪里用到了Redis?在我们的项目中很多地方都用到了Redis,Redis在我们的项目中主要有三个作用:使用Redis做热点数据缓存/接口数据缓存使用Redis存储一些业务数据,例如:验证码,用户信息,用户行为数据,数据计算结果,排行榜数据等使用Redis实现分布......
  • [redis 源码走读] - 跳跃表(skiplist)
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......
  • synchronized、Lock本地锁和Redisson分布式锁的简单使用
    文章目录概念准备工作synchronized本地锁演示JUC包的Lock本地锁演示Redisson的RLock分布式锁演示源码地址参考来源概念redisson是一个简单易用的Redis客户端工具。不仅如此,它还具备分布式锁的功能准备工作快速整合SSMP请参考我这篇文章SpringBoot快速整合Spring......
  • redis - [02] 安装部署
    在Windows和Linux操作系统下的安装部署  一、windows版(1)访问redis下载地址:https://github.com/tporadowski/redis/releases(2)将Redis-x64-5.0.14.1.zip下载并解压到合适的目录(3)打开cmd窗口,切换到该目录下运行:redis-server.exeredis.windows.conf运行之后,redis服务就......
  • redis自学(45)缓存同步
                             整个多级缓存的架构  ......
  • redis - [01] 概述
    题记部分 一、什么是redis  是一个由SalvastoreSanfilippo使用ANSIC语言编写的key-value存储系统,遵守BSD协议、支持网络、可基于内存、分布式、可选持久性的跨平台的非关系型数据库,并提供多种语言的API。Redis通常被称为数据结构服务器,因为值可以是字符串、哈希、列表、......