zoukankan      html  css  js  c++  java
  • asp.net core 实战之 redis 负载均衡和"高可用"实现

    1.概述

      分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的"高可用"实现, 呵呵双引号的"高可用"并不是传统意义的高可用哈,而是 redis集群挂了,并不影响asp.net core 的运行, 欲知详情,请看下文.

    注意: 本文主要阐述redis 的复制均衡和"高可用", 故redis 的主从复制搭建略, 请自行百度.

    2.负载均衡实现

      目前在tcp 负载均衡这块, haproxy 是官方实现, nginx 是三方实现, 个人偏向haproxy的简单易用. 故redis的负载均衡采用haproxy实现.

      Haproxy配置文件如下:

    global
        log 127.0.0.1 local2 #log语法:log <address_1>[max_level_1] # 全局的日志配置,使用log关键字,指定使用127.0.0.1 上的syslog服务中的local0日志设备,记录日志等级为info的日志
                                                                         
        chroot /var/lib/haproxy           #当前工作目录
        pidfile /var/run/haproxy.pid     #当前进程id文件
        maxconn 6000      #最大并发连接数
        user haproxy     #所属用户
        group haproxy     #所属组
        daemon             #以守护进程方式运行haproxy
        stats socket /var/lib/haproxy/stats
    defaults
        mode http     #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
        log global    #应用全局的日志配置
        option httplog    #启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求日志
        option dontlognull    # 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该 服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
        option http-server-close  #每次请求完毕后主动关闭http通道
        option forwardfor except 127.0.0.0/8 #如果服务器上的应用程序想记录发起请求的客户端的IP地址,需要在HAProxy上 配置此选项, 这样 HAProxy会把客户端的IP信息发送给服务器,在HTTP请求中添加"X-Forwarded-For"字段。 启用  X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP。
        option redispatch   # 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了, 但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
        retries 3       # 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
        timeout http-request 10s     #http请求超时时间
        timeout queue 1m             #一个请求在队列里的超时时间
        timeout connect 10s            #连接超时
        timeout client 1m            #客户端超时
        timeout server 1m            #服务器端超时
        timeout http-keep-alive 10s    #设置http-keep-alive的超时时间
        timeout check 10s            #检测超时
        maxconn 6000                #每个进程可用的最大连接数
    listen stats     #统计界面
        mode http
        bind *:2080    
        stats enable 
        stats refresh 30s
        stats uri /hastats
        stats realm Haproxy Statistics  
        stats auth admin:admin
        stats admin if TRUE
    frontend healthcheck
        bind :1099     #定义外部检测机制
        mode http    #http 负载均衡
        option httpclose
        option forwardfor
        default_backend AnuoApcNodes
    frontend http-in
        bind *:88 #监听的端口,处理请求的服务器集群为 default_backend 的配置值
        mode http 
        log global
        option httpclose
        option logasap #不等待响应结束就记录日志,表示提前记录日志,一般日志会记录响应时长,此不记录响应时长
        option dontlognull #不记录空信息
        capture request header Host len 20 #记录请求首部的前20个字符
        capture request header Referer len 60 #referer跳转引用,就是上一级
        default_backend AnuoApcNodes #处理请求的服务器集群
    backend AnuoApcNodes     #处理请求的服务器集群
        mode http
        balance roundrobin
        #check : 下面的check 表示ha 需要检查此节点的状态
        server websrv1 192.168.2.108:9090 check maxconn 6000
        server websrv2 192.168.1.112:88 check maxconn 6000
        
    listen SQLServer :1433  #tcp 负载均衡
        mode tcp
        balance roundrobin
        #weight : 权重, 表示此节点的优先级,值越高(最高256) , 优先执行越高
        #check port : 检测是否存活的端口
        #inter : interval 检测是否存活的 时间间隔
        #rise : server 从离线状态转为正常状态后, 需要复查的次数(看是否正常)
        #fall : server 从正常状态转换为不可用状态需要检查的次数
        server SQLServer1 192.168.2.101:1433 weight 1 maxconn 6000 check port 1433 inter 2000 rise 2 fall 2
        server SQLServer2 192.168.2.203:1433 weight 1 maxconn 6000 check port 1433 inter 2000 rise 2 fall 2
    listen Redis :6377  #tcp 负载均衡
        mode tcp
        balance roundrobin
        #weight : 权重, 表示此节点的优先级,值越高(最高256) , 优先执行越高
        #check port : 检测是否存活的端口
        #inter : interval 检测是否存活的 时间间隔
        #rise : server 从离线状态转为正常状态后, 需要复查的次数(看是否正常)
        #fall : server 从正常状态转换为不可用状态需要检查的次数
        server Redis1 192.168.2.101:6379 weight 1 maxconn 6000 check port 6379 inter 2000 rise 2 fall 2
        server Redis2 192.168.2.102:6379 weight 1 maxconn 6000 check port 6379 inter 2000 rise 2 fall 2

    其中最后的配置:

    为redis的负载均衡配置, 可以看到负载了两个redis IP, 101和102 .

    在实际运行中, redis的主库一般用作写, 从库用作读, so , 一般针对redis的从库进行负载.

    只需将上面的两个IP 替换为自己的ip 即可完成对 redis 从库的负载.

    3. asp.net core 端针对 redis "高可用"实现

    实现思路: 此处的实现不是传统意义的高可用实现,而是C#端检测到redis集群挂了, 自动将redis从系统中剔除, 保证asp.net core 能继续运行

    业界问题: redis 的高可用有官方实现叫sentinel , 现在应用案例并不多, 也逮到官方文档看了哈, 看了半天没看到, 有sentinel实战教程推荐的,或其他高可用实现的, 望留言 ^_^

    先下载完整源码: http://pan.baidu.com/s/1i52ViWP

    源码配置运行步骤如下:

    如下图

    3.1.配置VIPPort的值为 haproxy 暴露的redis 集群端口,如下图值

    3.2.配置ClusterVIPCom值为 haproxy 所在服务器 的 IP

    3.3.配置ClusterMultiIPCom 值为 redis主从复制集群中的全部从库IP, 用分号分割IP

    3.4. 代码运行起来, 调用 Sample 接口, 如下图

    调用URL: Get方法  http://localhost:9526/api/RedisTest/Sample

    运行逻辑如下:

    第一次取数据, redis没得缓存, 制造缓存对象, 缓存到redis, 成功返回.

    第二次取数据, redis 有缓存, 从缓存中取, 成功返回.

    第三次取数据, 假如redis挂了, 制造缓存对象, 还是成功返回.

    第四次取数据, redis恢复了, 重启 asp.net core ,  程序自动连接上redis, 从redis返回数据, 成功返回.

    至此达到了, redis 和 asp.net core 的完全解耦, 即redis挂了不影响 asp.net core 的继续运行 .

    可以想象哈, 当你半夜收到一个警报说redis挂了的时候, 你可以不慌不忙的去公司慢慢改, 因为asp.net core 还在运行, 只是慢了点而已.

  • 相关阅读:
    周末毒鸡汤时间
    MySQL 8.0发布,你熟悉又陌生的Hash Join?
    你可能需要的Kafka面试题与答案整理
    流程控制结构
    视图
    事务
    常用约束
    sql99语法的连接查询
    数据类型
    数据操作语句(DML)
  • 原文地址:https://www.cnblogs.com/anuo/p/6052029.html
Copyright © 2011-2022 走看看