精华内容
下载资源
问答
  • 图上的return出现在,通知各个客户端有人下线的代码中,表达啥意思。麻烦指教 谢谢谢谢![图片](https://img-ask.csdn.net/upload/201709/24/1506239798_205372.jpg)![图片]...
  • 前几天,老板微信找到我,上来就开门见山的告诉了我出了什么问题,大概意思就是:我们测试服务器又挂了,你怎么管理的服务器,测试服务器经常挂掉很影响公司形象的。。。(PS:求老板看到这段话别怼我 o(╥﹏╥)o ) ...

    欢迎访问我的博客https://www.marxcbr.cn/

    缘起

    前几天,老板微信找到我,上来就开门见山的告诉了我出了什么问题,大概意思就是:我们测试服务器又挂了,你怎么管理的服务器,测试服务器经常挂掉很影响公司形象的。。。(PS:求老板看到这段话别怼我
    o(╥﹏╥)o )

    但是鉴于前几天时间不多,便简单的处理了一下服务器的网络服务便下线了。因为上次服务挂掉的时候是因为服务器的测试网站被删了,所以便知道了服务器已经沦陷,被人家随意蹂躏了。花了一些时间处理好测试网站后就下线了,没有花时间分析入侵者以及他在咱们服务器里面干了什么。
    时间来到昨天,腾出了一个晚上。想着公司的测试服务器是时候要好好地排查一下安全问题已经分析一下入侵者的行径和他在里面干了什么了。
    话不多说,马上登录过去看看。

     

     

    在登录页面,可以看到左下角那几个猖獗的账号,入侵了别人服务器,不好好隐藏一下自己,还公然show出自己的用户名,实在太流批了。

     

     

    进入主机后,下了个D盾简单的扫了一下用户目录。果然有点东西的,在root$这个账号下有菜刀用的马。估计是传了一个小马进来然后再菜刀上大马搞的服务器。然后再另外一个用户下面呈现独占模式,所以,应该他这个账号还没注销。

     

     

    看看进程列表果然有很多这个用户下启动的软件,包括了他的游戏私服以及聊天机器人在内的软件进程。
    接着到终端下面看一下什么时候连进去的。

     

     

    居然昨天下午5点还连进去过。太叼了吧。然后我便到控制台创建一个快照,以备后续取证的时候需要证据的时候用到,然后我就把它账号给注销了。顺带把他的进程也给清掉了。

    找出他是谁

    在进程里面找到了他机器人是由“酷Q air”提供服务的,进入他的聊天机器人文件夹里面,打开一下他的机器人。看到了一个账号,数了一下,10位数,大概猜测是QQ号。

     



    重复登录一下看看,果然验证了我的猜测。

     

     



    接着便尝试到QQ中找一下这个账号,了解一下情况。

     

     

     

    使用小号访问他的空间看看

     



    可以很直观的看出这个只是一个小号。能挖掘的信息不多。然后便放弃了这个信息,准备挖其他信息。
    回到服务器上面。看到他其中的一个用户名qq11xxxxx24

     

     

     

    所以没猜错的话,这个应该也是他的QQ号。OK,还是用小号尝试找找看他的信息。

     

     

    emmm,“咸鱼王”的头像壁纸跟小号的都是“我的世界”的壁纸。所以基本可以确定两个账号为同一个人所有。
    而且他的所在地是“河南 郑州”,是真的在河南吗?
    接着到QQ空间看看情况怎么样。

     

     

    发现他昨天早上还发了一条说说,定位地点就是郑州市某学院。喜欢玩“我的世界””王者荣耀“,刚打上砖石,让他感觉好嗨哟,感觉人生已经到达了高潮~~~
    后续多条说说均定位于郑州市某学院,后面有一条定位点是郑州市亚太明珠,时间是,2月21,以及上一两条信息都是在那个地方,再联系上他是专科学生,2月21前大概率是寒假时间。基本可以推断出,这个地方就是他的家所在地区了。

     

     

    在多条说说中的定位可以看到他的定位点是某汽车工厂,联合他的学历,可以猜测到那个地方是他的实习工作地点了。
    但是直到现在,我们还是不知道他叫什么。。。
    所以,我又回到了服务器,看一下还能不能挖出点信息。
    回到服务器,找到他大号对应的账号的文件夹里面。到roaming这个缓存数据文件夹里面找了找东西,无意中发现了百度云盘?为啥有百度云盘?
    难道他文档里面那些私服文件都是百度云盘下载的?

     



    打开百度云盘看一下,他居然点了记住密码。。。
    顺利进入里面,看了一下传输列表,果然文件都是百度云盘下的。

     

     

     

    但是这些东西对我来说没用呀。等等,百度云盘的账号一般有两种,一种是邮箱型,另外一种是手机号码型。
    他会不会是手机号码型的呢?
    点击切换账号后,结果另人十分欣喜。

     

     

    拿到手机号了,就肯定要打开某付宝啦。看看这个兄弟的大宝名。

     

     

    xx钰,嗯,让我猜猜他姓啥。赵、钱、孙、陈、张…………都不对。。。
    这可咋办哟,正当我一筹莫展的时候,隔壁的朋友说:你不是有他空间了么,到空间里面看啊,肯定有他名字出现的,比如他生日什么的时候,就会有人留言说出他的名字的。
    诶,这可太机智了,我就知道QQ空间里面,能挖的信息不止那么一点点的。
    随即又来到他的空间,Ctrl+F,一搜“x钰”,再翻多几个页面。就出现了。

     

     

    看得出他很在乎他妹妹,都出宣战书了。(谁还没个年少轻狂的时候呢)


    这个时候已经基本可以拿到他的所有信息了。包括了,姓名、手机号、所在地区、所在学校、实习地点以及游戏爱好。顺便提一嘴,肖像其实在QQ空间里面也挖出来了。

    后续,今早添加他为好友后,进入到了他的私服群。因为昨晚服务器已经被我处理过了,所以,他今早就用不了。
    给大家看一段截图。大家乐呵乐呵就好。

     

     

    非法使用别人服务器被清理后还说服务器被盗了,我从未见过如此厚颜无耻之人!

     

    总结

        大家可以很明显的看到在QQ空间里面由于不注意保护隐私安全、任意一个人通过其QQ空间稍微总结观察一下便可以获取到大量信息。而且,上文中的那位老哥明显已经触犯《中华人民共和国网络安全法》了。各位观众老爷,研究信息安全的同学们,来跟我背一遍社会主义核心价值观!

     

    undefineduploading.4e448015.gif转存失败重新上传取消

     


    推荐阅读:
    VMware Workstation 安装以及Linux虚拟机安装 指北
    软件更新服务之服务端搭建
    搜索引擎的那些小技巧
    QQ音乐MP3文件下载

    本文对你有没帮助呀,喜欢的话,记得留言、点赞、转发哟。谢谢各位!

    undefineduploading.4e448015.gif转存失败重新上传取消

    欢迎扫码关注我的微信公众号:叙之亭

    展开全文
  • 解决方案总是为了解决某一问题,出现问题才会想着找解决方案,某天公司后端的一个服务下线,当大家都认为这个服务没有用的时候,偏偏就发生问题了,本以为一个正常的操作而导致一个大事故,为了防止此种问题再出现,...

    【使用场景】

    【解决方案】

     

    1、拨测

    发现问题解决问题是体现一个员工能力最有力的证明,为什么会提到自动化拨测呢?解决方案总是为了解决某一问题,出现问题才会想着找解决方案,某天公司后端的一个服务下线,当大家都认为这个服务没有用的时候,偏偏就发生问题了,本以为一个正常的操作而导致一个大事故,为了防止此种问题再出现,经过各方讨论,想到拨测方案。那拨测是什么意思呢?简单说就是用脚本的形式不断循环探测服务的正常,实时监控系统,及时告警。听起来感觉很有帮助。那跟自动化又有啥关系呢?

    接口自动化对于测试同学应该不会很陌生了,基本所有公司都会涉及到,是目前自动化测试最有效的实施方式,用语言模拟接口的调用,断言响应报文,以判断接口功能的正确性。到这里大家应该可以想到接下来如何和拨测联系在一起了,就是用循环调用接口自动化的方式,反复的来验证接口。想想感觉还是可以的

    2、解决方案

    接口自动化怎么实现,最常见的实现方式可能是Jmeter+ant+jenkins,postman,execl+python等等,最简单的那一定是直接用python+requests,话不多说直接上代码

    import requests, json,datetime,time
    
    url = 'https://***********'
    
    
    def api_test(api, body):
        api_url = url + api
        print(api_url)
        header = {'token': 'f7100db396fa344cb44ed3092e97e7e766d107a3', 'klzz_ol_home_uid': '219057934',
                  'time': '1605696563', 'Content-Type': 'application/json; charset=utf-8'}
        body = {'page': '1 ', 'catePid': '36'}
        res = requests.post(api_url, data=body, headers=header)
        print(res.status_code)
        print(res.text)
        try:
            assert res.status_code == 200
            # message = "{0}请求成功{1}".format(api_url,res.status_code)
            # dingding_tall_success(message)
        except AssertionError:
            dingding_tall(res.status_code)
    
    def dingding_tall(status_code):
        header = {'Content-Type': 'application/json; charset=utf-8'}
        url = 'https://oapi.dingtalk.com/robot/send?access_token=df47dbbacc16568adc6abab1ce0e4760762c40d007f1c3b31ee4ae5726291764'
        msg = "监控报警消息" + str(status_code) + "错误"
        body = {"msgtype": "text", "text": {"content": msg}}
        body = json.dumps(body)
        res = requests.post(url, data=body, headers=header)
        print(res.text)
    
    
    api_dictionary = {'Center_vlue': '/***/Center',
                      'List_vlue': '/***/List'}
    body_dictionary = {'Center_body': "{'page':'1 ','catePid':'36'}",
                       'List_body': "{'userId':22348277,'year':2020,month':'9'}"}
    api = ['test1', 'test2']
    
    
    
    if __name__ == '__main__':
    
        now = datetime.datetime.now()
    
        sched_timer = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute,
                                        now.second) + datetime.timedelta(seconds=5)
        flag = 0
        while (True):
                now = datetime.datetime.now()
                if sched_timer < now < sched_timer + datetime.timedelta(seconds=1):
                    time.sleep(1)
                    print(now)
                    # 运行程序
                    for api_key in api:
                        print(api_key)
                        api_test(api_dictionary[str(api_key) + '_vlue'], body_dictionary[str(api_key) + '_body'])
                    flag = 1
                else:
                    if flag == 1:
                        # 修改定时任务时间 时间间隔为?分钟
                        sched_timer = sched_timer + datetime.timedelta(seconds=10)
                        flag = 0
    

     

    展开全文
  • 前段时间在做WCF开发的过程中,用户需要在服务端对客户端进行监控,需要知道客户端什么时候上线,什么时候下线,当然服务端也可以给客户端推送信息,就是所谓的双向通信了。 要双向通信用我以前的HTTP协议是行不通...

    仅供参考:未经允许,不得转载。

             前段时间在做WCF开发的过程中,用户需要在服务端对客户端进行监控,需要知道客户端什么时候上线,什么时候下线,当然服务端也可以给客户端推送信息,就是所谓的双向通信了。

            要双向通信用我以前的HTTP协议是行不通了,问了一下别人,别人说了一个“心跳更新”这个概念,想必大家都懂这个吧,大概意思呢就是A向B定时发送一个消息来监测B是否活着,如果活着就返回一个消息,死掉当然就不需要了,其实我觉得心跳更新就是TCP协议,也就是双向通信,互相监测活着或者死掉。

            行了,废话不多说了,先让大家看下效果:

    客户端:

     客户端没有多少内容,就是引用一下服务端服务(WCF服务),并调用服务的方法。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ServiceModel;
    
    
    namespace WinTestTcp
    {
        public partial class ClientFrm : Form,MessageService.IMessageServiceCallback
        {
            private MessageService.MessageServiceClient mService = null;
            public ClientFrm()
            {
                InitializeComponent();
            }
    
    
            /// <summary>
            /// 窗体加载事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ClientFrm_Load(object sender, EventArgs e)
            {
                InstanceContext context = new InstanceContext(this);
                mService = new MessageService.MessageServiceClient(context);
                mService.Register();
            }
            /// <summary>
            /// 收到服务器消息
            /// </summary>
            /// <param name="message"></param>
            public void SendMessage(string message)
            {
                SetDisplayMessage("服务器:"+message);
            }
    
    
            /// <summary>
            /// 设置显示消息
            /// </summary>
            private void SetDisplayMessage(string message)
            {
                if (this.rtxtResult.InvokeRequired)
                {
                    this.rtxtResult.BeginInvoke(new MethodInvoker(delegate
                    {
                        SetDisplayMessage(message);
                    }));
                }
                else{
                    this.rtxtResult.Text += string.Format("{0}\r\n{1}\r\n",message,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                }
            }
    
    
            /// <summary>
            /// 发送事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnSend_Click(object sender, EventArgs e)
            {
                mService.ClientSendMessage(this.textBox1.Text);
                SetDisplayMessage("我说:"+this.textBox1.Text);
                this.textBox1.Text = "";
            }
        }   
    }

    代码注释很明显,我就不作解释了,如果还有看不懂可以留言。。。。

    服务端:

     WcfServiceLibraryDemo是一个WCF服务,行了创建的时候只需要把名字改一下,里面的东西不用动就OK了。

    WinWcf是Winform,先引用上面的WCF服务,个人不喜欢直接在WCF服务里面直接写服务,在这下面就新建WCF服务需要的两个类IMessageService.cs和MessageService.cs。里面有两个窗体,TcpFrm是带服务端广播的,MainFrm是不带广播的,根据个人需求只需在Program中设置启动就可以了。

    具体看下面:

    MessageService代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace WinWcf
    {
        /// <summary>
        ///  实例使用Single,共享一个
        ///  并发使用Mutiple, 支持多线程访问(一定要加锁)
        /// </summary>
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]//必须要加这句话
        public class MessageService:IMessageService
        {
            /// <summary>
            /// 客户端注册
            /// </summary>
            public void Register()
            {
                ICallBackServices client = OperationContext.Current.GetCallbackChannel<ICallBackServices>();
                string sessionid = OperationContext.Current.SessionId;//获取当前机器Sessionid--------------------------如果多个客户端在同一台机器,就使用此信息。
                string ClientHostName = OperationContext.Current.Channel.RemoteAddress.Uri.Host;//获取当前机器名称-----多个客户端不在同一台机器上,就使用此信息。
                TcpFrm.GetInstance().SetDisplayMessage(string.Format("客户端上线:\r\n{0}\r\n{1}",  sessionid, ClientHostName));
                TcpFrm.GetInstance().ListClient.Add(client);
                OperationContext.Current.Channel.Closed+=new EventHandler(Channel_Closed);
                TcpFrm.GetInstance().SetClientNum();
            }
    
    
            /// <summary>
            /// 客户端发送消息
            /// </summary>
            /// <param name="message"></param>
            public void ClientSendMessage(string message)
            {
                ICallBackServices client = OperationContext.Current.GetCallbackChannel<ICallBackServices>();
                string sessionid = OperationContext.Current.SessionId;//获取当前机器Sessionid--------------------------如果多个客户端在同一台机器,就使用此信息。
                string ClientHostName = OperationContext.Current.Channel.RemoteAddress.Uri.Host;//获取当前机器名称-----多个客户端不在同一台机器上,就使用此信息。
                TcpFrm.GetInstance().SetDisplayMessage(string.Format("客户端:{0}\r\n{1}\r\n{2}",message,sessionid,ClientHostName));
                client.SendMessage("你好,我是服务器");
            }
    
    
            /// <summary>
            /// 客户端关闭事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Channel_Closed(object sender, EventArgs e)
            {
                ICallBackServices client = sender as ICallBackServices;
                TcpFrm.GetInstance().ListClient.Remove(client);
                TcpFrm.GetInstance().SetClientNum();
            }
        }
    }

    IMessageService代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    namespace WinWcf
    {
        [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBackServices))]
        public interface IMessageService
        {
            /// <summary>
            /// 客户端注册上线
            /// </summary>
            /// <param name="message"></param>
            [OperationContract(IsOneWay = true)]
            void Register();
    
    
            /// <summary>
            /// 客户端发送消息
            /// </summary>
            /// <param name="message">消息内容</param>
            [OperationContract(IsOneWay=true)]
            void ClientSendMessage(string message);
        }
    
        public interface ICallBackServices
        {
            /// <summary>
            /// 服务像客户端发送信息(异步)
            /// </summary>
            /// <param name="Message"></param>
            [OperationContract(IsOneWay = true)]
            void SendMessage(string message);
        }
    }

    以上两个就是WCF服务了。

    TcpFrm代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.Net;
    
    namespace WinWcf
    {
        public partial class TcpFrm : Form
        {
            private bool isServerRun = true;
            private int ServerPort = 9900;
            private static TcpFrm instance = null;
            public List<ICallBackServices> ListClient = new List<ICallBackServices>();
    
    
            /// <summary>
            /// 获取单例
            /// </summary>
            /// <returns></returns>
            public static TcpFrm GetInstance()
            {
                if (instance == null)
                {
                    instance = new TcpFrm();
                }
                return instance;
            }
    
    
            private TcpFrm()
            {
                InitializeComponent();
            }
            /// <summary>
            ///  wcf 宿主服务线程
            /// </summary>
            /// <summary>
            /// 启动wcf服务
            /// </summary>
            private void StartServer()
            {
                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    try
                    {
                        isServerRun = true;
                        //获取本机IP
                        string ip = GetIP();
                        string tcpaddress = string.Format("net.tcp://{0}:{1}/", ip, ServerPort);
                        //定义服务主机
                        ServiceHost host = new ServiceHost(typeof(MessageService), new Uri(tcpaddress));
                        //设置netTCP协议
                        NetTcpBinding tcpBinding = new NetTcpBinding();
                        tcpBinding.MaxBufferPoolSize = 2147483647;
                        tcpBinding.MaxReceivedMessageSize = 2147483647;
                        tcpBinding.MaxBufferSize = 2147483647;
                        //提供安全传输
                        tcpBinding.Security.Mode = SecurityMode.None;
                        //需要提供证书
                        tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
                        //添加多个服务终结点
                        //使用指定的协定、绑定和终结点地址将服务终结点添加到承载服务中
                        //netTcp协议终结点
                        host.AddServiceEndpoint(typeof(IMessageService), tcpBinding, tcpaddress);
    
    
                        #region 添加行为
                        //元数据发布行为
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        //支持get请求
                        behavior.HttpGetEnabled = false;
                       
                        //设置到Host中
                        host.Description.Behaviors.Add(behavior);
                        #endregion
    /这部分其实就是config配置文件。我不过是把它写在了代码里面,看大家的习惯了,个人感觉这样他有助于理解里面的字段
    
                        //设置数据交换类型
                        host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
                        //启动服务
                        host.Open();
                        SetDisplayMessage(string.Format("服务启动成功,正在运行...\r\n{0}", tcpaddress));
                    }
                    catch (Exception ex)
                    {
                        SetDisplayMessage("服务启动失败");
                        MessageBox.Show(ex.Message, "服务启动失败,请检测配置中IP地址");
                        Environment.Exit(0);
                    }
                });
            }
    
    
            /// <summary>
            /// 获取本机IP地址
            /// </summary>
            /// <returns></returns>
            public string GetIP()
            {
                string name = Dns.GetHostName();
                IPHostEntry me = Dns.GetHostEntry(name);
                IPAddress[] ips = me.AddressList;
                foreach (IPAddress ip in ips)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        return ip.ToString();
                    }
                }
                return (ips != null && ips.Length > 0 ? ips[0] : new IPAddress(0x0)).ToString();
            }
    
    
            /// <summary>
            /// 设置运行内容
            /// </summary>
            /// <param name="msg"></param>
            public void SetDisplayMessage(string msg)
            {
                //在线程里以安全方式调用控件
                if (this.rtxtMsg.InvokeRequired)
                {
                    rtxtMsg.BeginInvoke(new MethodInvoker(delegate
                    {
                        SetDisplayMessage(msg);
                    }));
                }
                else
                {
                    if (rtxtMsg.Lines.Length >= 200)
                    {
                        rtxtMsg.Text = "";
                    }
                    rtxtMsg.AppendText(string.Format("{0}\r\n{1}\r\n\r\n", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                    rtxtMsg.SelectionStart = rtxtMsg.Text.Length;
                    rtxtMsg.ScrollToCaret();
                }
            }
            /// <summary>
            /// 窗体刚加载事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void MainFrm_Load(object sender, EventArgs e)
            {
                StartServer();//开启WCF服务
                SetClientNum();
            }
    
    
            /// <summary>
            /// 设置在线客户端数量
            /// </summary>
            public void SetClientNum()
            {
                if (this.InvokeRequired)
                {
                    this.BeginInvoke(new MethodInvoker(delegate{
                        SetClientNum(); 
                    }));
                }
                else
                {
                    this.Text=string.Format("服务已启动,当前客户端数量{0}",ListClient.Count);
                }
            }
    
    
            /// <summary>
            /// 广播事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnSend_Click(object sender, EventArgs e)
            {
                string message = this.txtMessage.Text;
                foreach (ICallBackServices icbs in ListClient)
                {
                    icbs.SendMessage(message);
                }
            }
        }
    }

           大概说一下过程吧,客户端打开后会调用服务端的Register(),服务端监控把客户端上线的信息显示出来,客户端点击发送后会调用服务端的ClientSendMessage(),并向服务端发送消息,服务端收到后显示出来,服务端做到了实时监控,并广播给客户端发送信息,将消息显示在客户端,大概流程就是这样,代码很容易理解。

           我们不管是用windows还是Android调用WCF服务,都可以做到实时监控,服务端知道客户端什么时候上线或者下线,客户端可以知道服务端此时是不是卡死或者活着,其实我的项目要求有一部分就是需要服务端可客户端的状态实时监控并保存到数据库,并定期给客户端推送消息,至于下线相信大家看了这个demo应该自己会加,我就不多说了。

            最后附上源代码,只要环境ok就能跑通,理解了原理,可以使用任何版本。如果有问题的可以留言,小弟上线后第一时间会回答。

    Demo源码

    展开全文
  • 就是监视某区域的士兵,这里的哨兵模式就是这个意思什么是哨兵?哨兵(Sentinel)就是一个独立的进程,多个Sentinel实例组成Sentinel集群。哨兵(Sentinel)通过发送命令,等待服务器响应,以此来监视多个redis...

    首先明确一点,哨兵模式就是为了弥补主从复制中,当主机挂掉之后,需要重新手动选择主机的缺点而提出的方案。哨兵模式可以自动选取主机。

    啥是哨兵?就是监视某区域的士兵,这里的哨兵模式就是这个意思,什么是哨兵?哨兵(Sentinel)就是一个独立的进程,多个Sentinel实例组成Sentinel集群。哨兵(Sentinel)通过发送命令,等待服务器响应,以此来监视多个redis实例,被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

    在这里插入图片描述
    简单点说,有点像打仗时候的侦查兵,连长挂掉了,排长顶上,排长挂掉了班长顶上

    哨兵模式的主要功能

    • 集群监控,监控master和slave进程是否正常工作
    • 消息通知,如果redis实例出现故障,哨兵Sentinel进程负责报警
    • 故障转移,master挂掉,slave选举上岗
    • 配置中心,如果故障转移出现,通知client客户端新的master

    如何实现哨兵模式

    新建sentinel.conf

    输入

    sentinel monitor host6379 127.0.0.1 6379 1
    

    启动哨兵模式

    [root@localhost bin]# redis-sentinel /myredis/sentinel.conf 
    

    启动成功
    在这里插入图片描述
    此时挂掉6379,等待一段时间之后,发现6381成为主机
    在这里插入图片描述
    6381set数据
    在这里插入图片描述
    6380可以获取到数据
    在这里插入图片描述
    等6379恢复之后,成为从机
    在这里插入图片描述
    然后观察sentinel日志,发现选举失败一次,然后选举了6381
    `

    复制的缺点

    由于所有写操作都是先在master上操作,然后同步更新到slave上,所以从master同步到slave机器上有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,slave机器数量的增加也会使这个问题更加严重

    实际java项目中应用

    第一步,配置主从,由于主从复制中,配从不配主,故只修改从主机的配置文件即可

    # 指定主服务器,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
    slaveof 192.168.25.139 6379
    # 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
    masterauth 123456
    

    第二步,修改sentinel.conf

    protected-mode no
    # 配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,1代表只有一个或一个以上的哨兵认为主服务器不可用的时候(可以改为2),才会进行failover操作。
    sentinel monitor mymaster 192.168.25.139 6379 1
    

    然后启动主机和从机,最后启动哨兵服务即可

    启动顺序

    首先是主机(192.168.25.139)的Redis服务进程,然后启动从机的服务进程,最后启动3个哨兵的服务进程。

    第三步,编写java代码,使用jedis为例

    /**
     * 测试Redis哨兵模式
     * @author jie
     */
    public class TestSentinel {
        @SuppressWarnings("resource")
        @Test
        public void testSentinel() {
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxTotal(10);
            jedisPoolConfig.setMaxIdle(5);
            jedisPoolConfig.setMinIdle(5);
            // 哨兵信息
            Set<String> sentinels = new HashSet<>(Arrays.asList("192.168.25.139:6379",
                    "192.168.25.139:6379","192.168.25.139:6379"));
            // 创建连接池
            JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig);
            // 获取客户端
            Jedis jedis = pool.getResource();
            // 执行两个命令
            jedis.set("k1", "v1");
            String value = jedis.get("k1");
            System.out.println(value);
        }
    }
    
    展开全文
  • UDS入门

    2020-06-05 11:26:48
    它还可以用来进行汽车的下线检测,汽车下线时把VIN码、软硬件版本号、生产日期等信息写入汽车中的各个零部件中(ECU),以及一些其他的功能等等。 二、为什么要做UDS? 有人可能会问了,如果是要实现上面的那些...
  • 这个和我们计算机貌似没有什么关系。我们这里说的Cookies是指服务器在暂存在计算机上的一段资料。  2.Session 按照英文单词翻译过来是“会话”的意思。存在于服务器的内存中。  限制用户登录的一下场景 1。比如QQ...
  • 8、重复消费 没启用,也没测试过这个重复消费是什么意思 10、分润工资 这个就相当于每个月发固定工资,这个是按级别来的,在财务里有这个 11、有内部商城,可提供完整的购买和发货流程(不支持在线支付和快递发货的...

空空如也

空空如也

1 2 3
收藏数 43
精华内容 17
关键字:

服务下线什么意思