EMQX 在 Kubernetes 中如何进行优雅升级

背景

为了降低 EMQX 在 Kubernetes 上的部署、运维成本,我们将一些日常运维能力进行总结、抽象并整合到代码中,以 EMQX Kubernetes Operator 的方式帮助用户实现 EMQX 的自动化部署和运维。

此前,EMQX Kubernetes Operator v1beta1、v1beta2、v1beta3 的升级策略均为滚动升级,相关升级流程如下:

问题分析

滚动升级在生产环境中可能会面临以下问题:

  1. 升级过程中会逐个销毁旧的节点再创建新的节点,因此可能导致客户端多次断连(最糟糕的情况下断连次数与节点数量一致),从而影响用户体验。
  2. 当集群处于较高连接的情况下,一个节点被销毁,那么该节点上面的连接会在瞬间断开,由客户端重试逻辑来进行重连;当单节点连接数较大时,如果大量客户端进行重连,则可能会给服务端造成压力导致过载。
  3. 升级完成后,各节点间的负载不均衡(如上图:emqx-ee-0 在升级过程中,客户端可能会进行重连,此时由于 emqx-ee-0 还未就绪,因此可能连接到 emqx-ee-1 或者 emqx-ee-2,升级完成后 emqx-ee-0 上可能只有较少负载或者无负载),从而打破业务容量模型的规划,可能影响到服务。
  4. 由于使用 StatefulSets 进行部署,在升级过程中提供服务的节点会比实际节点要少一个(影响到用户的业务模型),这可能会增加服务端的一些压力。

如果上面几个步骤的问题叠加(多次断连与大量断连的客户端不停的重试连接),则可能会放大客户端重连的规模,从而造成服务端过载或雪崩。

下图是在现有升级模式下连接数的监控图(在不同的业务中会存在差异,比如后端依赖的不同资源、服务器配置、客户端重连或重试策略等,均会带来一些不同的影响)。其中:

  • sum:总的连接数,图中最上面的一条线
  • emqx-ee-a:前缀表示的是升级前 3 个 EMQX 节点
  • emqx-ee-b:前缀表示的是升级后 3 个 EMQX 节点

在上图中,当我们开始执行滚动升级时,首先 emqx-ee-a-emqx-ee-2 进行销毁,并创建新的 emqx-ee-b-emqx-ee-2,此时仅有 emqx-ee-a-emqx-ee-1、emqx-ee-a-emqx-ee-0 能够提供服务,当客户端进行重连时,LB 会将流量转移到 emqx-ee-a-emqx-ee-0、emqx-ee-a-emqx-ee-1 上面,因此我们能够看到 emqx-ee-a-emqx-ee-1、emqx-ee-a-emqx-ee-0 有明显的流量上升,当后面更新这两个 pod 时,意味着客户端可能多次断连。由于新 pod 建立的过程存在着时间差,以上图为例,emqx-ee-a-emqx-ee-0 最后升级,当升级完成后,可能客户端已经完成重试、重连,此时主要连接已经被另两个 pod 接纳,因此会导致 pod 之间流量不均衡,从而影响到用户业务模型的评估,或者影响到服务。

为了方便展示,我们未压测大量连接模拟重连、导致服务端过载的场景(在实际生产环境中可能遇到,TPS 超过云端规划的容量模型),但从连接数监控图上,我们依然看到一个大缺口,说明对业务产生了较大影响。因此我们需制定一种方案来规避以上几个问题,保障升级过程中的平滑稳定。

问题解决

目标

  1. 升级过程中实现连接数可控迁移(可根据服务端处理能力设置相应的迁移速率)。
  2. 升级过程中减少连接断开的次数(一次断连)。
  3. 在整个升级的过程中始终保持预期的节点来提供服务。
  4. 升级完成后,不需要集群负载重平衡,各节点间的连接相对均衡(与 LB 调度策略有一定关系)。

方案设计

蓝绿发布是一种同时运行两个版本应用的发布策略。EMQX Kubernetes Operator 近日在 2.1.0 版本中实现了 EMQX Enterprise 的蓝绿发布,即从现有的 EMQX Enterprise 集群开始,创建一套新版本的 EMQX Enterprise 集群,在这一过程中不停止掉老版本,等新版本集群运行起来后,再将流量逐步平滑切换到新版本上。

从 4.4.12 版本开始,EMQX 企业版本支持节点疏散功能。节点疏散功能允许用户在关闭节点之前强制将连接和会话以一定速率迁移到其他节点,以避免节点关闭带来的会话数据丢失。

关于节点疏散更多信息请参考相关文档

在 Kubernetes 上我们通过模拟蓝绿发布以及结合节点疏散功能,实现了连接可控迁移,极大减少了断连的次数(仅断连一次)。相关升级流程图如下:

整个升级流程大致可分为以下几步:

  1. 升级时(镜像、Pod 相关资源修改调整)我们会先创建一个同规格的节点加入到现有集群中。
  2. 当新节点全部就绪后,我们将 service 全部指向新创建的节点,此时新节点开始接受新的连接请求。
  3. 将旧节点从 service 中摘出,此时旧节点不再接收新的连接请求。
  4. 通过 EMQX 节点疏散功能,逐个对节点上的连接进行可控迁移,直至连接全部完成迁移,再对节点进行销毁。

操作流程

节点疏散是 EMQX Enterprise 4.4.12 开始支持的新特性,EMQX Kubernetes Operator 在 2.1 版本中对该能力进行适配,如需使用该能力,请将 EMQX 升级到企业版 v4.4.12,EMQX Kubernetes Operator 升级到 v2.1。

  • 配置蓝绿升级
apiVersion: apps.emqx.io/v1beta4
...
spec:
   blueGreenUpdate:
    initialDelaySeconds: 60
    evacuationStrategy:
      waitTakeover: 5
      connEvictRate: 200
      sessEvictRate: 200
...

initialDelaySeconds :所有的节点就绪后(蓝绿节点),开始节点疏散前的等待时间 (由于切换 Service 后,LoadBalancer 需要时间来处理 service 与 pod 的关系)(单位:秒)

waitTakeover :所有连接断开后,等待客户端重连以接管会话的时间(单位:秒)

connEvictRate :客户端每秒断开连接速度

sessEvictRatewaitTakeover 之后每秒会话疏散速度

详情可参考:Operator 文档

升级过程中连接数监控图如下(本次测试以 10 万连接进行):

sum:总的连接数,图中最上面的一条线

emqx-ee-86d7758868:前缀表示的是升级前的 3 个 EMQX 节点

emqx-ee-745858464d:前缀表示升级后的 3 个 EMQX 节点

如上图,我们通过 EMQX Kubernetes Operator 的蓝绿发布在 Kubernetes 中实现了优雅升级,通过该方案升级,总连接数未出现较大抖动(取决于迁移速率、服务端能够接收的速率、客户端重连策略等),能够极大程度保障升级过程的平滑,有效防止服务端过载,减少业务感知,从而提升服务的稳定性。

注:由于升级后的集群,三个节点负载较平均,因此上图三条线重叠在了一起。

结语

通过采用节点疏散功能结合模拟蓝绿发布,本文所提供的方案解决了普通升级导致的多次断连和可能的服务过载与负载不均问题,实现了在 Kubernetes 上优雅的升级。

作为一个自动化管理工具,EMQX Kubernetes Operator 旨在帮助用户轻松创建和管理 EMQX 集群,充分享受 EMQX 的强大产品能力。通过本文方案完成 EMQX 的升级,用户可以进一步体验 EMQX 的最新特性,构建创新物联网应用。

版权声明: 本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.com/zh/blog/how-to-upgrade-emqx-in-kubernetes?utm_source=cloud.tencent.com&utm_medium=referral

本文转载于网络 如有侵权请联系删除

相关文章

  • 盛名之下,其实难副?两篇ICML杰出论文受质疑,作者亲自回应了

    机器之心报道编辑:张倩、蛋酱可能存在缺陷的论文拿了奖,到底是谁的问题?前两天,机器学习顶会ICML公布了2022年的论文获奖情况,包括15篇杰出论文奖和1项时间检验奖。其中,复旦大学、上海交通大学、厦门大学、莱斯大学胡侠团队等多个华人团队的研究获得杰出论文奖。ICML2012关于「投毒攻击」的论文《PoisoningAttacksagainstSupportVectorMachines》获得了大会的时间检验奖。一次性评选出15篇杰出论文,这个不同于寻常的做法引起了研究者们的关注。与此同时,部分获奖论文的内容也在推特上引起了强烈的争议。论文1:BayesianModelSelection,theMarginalLikelihood,andGeneralization引起争议的第一篇论文是纽约大学的研究《BayesianModelSelection,theMarginalLikelihood,andGeneralization》。论文地址:https://proceedings.mlr.press/v162/lotfi22a/lotfi22a.pdf这篇论文首先回顾了学习约束和假设检验的边

  • 如何打造高性能的 Go 缓存库

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/531 文中代码位置:https://github.com/devYun/mycache我在看一些优秀的开源库的时候看到一个有意思的缓存库fastcache,在它的介绍主要有以下几点特点:读写数据要快,即使在并发下;即使在数GB的缓存中,也要保持很好的性能,以及尽可能减少GC次数;设计尽可能简单;本文会通过模仿它写一个简单的缓存库,从而研究其内核是如何实现这样的目标的。希望各位能有所收获。设计思想在项目中,我们经常会用到Go缓存库比如说patrickmn/go-cache库。但很多缓存库其实都是用一个简单的Map来存放数据,这些库在使用的时候,当并发低,数据量少的时候是没有问题的,但是在数据量比较大并发比较高的时候会延长GC时间,增加内存分配次数。比如,我们使用一个简单的例子:funcmain(){ a:=make(map[string]string,1e9) fori:=0;i<10;i++{ runtime.GC() } runtime

  • SD模块基础教程(十五):分配装运点给工厂

    作者:Happy 声明:本文章仅用于SAP软件的应用与学习,不代表SAP公司。(注:文中所示截图来源SAP软件,相应著作权归SAP所有。)前言:根据SAP顾问圈内初步统计,市场上的FICO和MM顾问居多,相对最少的应该是SD模块的顾问,这个跟市场上不同企业所处的行业、业务等因素决定。原则上,不管是哪个模块只要用心学习,并真正掌握且能够在项目中锻炼后“出炉”,我想也一定会拥有美好的前景和未来。在SAP各业务模块中,个人觉得MMSD是适众性最强的,也是相对容易学习的两个模块。其中,SD模块相对于MM模块则更加简单点,本系列我们就介绍下SD(SalesandDistribution)模块,中文一般称为销售与分销模块。该模块主要涉及销售、询价、报价、销售订单、交运和开具发票等内容。“万丈高楼平地起”,任何事物都需要一个过程,不断坚持,量变一定会产生质变。务必把基础打牢,在学习的过程中要关注下与其它业务如MM、PP、FICO等模块的集成与业务交叉,也能帮助我们更好、更全面地掌握SD模块知识。本章内容:一、分配装运点给工厂(附高清操作视频)二、SD模块知识体系介绍(完结篇)前几章介绍了SAP系统中

  • js和object的常见操作,持续更新中...

    PS:⚠️不是返回值,是提醒注意事项,除⚠️符号之外的均为返回值将string类型的数组,进行格式化为object类型的数组letstr="[{'env':'测试','problem':'允许','protocol':'TCP','source_port':'修改的数据源数据','purpose':'修改的数据','source_ip':'修改的数据源数据','dest_port':'修改的数据源数据','partner':'修改的数据源数据','dest_ip':'修改的数据源数据','id':0}]" console.info(eval(str)) //返回值 [ { env:'

  • 事件_窗体传值(使用系统自带的委托)

    本实验的目的:利用系统自带的EventHandler委托。模仿.netFrame系统的委托是如何实现功能的;Form1的代码:usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; usingSystem.Windows.Forms; namespace事件_窗体传值_用系统自带委托_ { publicpartialclassForm1:Form { publicForm1() { InitializeComponent(); } publiceventEventHandlerevt;//1、首先在这里声明一个系统委托的字段; privatevoidbutton1_Click(objectsender,EventArgse) { //显示窗体2 Form2f2=newForm2(); thi

  • 设计模式学习 - 策略模式

    学习、梳理设计模式。策略模式由策略接口、多个具体的策略实现、上下文组成。由客户端来选择具体的策略实现。一个背景,CRM系统内有多种帐号体系:手机号注册的客户、微信授权的客户、微博授权的客户。 一个场景,需要把这些不同帐号体系的ID转换为CRM系统内部的统一UserId。策略接口及实现策略接口publicinterfaceUserStrategy{ longtransform2UserId(Stringorigin); }复制手机号客户实现publicclassMobileUserStrategyimplementsUserStrategy{ @Override publiclongtransform2UserId(Stringorigin){ return1L; } }复制微信客户实现publicclassOpenIdUserStrategyimplementsUserStrategy{ @Override publiclongtransform2UserId(Stringorigin){ return3L; } }复制微博客户实现publicclassWeiBoIdUse

  • Nebula:Slack 的覆盖全球性的开源网络

    Nebula是Slack开发的高安全性与性能的网络服务,这可以为Slack的用户提供可靠的安全隔离,谁也不希望和同事讨论的内容被他人窃取。感谢学而思网校架构师刘连响对本文所做的技术审校。文/RyanHuber译/AdrianNg技术审校/刘连响原文https://slack.engineering/introducing-nebula-the-open-source-global-overlay-network-from-slack-884110a5579如何安全的连接分布在全球多个地区的多个云服务商的成千上万台机器?我们的答案是-Nebula,你想知道为什么吗?在Slack,我们几年前已在研究这问题。我们尝试了许多方法来解决这个问题,但每种方法都在性能、安全性、特性或易用性方面艰难的权衡。我们很乐意在以后的演讲和写作中分享整这些经历,但是之前我们并没想过着手编写软件来解决这个问题。Slack的营业范围是为了促进人类关系而不是计算机。什么是Nebula?Nebula是一个专注于性能、简单性和安全,可扩展的网络覆盖工具。它可以让你无缝连接全世界每个角落、任何地方的计算机。Nebula是便

  • Vue中使用CSS预处理器 stylus以及配置全局变量的方法

    前言不得不说CSS预处理器(Sass/Less/Stylus)极大的方便了前端研发攻城狮编写CSS样式,提供了变量定义、可嵌套的选择器、mixins混合书写、函数定义等诸多便捷的能力。今天呢,胡哥就以stylus在vue中的使用为例,为大家分享css预处理器的基本使用方式,以及全局变量的定义和便捷使用方式。三种CSS预处理器在vue中的使用原理是相同的,希望大家能触类旁通…一、stylus的基本使用下载安装stylus、stylus-loader包 npmistylusstylus-loader-Dwebpack中的配置(可选) //配置文件build/webpack.base.conf.js--对应vue-cli生成的项目 module:{ rules:[ //配置stylus { test:/.styl$/, loader:'style-loader!css-loader!stylus-loader' } ] } 其实在vue-cli生成的vue2.0的项目中,此处的webpack可以不再进行配置,vue会自动检测如果使用了stylus语法,会自动调用stylu

  • C++函数模版与重载的区别

    C++函数模版与重载的区别微信公众号:杨源鑫 如果你觉得本文对你有帮助,欢迎留言探讨!首先,先来看一个例子:#include<iostream>usingnamespacestd;//C++函数模版两种定义方式//template<typenameT>或template<classT> template<typenameT1>T1check_max(T1x,T1y); template<classT>Tprint_value(Tx,Ty); //C++重载intadd(intx,inty);intadd(intx,inty,intz);stringadd(stringstr,stringstr1,stringstr2); intmain(void){intx=33;inty=44;longl1=333,l2=444;floatf1=3.14,f2=3.15926; //系统会自动识别类型T1为int类型cout<<"max(x,y)="<<check_max(x,y)<&l

  • Groovy-17.命令行

    Groovy的shell被称为groovysh,可以评估groovy的表达式,定义类,运行简单的程序。Groovy提供的命令行选项:命令行参数全名描述-C--color[=FLAG]启用或禁用使用ANSI颜色-D--define=NAME=VALUE定义系统属性-T--terminal=TYPE指定要使用的终端TYPE-V--version显示版本-classpath指定在哪里找到类文件-必须是第一个参数-cp--classpath别名“-classpath”-d--debug启用调试输出-e--evaluate=arg启动交互式会话时,评估选项指标-H--help显示此帮助消息-q--quiet禁止多余的输出-v--verbose启用详细输出命令命令命令说明:help(:h)显示此帮助消息?(:?)别名为::帮助:exit(:x)退出shell:quit(:q)别名为::exitimport(:i)将一个类导入命名空间:display(:d)显示当前缓冲区:clear(:c)清除缓冲区并复位提示计数器:show(:S)显示变量,类或导入:inspect(:n)使用GUI对象浏览器检查

  • 【震撼】谷歌发布全球首个72量子比特通用量子计算机,量子霸权威慑IBM、微软

    研究科学家MarissaGiustina在圣芭芭拉谷歌量子AI实验室安装Bristlecone芯片。来源:GoogleQuantumAILab新智元报道来源:GoogleBlog,Nature等 作者:闻菲,小潘【新智元导读】谷歌今天宣布推出一款72个量子比特的最新量子计算机Bristlecone,实现了1%的低错误率,与9个量子比特的量子计算机持平。谷歌认为使用Bristlecone可以实现量子霸权。上周IBM才曝光了其50个量子比特量子原型机内部构造。谷歌在量子比特位数和错误率上的亮眼表现,霎时将2018年的量子霸权竞赛赛点提前,接下来就看微软传言中的里程碑表现。 今天,谷歌量子AI实验室研究科学家JulianKelly在GoogleResearch官博发文,介绍了经过同行评议的,谷歌的最新72位量子比特量子计算机。“我们刚开始测试,”Google的物理学家JohnMartinis说:“从目前我们所知道的情况来看,我们非常乐观。”Martinis说,如果一切运作良好,量子霸权可能会在几个月内实现。Kelly介绍说,谷歌量子AI实验室(GoogleQuantumAILab)的目标是构

  • 好的程序员做不出好的软件设计

      你不能看到一个程序员还不错,就把他推到系统分析师、软件设计师或软件架构师的位置上。  如果你在团队或公司里寻找一个能胜任软件架构师或设计师这样重要位置的人时,首先出现在脑子里的想法通常是在程序员中选一个最好的。别这么干。这样的位置不是随意的找个不错的程序员就能胜任的。把你最资深的程序员晋升到这个位置也未必就合适。  乍一听你可能感觉荒诞。为什么我不能让一个程序员去做系统设计呢?毕竟,他们是设计程序的,不是吗?的确是的,没错。但你要明白的事情是,设计软件相对于编写程序,它需要的是一套完全不同的技能。  让我们来看看为什么一个好的程序员就未必可以做一个好的软件设计师。但首先,让我们来问问自己一个问题,是什么让一个程序员变的优秀,甚至杰出?要想成为一个好的程序员,你需要有能力实现真实世界里重要的软件。只能够写出一个简单的文本编辑器是远远不够的。  为了能做到可以解决重大的、复杂的编程问题,一个程序员需要在某个特点的编程语言上进行数年的经验积累。也就是说,为了能熟练的使用这种语言、熟悉这种语言的各种特色,他必须专注于这种语言。问题就在这儿。对于只有锤子的人,他能解决的问题就是钉钉子  如果

  • postman如何安装_xiaopanos图文使用教程

    大家好,又见面了,我是你们的朋友全栈君。 为了验证接口能否被正常访问,我们常常需要使用测试工具,来对数据接口进行检测。 好处:接口测试工具能让我们在不写任何代码的情况下,对接口进行调用和调试。 下载并安装PostMan首先,下载并安装PostMan,请访问PostMan的官方下载网址:https://www.getpostman.com/downloads/ 下载所需的安装程序后,直接安装即可使用PostMan测试GET接口步骤:(一)选择请求的方式(二)写请求的URL地址(三)填写请求的参数(四)点击Send按钮发起GET请求(五)查看服务器响应的结果使用PostMan测试POST接口步骤: 1、选择请求的方式 2、填写请求的URL地址 3、选择Body面板并勾选数据格式 4、填写要发送到服务器的数据 5、点击Send按钮发起POST请求 6、查看服务器响应的结果唯一不同的地方是第三步:选择Body面板并勾选数据格式,其余步骤相同注册登录步骤步骤:1、如果原先没有账号需要点击右上角的注册按钮CreateAccount,有账号则直接点击登录按钮SignIn2、注册账号点击之后进入的界面

  • 图像边缘检测

    不想复习的AbNer前来水一篇文章 图像边缘检测 边缘检测原理   图像边缘指的是图像中像素灰度值突然发生变化的区,如对像素灰度值曲线求取一阶导数可以得到导数曲线(废话文学),曲线最大值所在区域就是图像中的边缘所在区域,而图像是离散的信号,我们可以用邻近的两个像素的插值来表示像素灰度值函数的导数,即求导方式为:

  • (转载)HTTP简介

    转载:https://www.cnblogs.com/ranyonsue/p/5984001.html   HTTP简介 HTTP协议是HyperTextTransferProtocol(超文本传输协议)的缩写,是用于从万维网(WWW:WorldWideWeb)服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据(HTML文件,图片文件,查询结果等)。 HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(NextGenerationofHTTP)的建议已经提出。 HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。 http请求-响应模型.jpg 主要特点 1、简单快速:客户向服务器请求服务时,只需

  • 杂技

    11.22BaselProblem 考虑多项式\(f(x)=\sum_{i=0}^na_ix^i\),其所有复根记为\(x_i(1\lei\len)\),则\(x_i^{-1}\)是方程\(\sum_{i=0}^na_{n-i}y^i=0\)的根,容易求出\(\sumx_i^{-2}=a_1^2-2a_2\);假定上述结论对于无限幂级数也成立,则考察 \[F(z)=\dfrac{\sin\piz}{z}=\pi-\dfrac{\pi^2}6z^2+\cdots \]其在\(\mathbb{C}\)上的根为\(\mathbb{Z}-\{0\}\),从而\(2\zeta(2)=a_1^2-2a_2\Rightarrow\zeta(2)=\dfrac{\pi^2}6\). 11.07构造函数 二阶可导函数\(f\),\(f(1)=0\),\(f''\)有界,证明存在一点\(\xi\)使得:$$\xif''(\xi)+(2+\xi)f'(\xi)+f(\xi)=0$$ 构造\(g(x)=xf(x)\),根据罗尔定理知\(\existsx_0\in(0,1),x_0f'(x_0)+f(x_

  • 单调栈

    目录503.下一个更大元素II思路代码单调栈单调栈简介找到元素向左遍历第一个比它小的元素84.柱状图中最大的矩形找到元素向左遍历第一个比它大的元素42.接雨水 503.下一个更大元素II 思路 可以使用单调栈解决本题。 单调栈中保存的是下标,从栈底到栈顶的下标在数组nums中对应的值是单调不升的。 每次我们移动到数组中的一个新的位置i,我们就将当前单调栈中所有对应值小于nums[i]的下标弹出单调栈,这些值的下一个更大元素即为nums[i]。 注意到只遍历一次序列是不够的,例如遍历序列[2,3,1]后元素[1]的下一个更大元素还是不知道。我们可以把这个循环数组「拉直」(处理时对下标取模),即复制该序列的前n−1个元素拼接在原序列的后面,将这个新序列当作普通序列继续处理。 代码 classSolution{ publicint[]nextGreaterElements(int[]nums){ intn=nums.length; int[]ret=newint[n]; Arrays.fill(ret,-1); Deque<Integer>stack=newLinkedList

  • 洛谷 P1345 [USACO5.4]奶牛的电信Telecowmunication

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相连,a2与a3相连,等等,那么电脑a1和a(c)就可以互发电邮。 很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。 有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。 以如下网络为例: 1* /3-2* 这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。 输入输出格式 输入格式:   第一行四个由空格分隔的整数:N,M,c1,c2.N是电脑总数(1<=N<=100),电脑由1到N编号。M是电脑之间连接的总数(1<=M<=600)。最后的两个整数c1和c2是上述两头奶牛使用的电脑编号。连接没有重复且均为双

  • 转载 ARP/RARP

    版权声明:欢迎转载,请注明出处。https://blog.csdn.net/jxch____/article/details/78875873 不管网络层使用的是什么协议,在实际网络的链路上传送数据帧时,最终还是必须使用硬件地址。每一个主机都设有一个ARP高速缓存(ARPcache),里面有所在的局域网上的各主机和路由器的IP地址到硬件地址的映射表。当主机A欲向本局域网上的某个主机B发送IP数据报时,就先在其ARP高速缓存中查看有无主机B的IP地址。如有,就可查出其对应的硬件地址,再将此硬件地址写入MAC帧,然后通过局域网将该MAC帧发往此硬件地址。   ARP高速缓存的作用:为了减少网络上的通信量,主机A在发送其ARP请求分组时,就将自己的IP地址到硬件地址的映射写入ARP请求分组。当主机B收到A的ARP请求分组时,就将主机A的这一地址映射写入主机B自己的ARP高速缓存中。这对主机B以后向A发送数据报时就更方便了。 应当注意:ARP是解决同一个局域网上的主机或路由器的IP地址和硬件地址的映射问题。如果所要找的主机和源主机不在同一个局域网上,那么就要通过ARP找到一个位于本局

  • Netty的核心组件Bootrap=》 ServerBootstrap=》Future=》ChannelFuture=》 Channel=》 Selector =》 ChannelHandle=》 pipeline和ChannelPipeline =》ChannelHandleContext=》 EventLoopGroup和其实现类=》 NioEventLoopGroup及其实现类

    1.BootstrapServerBootstrap 1)Bootstrap意思是引导, 一个Netty通常由一个Bootstrap开始,主要作用是配置整个Netty程序,串联各个组件。Netty中Bootstrap类是客户端启动引导类,ServerBootstrap是服务器端启动引导类。 2)常见的方法有 publicServerBootstrapgroup(EventLoopGroupparentGroup,EventLoopGroupchildGroup),该方法用于服务器端,用来设置两个EventLoop publicBgroup(EventLoopGroupgroup),该方法用于客户端,用来设置一个EventLoop public<T>Bchannel(Class<?extendsC>channelClass),该方法用来设置一个服务器端的通道实现 public<T>Boption(ChannelOption<T>option,Tvalue),用来给ServerChannel添加配置 public<T>

  • Python中的垃圾回收与del语句

    python中的垃圾回收采用计数算法 一个对象如果被引用N次,则需要N次(即计算引用次数为零时)执行del才能回收此对象。 a=100 b=a dela print(b) print(a) 100 NameError:name'a'isnotdefined复制 在函数和类中如果传递参数的时候,很有可能参数会做一些改变,一下为一个经典的坑:      defadd(a,b): a+=b returna a=[1,2] b=[3,4] c=add(a,b) print(b) print(a) print(c) [3,4] [1,2,3,4] [1,2,3,4] 在传递为可变对象list时候,函数内部可以对全局变量引用并改变。但是如果传递参数为不可变对象时,原参数就不会发生改变。 classCompany(): def__init__(self,name,staffs=[]): self.name=name self.staffs=staffs defadd(self,staff_name): self.staffs.append(staff_name) defremove(se

相关推荐

推荐阅读