PHP对接企业微信

前言

        最近在做项目中,要求在后台管理中有企业微信管理的相关功能。相关准备工作,需要准备好企业微信账号,添加自建应用,获得相应功能的权限,以及agentid、secre等。

        参考文档:

        企业微信开发文档

功能实现

        因功能接口比较多,这里以“客户敏感词”为例,以下为“敏感词”管理功能实现。

        1 想法思路

         企业微信接口有请求次数限制,后台操作频繁,避免多次请求企业微信接口,也为了相应速度考虑,我这里考虑将输入进行入库处理。每次新建敏感词,企业微信“新增敏感词”接口请求成功后,将数据添加到数据库,编辑和删除同理。这样敏感词列表、查看敏感词就可以减少对企业微信接口的请求。

        2 注意事项

         (1)敏感词这里需要依赖通讯录中的成员和部门,因此需要先开发这两个模块之后,再进行敏感词功能开发(成员和部门也做了入库处理,所以在下面代码中,我也是直接查询数据库的内容);

         (2)access_token 有三种:通讯录access_token、联系人access_token以及自建应用 access_token,要根据接口需要,看需要哪一种access_token,否则就会报错。敏感词这里使用的是自建应用 access_token。

         (3)要记得添加IP白名单。

        3 代码实现

  InterceptController.php

<?php
// +-----------------------xiaozhe-----------------------------------------------

namespace app\wework\controller;

use cmf\controller\AdminBaseController;
use app\wework\service\InterceptService;
use app\wework\service\WechatInterceptApi;
use app\wework\model\InterceptModel;
use app\wework\model\WeUserModel;
use app\admin\model\AdminMenuModel;

class InterceptController extends AdminBaseController
{
    
    // 敏感词列表
    public function index()
    {   
        // 接口请求敏感词列表
        // $wxinterceptApi = new WechatInterceptApi();
        // $list = $wxinterceptApi->getInterceptRuleList();
        // echo "<pre>";
        // print_r($list);
        // exit;
        $param = $this->request->param();
        $interceptService = new InterceptService();
        $data = $interceptService->getList($param);
        $data->appends($param);
        $this->assign('keyword', isset($param['keyword']) ? $param['keyword'] : '');
        $this->assign('lists', $data->items());
        $this->assign('page', $data->render());
        return $this->fetch();
    }


    // 新增敏感词
    public function add()
    {
        if ($this->request->isPost()) {
            $data = $this->request->param();
            $interceptModel = new InterceptModel();
            $data['create_time'] = time();
            $data['user_id'] = cmf_get_current_admin_id();
            $data['group_id'] = 0;
            if ($data['applicable_type'] == 2) {
                // 选择员工的话,是员工名
                $userModel = new WeUserModel();
                $userList = $userModel->whereIn('userid',$data['applicable_range'])->column("userid","department_id");
                $group_arr = array_unique(array_keys($userList));
                $applicable_range['user_list'] = implode(",",$userList);
                $applicable_range['department_list'] = implode(",",$group_arr);
                $data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            } else {
                $userModel = new WeUserModel();
                $userList = $userModel->whereIn('department_id',$data['applicable_range'])->column("userid");
                $applicable_range['user_list'] = implode(",",$userList);
                $applicable_range['department_list'] = $data['applicable_range'];
                $data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            }
            if (!empty($data['semantics_list'])) {
                $data['semantics_list'] = implode(",",$data['semantics_list']);
            }

            // 敏感词接口新增
            $user_list = !empty($applicable_range['user_list']) ? explode(",",$applicable_range['user_list']) : [];
            $department_list = explode(",",$applicable_range['department_list']);
            $wx_intercept = array(
                'rule_name' => $data['rule_name'],
                'word_list' => explode(",",$data['word_list']),
                'semantics_list' => explode(",",$data['semantics_list']),
                'intercept_type' => $data['intercept_type'],
                'applicable_range' => array(
                    'user_list' =>  $user_list,
                    'department_list' => $department_list
                )
            );
            
            $wxinterceptApi = new WechatInterceptApi();
            $res = $wxinterceptApi->addInterceptRule($wx_intercept);
            if ($res['errcode'] != 0) {
                $this->error($res['errmsg'], url("Intercept/index"));
            }

            $data['rule_id'] = $res['rule_id'];
            $result = $interceptModel->save($data);
            if ($result) {
                $this->success('添加成功!', url("Intercept/index"));
            } else {
                $this->error('添加失败!', url("Intercept/index"));
            }
        }
        return $this->fetch();
    }

    // 编辑敏感词
    public function edit()
    {
        if ($this->request->isPost()) {
            $data = $this->request->param();
            $id = $data['id'] ?? 0;
            unset($data['id']);
            if ($data['applicable_type'] == 2) {
                // 选择员工的话,是员工名
                $userModel = new WeUserModel();
                $userList = $userModel->whereIn('userid',$data['applicable_range'])->column("userid","department_id");
                $group_arr = array_unique(array_keys($userList));
                $applicable_range['user_list'] = implode(",",$userList);
                $applicable_range['department_list'] = implode(",",$group_arr);
                $data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            } else {
                $userModel = new WeUserModel();
                $userList = $userModel->whereIn('department_id',$data['applicable_range'])->column("userid");
                $applicable_range['user_list'] = implode(",",$userList);
                $applicable_range['department_list'] = $data['applicable_range'];
                $data['applicable_range'] = json_encode($applicable_range,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            }
            
            $update_info = $data;
            $interceptModel = new InterceptModel();
            // 敏感词接口编辑
            // 查询原来的数据
            $rule_info = $interceptModel->field("rule_id,applicable_range")->where("id",$id)->find();

            $old_add_applicable_range = json_decode($rule_info['applicable_range'],true);
            $old_user_list = !empty($old_add_applicable_range['user_list']) ? explode(",",$old_add_applicable_range['user_list']) : [];
            $old_department_list = !empty($old_add_applicable_range['department_list']) ? explode(",",$old_add_applicable_range['department_list']) : [];
           
            $user_list = !empty($applicable_range['user_list']) ? explode(",",$applicable_range['user_list']) : [];
            $department_list = explode(",",$applicable_range['department_list']);
           
            $wx_intercept = array(
                'rule_id' => $rule_info['rule_id'],
                'rule_name' => $update_info['rule_name'],
                'word_list' => explode(",",$update_info['word_list']),
                'extra_rule' => array(
                    'semantics_list' => $data['semantics_list'],
                ),
                'intercept_type' => $data['intercept_type'],
                'add_applicable_range' => array(
                    'user_list' =>  $user_list,
                    'department_list' => $department_list
                ),
                'remove_applicable_range' => array(
                    'user_list' => $old_user_list,
                    'department_list' => $old_department_list
                )
            );
            
            $wxinterceptApi = new WechatInterceptApi();
            $res = $wxinterceptApi->updateInterceptRule($wx_intercept);
           
            if ($res['errcode'] != 0) {
                $this->error($res['errmsg'], url("Intercept/index"));
            }

            if (!empty($update_info['semantics_list'])) {
                $update_info['semantics_list'] = implode(",",$update_info['semantics_list']);
            }

            $result = $interceptModel->where("id",$id)->update($update_info);

            if ($result) {
                $this->success('编辑成功!', url("Intercept/index"));
            } else {
                $this->error('编辑失败!', url("Intercept/index"));
            }
        }
        $id = $this->request->param('id', 0, 'intval');
        if (empty($id)) {
            $this->error('请求参数有误!');
        }
        // 查询敏感词信息
        $interceptService = new InterceptService();
        $info = $interceptService->getInfo($id);
        // 接口请求敏感词详情
        // $wxinterceptApi = new WechatInterceptApi();
        // $list = $wxinterceptApi->getInterceptRuleInfo(['rule_id'=>$info['rule_id']]);
        // echo "<pre>";
        // print_r($list);
        // exit;
        $this->assign('info',$info);
        return $this->fetch();
    }

    // 删除敏感词
    public function delete()
    {
        $param = $this->request->param();
        $interceptModel = new InterceptModel();
        if (isset($param['id'])) {
            $id = $this->request->param('id', 0, 'intval');
            $rule_info = $interceptModel->field("rule_id")->where("id",$id)->find();
            $wxinterceptApi = new WechatInterceptApi();
            $wx_res = $wxinterceptApi->deleteInterceptRule(['rule_id'=>$rule_info['rule_id']]);
            if ($wx_res['errcode'] == 0) {
                $result = $interceptModel->where('id', $id)->delete();
                $this->success("删除成功!");
            } else {
                $this->error("删除失败!");
            }
        }
    }

    public function checkWorker()
    {
        $param = $this->request->param();
        $applicable_type = $param['type'] ?? 1;
        $applicable_range = $param['value'] ?? "";
        $interceptService = new InterceptService();
        $result = $interceptService->getWorkerList($param);
        $this->assign('menus', $result);
        $this->assign('applicable_range', explode(",",$applicable_range));
        $this->assign('applicable_type',$applicable_type);
        return $this->fetch();
    }

}

 InterceptService.php

<?php
// +----------------------------------------------------------------------
// xiaozhe
// +----------------------------------------------------------------------
namespace app\wework\service;

use app\wework\model\InterceptModel;
use app\wework\model\DepartModel;
use app\wework\model\WeUserModel;
use think\db\Query;

class InterceptService
{
    public function getList($filter)
    {
        $field = 'a.id,a.rule_name,a.word_list,a.intercept_type,a.applicable_type,a.user_id,a.create_time,a.update_time,u.user_nickname';
        $interceptModel = new InterceptModel();
        $result = $interceptModel
            ->alias("a")
            ->leftJoin("user u","a.user_id = u.id")
            ->field($field)
            ->where(function (Query $query) use ($filter) {
                $keyword = empty($filter['keyword']) ? '' : $filter['keyword'];
                if (!empty($keyword)) {
                    $query->where('a.title', 'like', "%$keyword%");
                }
            })
            ->paginate(15);
        return $result;
    }

    public function getInfo($id)
    {
        $interceptModel = new InterceptModel();
        $info = $interceptModel->where("id",$id)->find();
        if (!empty($info['semantics_list'])) {
            $info['semantics_list'] = explode(",",$info['semantics_list']);
        }
        if (!empty($info['applicable_range'])) {
            $info['applicable_range'] = json_decode($info['applicable_range'],true);
            $info['user_count'] = count(explode(",",$info['applicable_range']['user_list']));
            $info['depart_count'] = count(explode(",",$info['applicable_range']['department_list']));
            if ($info['applicable_type'] == 1) {
                // 部门
                $info['applicable_range_value'] = $info['applicable_range']['department_list'];
            } else {
                // 员工
                $userModel = new WeUserModel();
                $userIds = $userModel->whereIn("userid",$info['applicable_range']['user_list'])->whereIn("department_id",$info['applicable_range']['department_list'])->column("userid");
                $info['applicable_range_value'] = implode(",",$userIds);
            }
        }
        return $info;
    }

    public function getWorkerList($filter)
    {
        $type = $filter['type'];
        switch ($type) {
            case 1:
                // 部门
                $departmentModel = new DepartModel();
                $newList = $departmentModel->field("department_id as id,name,parentid as parent_id")->select()->toArray();
                break;
            case 2:
                // 员工
                $userModel = new WeUserModel();
                $newList = $userModel->field("userid as id,name")->select()->toArray();
                break;
            default:
                // code...
                break;
        }
        return $newList;
    }
    

}

WechatInterceptApi.php 

<?php 
// +----------------------------------------------------------------------
// | xiaozhe
// +----------------------------------------------------------------------
namespace app\wework\service;
use app\wework\model\ConfigModel;
use think\Db;
/**
* 企业微信接口
**/
class WechatInterceptApi 
{
    /**
    * 获取通讯录access_token
    **/
    public  function getStaffAccessToken(){
            $cache_key = 'staff_access_token';
            $res = cache($cache_key);
            if(empty($res)){
                // 读取配置
                $WeworkConfigModel = new ConfigModel();
                $info = $WeworkConfigModel->where("id",1)->find();
                $response = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$info['corpid']}&corpsecret={$info['user_secret']}");
                $arr = json_decode($response, true); 

                if($arr['errcode'] !== 0){
                    return '';
                }
                cache($cache_key, $arr['access_token'], 6900);
            }
            return $res;
    }
    /**
    * 获取客户联系人access_token
    **/
    static  public  function getCustomerAccessToken(){
            $cache_key = 'customer_access_token';
            $res = cache($cache_key);
            if(empty($res)){
                $WeworkConfigModel = new ConfigModel();
                $info = $WeworkConfigModel->where("id",1)->find();
                $response = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$info['corpid']}&corpsecret={$info['customer_secret']}");
                $arr = json_decode($response, true); 

                if($arr['errcode'] !== 0){
                    return '';
                }
                cache($cache_key, $arr['access_token'], 6900);
            }
            return $res;
    }
    /**
    * 获取自建应用 access_token
    **/
    public  function getSelfappAccessToken(){
                $cache_key = 'selfapp_access_token';
                $res = cache($cache_key);
                if(empty($res)){
                    $WeworkConfigModel = new ConfigModel();
                    $info = $WeworkConfigModel->where("id",1)->find();
                    
                    $response = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$info['corpid']}&corpsecret={$info['corpsecret']}");
                    $arr = json_decode($response, true); 
                   
                    if($arr['errcode'] !== 0){
                        return '';
                    }
                    cache($cache_key, $arr['access_token'], 6900);
                }
        return $res;
    }

    // 获取敏感词列表
    public function getInterceptRuleList()
    {
        $token = self::getSelfappAccessToken();
        $res = cmf_curl_get("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_intercept_rule_list?access_token=".$token,array());
        $resp_arr = json_decode($res, 1);
        return $resp_arr;
    }

    // 新增敏感词
    public function addInterceptRule($filter)
    {
        $token = self::getSelfappAccessToken();
        $res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_intercept_rule?access_token=".$token,
            json_encode($filter)
        );
        $resp_arr = json_decode($res, 1);
        return $resp_arr;
    }

    // 获取敏感词详情
    public function getInterceptRuleInfo($filter)
    {
        $token = self::getSelfappAccessToken();
        $res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_intercept_rule?access_token=".$token,
            json_encode($filter)
        );
        $resp_arr = json_decode($res, 1);
        return $resp_arr;
    }

    // 修改敏感词规则
    public function updateInterceptRule($filter)
    {
        $token = self::getSelfappAccessToken();
        $res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_intercept_rule?access_token=".$token,
            json_encode($filter)
        );
        $resp_arr = json_decode($res, 1);
        return $resp_arr;
    }

    // 删除敏感词
    public function deleteInterceptRule($filter)
    {
        $token = self::getSelfappAccessToken();
        $res = self::curl_post("https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_intercept_rule?access_token=".$token,
            json_encode($filter)
        );
        $resp_arr = json_decode($res, 1);
        return $resp_arr;
    }

   public function curl_post($url,$data){
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS,$data); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $result = curl_exec($curl); // 执行操作
        return $result;
    }
}

(前端代码我就不放了哈,自行写一哈) 

实现效果

敏感词列表

新增敏感词

 编辑敏感词

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/227091.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode:1365. 有多少小于当前数字的数字(python3解法)

难度&#xff1a;简单 给你一个数组 nums&#xff0c;对于其中每个元素 nums[i]&#xff0c;请你统计数组中比它小的所有数字的数目。 换而言之&#xff0c;对于每个 nums[i] 你必须计算出有效的 j 的数量&#xff0c;其中 j 满足 j ! i 且 nums[j] < nums[i] 。 以数组形式…

Android : XUI- SimpleImageBanner+BannerItem带标题的轮播图-简单应用

示例图&#xff1a; 1.导入XUI http://t.csdnimg.cn/qgGaN 2.MainActivity.java package com.example.viewpagerbanne;import android.os.Bundle; import android.view.View; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.xu…

步进电机驱动芯片TB6600HG部分翻译

有些参数没看懂。一边设计&#xff0c;一边修正。 目录 1.芯片梗概 2.引脚配置 1)引脚含义 2)内部逻辑 3.功能详解 1&#xff09;励磁模式设置 2&#xff09;功能设置 3&#xff09;初始模式 4&#xff09;100% 电流设置(电流值) 5&#xff09;OSC 6&#xff09;衰减…

Mac电脑统计分析绘图 GraphPad Prism 10 最新 for Mac

GraphPad Prism 10是一款强大的科学数据分析和可视化软件&#xff0c;提供了丰富的统计工具、数据可视化选项和报告生成功能。它使用户能够更轻松地分析和解释实验数据&#xff0c;以支持科学研究和决策。 数据导入和整理&#xff1a;GraphPad Prism 10支持从多种数据源导入数据…

CnetSDK .NET OCR Library SDK Crack

CnetSDK .NET OCR Library SDK Crack CnetSDK .NET OCR Library SDK 是一款高精度 .NET OCR 扫描仪软件&#xff0c;用于从图像中识别字符&#xff0c;如文本、手写和符号。该.NET OCR库软件采用Tesseract OCR引擎技术&#xff0c;将字符识别准确率提高高达99%。通过将 .NET OC…

demo(七) zuul请求过滤

在之前的基础上&#xff0c;实现请求过滤功能&#xff1a; 一、介绍&#xff1a; 1、背景&#xff1a;为实现对用户请求的安全校验和权限控制&#xff0c;用于对签名验证、权限校验的过滤器或拦截器。 2、实现方法&#xff1a;实现请求过滤只需继承ZuulFilter并重写方法&…

TCP数据粘包的处理

TCP数据粘包的处理 背锅侠TCP解决方案2.1 发送端2.2 接收端 背锅侠TCP 在前面介绍套接字通信的时候说到了TCP是传输层协议&#xff0c;它是一个面向连接的、安全的、流式传输协议。因为数据的传输是基于流的所以发送端和接收端每次处理的数据的量&#xff0c;处理数据的频率可…

QT Windos平台下打包应用程序

一、windeployqt.exe windeployqt&#xff1a;是 Qt 框架自带的一个工具&#xff0c;用于将一个 Qt 应用程序在 Windows 操作系统下进行打包。它可以通过扫描应用程序的依赖项获取所需的 Qt 库文件、插件和翻译文件&#xff0c;以及复制应用程序可执行文件和所需的依赖项到指定…

CentOS 7.9 安装 k8s(详细教程)

文章目录 安装步骤安装前准备事项安装docker准备环境安装kubelet、kubeadm、kubectl初始化master节点安装网络插件calicowork 加入集群 k8s集群测试 安装步骤 安装前准备事项 一台或多台机器&#xff0c;操作系统 CentOS7.x-86_x64硬件配置&#xff1a;2GB或更多RAM&#xff0…

cache教程1.LRU 缓存淘汰策略

这一节实现LRU算法&#xff0c;要理解明白其使用的数据结构。 FIFO/LFU/LRU 算法简介 Cache的缓存全部存储在内存中&#xff0c;内存是有限的&#xff0c;因此不可能无限制地添加数据。当占用内存超过了给定的内存大小时候&#xff0c;就需要从缓存中移除一条或多条数据了。我…

ARM day3

题目&#xff1a;实现3盏灯的流水 代码&#xff1a; .text .global _start _start: 设置RCC寄存器使能 LDR R0,0X50000A28 LDR R1,[R0] ORR R1,R1,#(0X1<<4) ORR R1,R1,#(0X1<<5) STR R1,[R0]设置PE10管脚为输出模式 LDR R0,0X50006000 LDR R1,[R0] BIC R1,R1,…

【动手学深度学习】(十)PyTorch 神经网络基础+GPU

文章目录 一、层和块1.自定义块2.顺序块3.在前向传播函数中执行代码 二、参数管理1.参数访问2.参数初始化3.参数绑定 三、自定义层1.不带参数的层2.带参数的层 四、读写文件1.加载和保存张量2.加载和保存模型参数五、使用GPU [相关总结]state_dict() 一、层和块 为了实现复杂神…

高精度时钟芯片SD2405

概要 SD2405是一款非常优秀的RTC解决方案&#xff0c;为了能让用户在Arduino上有一款方便易用的时钟模块。该模块是一款内置晶振&#xff0c;支持IIC串行接口的高精度时钟模块&#xff1b;内置一次性工业级电池&#xff0c;可保证外部掉电的情况下&#xff0c;可以继续工作5~8…

elk(filebeat)日志收集工具

elk&#xff08;filebeat&#xff09;日志收集工具 elk&#xff1a;filebeat日志收集工具 和logstash相同 filebeat是一个轻量级的日志收集工具&#xff0c;所使用的系统资源比logstash部署和启动时使用的资源要小得多 filebeat可以运行在非Java环境。他可以代理logstash在…

浅谈基于泛在电力物联网的综合能源管控平台设计及硬件选型

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;城区内一般都具有错综复杂的能源系统&#xff0c;且大部分能耗都集中于城区的各企、事业单位中。基于泛在电力物联网的综合能源管控平台将城区内从能源产生到能源消耗的整体流动情况采用大屏清晰展示&#xff…

单片机语言--C51语言数据类型与存储类型以及C51的基本运算

单片机语言——C51语言 文章目录 单片机语言——C51语言一、 C51与标准C的比较二、 C51语言中的数据类型与存储类型2.1、C51的扩展数据类型2.2、数据存储类型 三、 C51的基本运算3.1 算术运算符3.2 逻辑运算符3.3 关系运算符3.4 位运算3.5 指针和取地址运算符 一、 C51与标准C的…

深入浅出分析kafka客户端程序设计 ----- 生产者篇----万字总结

前面在深入理解kafka中提到的只是理论上的设计原理&#xff0c; 本篇讲得是基于c语言的kafka库的程序编写&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 首先要编写生产者的代码&#xff0c;得先知道生产者的逻辑在代码上是怎么体现的 1.kafka生产者的逻辑 …

Spark Structured Streaming使用教程

文章目录 1、输入数据源2、输出模式3、sink输出结果4、时间窗口4.1、时间窗口4.2、时间水印&#xff08;Watermarking&#xff09; 5、使用例子 Structured Streaming是一个基于Spark SQL引擎的可扩展和容错流处理引擎&#xff0c;Spark SQL引擎将负责增量和连续地运行它&#…

从主从复制到哨兵模式(含Redis.config配置模板)

文章目录 前言一、主从复制1.概述2.作用3.模拟实践搭建场景模拟实践 二、哨兵模式1.概述2.配置使用3.优缺点4.sentinel.conf完整配置 总结 前言 从主从复制到哨兵模式。 一、主从复制 1.概述 主从复制&#xff0c;是指将一台 Redis 服务器的数据&#xff0c;复制到其他的 Red…

Smart Link和Monitor Link

Smart Link和Monitor Link简介 Smart Link&#xff0c;又叫做备份链路。一个Smart Link由两个接口组成&#xff0c;其中一个接口作为另一个的备份。Smart Link常用于双上行组网&#xff0c;提供可靠高效的备份和快速的切换机制。 Monitor Link是一种接口联动方案&#xff0c;它…