先了解一下DHCP的工作原理
客户端广播dhcp发现,寻找dhcp服务器。
服务器为客户端提供一个ip地址
客户端检测是否存在冲突
客户端正式请求地址
服务器正式确认地址
如果存在多台dhcp服务器,那么每台服务器都会给客户端分配一个ip地址,但是客户端只接受其中一个,在正式请求地址阶段,客户端仍然采用广播,这样未被客户端接受的地址服务器就会分给其他客户端。
若是一个dhcp服务器的地址池已满,将不再提供地址,客户端只能收到地址池仍有空间的dhcp服务器提供的响应,因此使用该地址。不存在切换问题。
若是一个dhcp服务器故障,自然也就无法再发出响应,客户端会选择仍然有响应的dhcp服务器。也不存在切换问题。
唯一的问题在于,如果一台服务器发出一部分ip地址后发生故障,那么将无法响应客户端的地址续约,如果服务器没能在租约时间到期之前恢复,客户端将不得不重新开始申请地址,这可能造成客户端应用软件的短暂中断(游戏掉线什么的)。
微服务在最近几年大行其道,很多系统的研发都在考虑采用微服务架构,同时,随着 Docker 容器技术和DevOps开发运维一体化等相关技术发展,微服务变得更容易管理,这为微服务架构快速发展创造了有利条件。
在落地微服务的路上,拆分服务是个很热的话题。我们应该按照什么原则将现有的业务进行拆分?是否拆分得越细就越好?接下来一起聊聊服务拆分的策略和原则。
不忘初心方得始终。
在介绍如何拆分之前,我们需要了解下拆分的目的是什么,这样才不会在后续的拆分过程中忘了最初的目的。拆分的本质是 为了将复杂的问题简单化 ,那么我们在单体架构阶段遇到了哪些复杂性问题呢?
首先来回想下当初为什么选用了单体架构,在很多项目刚启动的时候,我们只希望能尽快地将项目搭建起来,方便将产品更早的投放市场进行快速验证。在开发初期,这种架构确实给开发和运维带来了很大的便捷,主要体现在:
但是随着功能越来越多,开发团队的规模越来越大,单体架构的缺陷慢慢体现出来,主要有以下几个方面:
产品初期,应该以单体架构优先。因为面对一个新的领域,对业务的理解很难在开始阶段就比较清晰,往往是经过一段时间之后,才能逐步稳定,如果拆分过早,导致边界拆分不合理或者拆的过细,反而会影响生产力。很多时候,从一个已有的单体架构中逐步划分服务,要比一开始就构建微服务简单得多。同时公司的产品并没有被市场验证过,有可能会失败,所以这个投入的风险也会比较高。另外,在资源受限的情况下,采用微服务架构很多优势无法体现,性能上的劣势反而会比较明显。如下图所示。当业务复杂度达到一定程度后,微服务架构消耗的成本才会体现优势,并不是所有的场景都适合采用微服务架构,服务的划分应逐步进行,持续演进。产品初期,业务复杂度不高的时候,应该尽量采用单体架构。
随着公司的商业模式逐渐得到验证,且产品获得了市场的认可,为了能加快产品的迭代效率快速占领市场,公司开始引进更多的开发同学,这时系统的复杂度会变得越来越高,就出现单体应用和团队规模之间出现矛盾,研发效率不升反降。上图中的交叉点表明,业务已经达到了一定的复杂度,单体应用已经无法满足业务增长的需求,研发效率开始下降,而这时就是需要考虑进行服务拆分的时机点。这个点需要架构师去权衡。当我们清楚了什么时候进行拆分,就可以直接落地了吗?不是的,微服务拆分的落地还要提前准备好配套的基础设施,如:服务接口设计(描述)、注册中心、微服务框架选型、服务监控、服务追踪、服务治理等几大基本组件,以上每个组件缺一不可,每个组件展开又包括很多技术,比如:持续集成、容器技术、持续部署、DevOps 等相关概念,以及人才的储备和观念的变化。 微服务不仅仅是技术的升级,更是开发方式、组织架构、开发观念的转变。
何时进行微服务的拆分,整体总结如下:
1 单一服务内部功能高内聚低耦合
也就是说每个服务只完成自己职责内的任务,对于不是自己职责的功能交给其它服务来完成。
2 闭包原则(CCP)
微服务的闭包原则就是当我们需要改变一个微服务的时候,所有依赖都在这个微服务的组件内,不需要修改其他微服务。
3 服务自治、接口隔离原则
尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这使得服务可以独立开发、测试、部署、运行,以服务为单位持续交付。
4 持续演进原则
在服务拆分的初期,你其实很难确定服务究竟要拆成什么样。从微服务这几个字来看,服务的粒度貌似应该足够小,但是服务多了也会带来问题,服务数量快速增长会带来架构复杂度急剧升高,开发、测试、运维等环节很难快速适应,会导致故障率大幅增加,可用性降低,非必要情况,应逐步划分,持续演进,避免服务数量的爆炸性增长,这等同于灰度发布的效果,先拿出几个不太重要的功能拆分出一个服务做试验,如果出现故障,则可以减少故障的影响范围。
5 拆分的过程尽量避免影响产品的日常功能迭代
也就是说要一边做产品功能迭代,一边完成服务化拆分。比如优先剥离比较独立的边界服务(如短信服务等),从非核心的服务出发减少拆分对现有业务的影响,也给团队一个练习、试错的机会。同时当两个服务存在依赖关系时优先拆分被依赖的服务。
6 服务接口的定义要具备可扩展性
服务拆分之后,由于服务是以独立进程的方式部署,所以服务之间通信就不再是进程内部的方法调用而是跨进程的网络通信了。在这种通信模型下服务接口的定义要具备可扩展性,否则在服务变更时会造成意想不到的错误。比如微服务的接口因为升级把之前的三个参数改成了四个,上线后导致调用方大量报错,推荐做法服务接口的参数类型最好是封装类,这样如果增加参数就不必变更接口的签名,而只需要在类中添加字段就可以了。
7 避免环形依赖与双向依赖
尽量不要有服务之间的环形依赖或双向依赖,原因是存在这种情况说明我们的功能边界没有化分清楚或者有通用的功能没有下沉下来。
8 阶段性合并
随着你对业务领域理解的逐渐深入或者业务本身逻辑发生了比较大的变化,亦或者之前的拆分没有考虑的很清楚,导致拆分后的服务边界变得越来越混乱,这时就要重新梳理领域边界,不断纠正拆分的合理性。
目前很多传统的单体应用再向微服务架构进行升级改造,如果拆分粒度太细会增加运维复杂度,粒度过大又起不到效果,那么改造过程中如何平衡拆分粒度呢?
弓箭原理
平衡拆分粒度可以从两方面进行权衡,一是业务发展的复杂度,二是团队规模的人数。如上图,它就像弓箭一样,只有当业务复杂度和团队人数足够大的时候,射出的服务拆分粒度这把剑才会飞的更远,发挥出最大的威力。比如说电商的商品服务,当我们把商品从大的单体里拆分出来的时候,就商品服务本身来讲,逻辑并没有足够复杂到 2~3 个人没法维护的地步,这时我们没有必要继续将商品服务拆的更细,但是随着业务的发展,商品的业务逻辑变的越来越复杂,可能同时服务公司的多个平台,此时你会发现商品服务本身面临的问题跟单体架构阶段面临的问题基本一样,这个阶段就需要我们将商品拆成更细粒度的服务,比如:库存服务、价格服务、类目服务、商品基础信息服务等等。虽然业务复杂度已经满足了,如果公司此时没有足够的人力(招聘不及时或员工异动比较多),服务最好也不要拆分,拆分会因为人力的不足导致更多的问题,如研发效率大幅下降(一个开发负责与其不匹配数量的服务)。这里引申另外一个问题,一个微服务究竟需要几个开发维护是比较理性的?
三个火q手原则
为什么说是三个人分配一个服务是比较理性的?而不是 4 个,也不是 2 个呢?首先,从系统规模来讲,3 个人负责开发一个系统,系统的复杂度刚好达到每个人都能全面理解整个系统,又能够进行分工的粒度;如果是 2 个人开发一个系统,系统的复杂度不够,开发人员可能觉得无法体现自己的技术实力;如果是 4 个甚至更多人开发一个系统,系统复杂度又会无法让开发人员对系统的细节都了解很深。其次,从团队管理来说,3 个人可以形成一个稳定的备份,即使 1 个人休假或者调配到其他系统,剩余 2 个人还可以支撑;如果是 2 个人,抽调 1 个后剩余的 1 个人压力很大;如果是 1 个人,这就是单点了,团队没有备份,某些情况下是很危险的,假如这个人休假了,系统出问题了怎么办?最后,从技术提升的角度来讲,3 个人的技术小组既能够形成有效的讨论,又能够快速达成一致意见;如果是 2 个人,可能会出现互相坚持自己的意见,或者 2 个人经验都不足导致设计缺陷;如果是 1 个人,由于没有人跟他进行技术讨论,很可能陷入思维盲区导致重大问题;如果是 4 个人或者更多,可能有的参与的人员并没有认真参与,只是完成任务而已。“三个火q手”的原则主要应用于微服务设计和开发阶段,如果微服务经过一段时间发展后已经比较稳定,处于维护期了,无须太多的开发,那么平均 1 个人维护 1 个微服务甚至几个微服务都可以。当然考虑到人员备份问题,每个微服务最好都安排 2 个人维护,每个人都可以维护多个微服务。
综上所诉,拆分粒度不是越细越好,粒度需要符合弓箭原理及三个火q手原则。
拆分策略可以按功能和非功能维度进行考虑,功能维度主要是:划分清楚业务的边界,非功能维度主要考虑六点包括:扩展性、复用性、高性能、高可用、安全性、异构性。接下来详细介绍下。
1 功能维度
功能维度主要是划分清楚业务边界,采用的主要设计方法可以利用 DDD(即领域驱动设计,关于 DDD 的理论知识可以参考网上其它资料),DDD 的战略设计会建立领域模型,可以通过领域模型指导微服务的拆分,主要分四步进行:
以电商的场景为例,交易链路划分的限界上下文如下图左半部分,根据一个限界上下文可以设计一个微服务,拆解出来的微服务如下图右侧部分。
2 非功能维度
当我们按照功能维度进行拆分后,并不是就万事大吉了,大部分场景下,我们还需要加入其它维度进一步拆分,才能最终解决单体架构带来的问题。
以上几种拆分方式不是多选一,而是可以根据实际情况自由排列组合。 同时拆分不仅仅是架构上的调整,也意味着要在组织结构上做出相应的适应性优化,以确保拆分后的服务由相对独立的团队负责维护。
古希腊哲学家赫拉克利特曾经说过:“人不能两次踏进同一条河流。”随着时间的流逝,任何事物的状态都会发生变化。线上系统同样如此,即使一个系统在不同时刻的状况也绝不会一模一样。现在拆分出来的服务粒度也许合适,但谁能保证这个粒度能够一直正确呢。
1 不打无准备之仗
开发团队是否具备足够的经验,能否驾驭微服务的技术栈,可能是第一个需要考虑的点。这里并不是要求团队必须具备完善的经验才能启动服务拆分,如果团队中有这方面的专家固然是最好的。如果没有,那可能就需要事先进行充分的技术论证和预演,至少不打无准备之仗。避免哪个简单就先拆哪个,哪个新业务要上了,先起一个服务再说。否则可能在一些分布式常见的问题上会踩坑,比如服务器资源不够、运维困难、服务之间调用混乱、调用重试、超时机制、分布式事务等等。
2 不断纠正
我们需要承认我们的认知是有限的,只能基于目前的业务状态和有限的对未来的预测来制定出一个 相对合适的拆分方案 ,而不是所谓的最优方案,任何方案都只能保证在当下提供了相对合适的粒度和划分原则,要时刻做好在未来的末一个时刻会变得不和时宜、需要再次调整的准备。因此随着业务的演进,需要我们重新审视服务的划分是否合理,如服务拆的太细,导致人员效率反而下降,故障的概率也大大增加,则需要重新划分好领域边界。
3 要做行动派,而不是理论派
在具体怎么拆分上,也不要太纠结于是否合适,不动手怎么知道合不合适呢?如果拆了之后发现真的不合适,在重新调整就好了。你可能会说,重新调整成本比较高。但实际上这个问题的本质是有没有针对服务化架构搭建起一套完成的能力体系,比如服务治理平台、数据迁移工具、数据双写等等,如果有的话,重新调整的成本是不会太高的。
2021年6月11日整理于去往大连的动车上,前方到站:盘锦。
一般用的就用简单的轮询就好了调度算法
静态方法:仅根据算法本身实现调度;实现起点公平,不管服务器当前处理多少请求,分配的数量一致
动态方法:根据算法及后端RS当前的负载状况实现调度;不管以前分了多少,只看分配的结果是不是公平
静态调度算法(static Schedu)(4种):
(1)rr (Round Robin) :轮叫,轮询
说明:轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。缺点:是不考虑每台服务器的处理能力。
(2)wrr (Weight Round Robin) :加权轮询(以权重之间的比例实现在各主机之间进行调度)
说明:由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,我们根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。
(3)sh (Source Hashing) : 源地址hash实现会话绑定sessionaffinity
说明:简单的说就是有将同一客户端的请求发给同一个real server,源地址散列调度算法正好与目标地址散列调度算法相反,它根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的并且没有超负荷,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法的相同。它的算法流程与目标地址散列调度算法的基本相似,除了将请求的目标IP地址换成请求的源IP地址。
(4)dh : (Destination Hashing) : 目标地址hash
说明:将同样的请求发送给同一个server,一般用于缓存服务器,简单的说,LB集群后面又加了一层,在LB与realserver之间加了一层缓存服务器,当一个客户端请求一个页面时,LB发给cache1,当第二个客户端请求同样的页面时,LB还是发给cache1,这就是我们所说的,将同样的请求发给同一个server,来提高缓存的命中率。目标地址散列调度算法也是针对目标IP地址的负载均衡,它是一种静态映射算法,通过一个散列(Hash)函数将一个目标IP地址映射到一台服务器。目标地址散列调度算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
动态调度算法(dynamic Schedu)(6种):
(1)lc (Least-Connection Scheduling): 最少连接
说明:最少连接调度算法是把新的连接请求分配到当前连接数最小的服务器,最小连接调度是一种动态调度短算法,它通过服务器当前所活跃的连接数来估计服务器的负载均衡,调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1,当连接中止或超时,其连接数减一,在系统实现时,我们也引入当服务器的权值为0时,表示该服务器不可用而不被调度。此算法忽略了服务器的性能问题,有的服务器性能好,有的服务器性能差,通过加权重来区分性能,所以有了下面算法wlc。
简单算法:active256+inactive (谁的小,挑谁)
(2)wlc (Weighted Least-Connection Scheduling):加权最少连接
加权最小连接调度算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权限,加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。由于服务器的性能不同,我们给性能相对好的服务器,加大权重,即会接收到更多的请求。
简单算法:(active256+inactive)/weight(谁的小,挑谁)
(3)sed (shortest expected delay scheduling):最少期望延迟
说明:不考虑非活动连接,谁的权重大,我们优先选择权重大的服务器来接收请求,但会出现问题,就是权重比较大的服务器会很忙,但权重相对较小的服务器很闲,甚至会接收不到请求,所以便有了下面的算法nq。
基于wlc算法,简单算法:(active+1)256/weight (谁的小选谁)
(4)nq (Never Queue Scheduling): 永不排队
说明:在上面我们说明了,由于某台服务器的权重较小,比较空闲,甚至接收不到请求,而权重大的服务器会很忙,所此算法是sed改进,就是说不管你的权重多大都会被分配到请求。简单说,无需队列,如果有台real server的连接数为0就直接分配过去,不需要在进行sed运算。
(5)LBLC(Locality-Based Least Connections) :基于局部性的最少连接
说明:基于局部性的最少连接算法是针对请求报文的目标IP地址的负载均衡调度,主要用于Cache集群系统,因为Cache集群中客户请求报文的目标IP地址是变化的,这里假设任何后端服务器都可以处理任何请求,算法的设计目标在服务器的负载基本平衡的情况下,将相同的目标IP地址的请求调度到同一个台服务器,来提高服务器的访问局部性和主存Cache命中率,从而调整整个集群系统的处理能力。
(6)LBLCR(Locality-Based Least Connections with Replication) :基于局部性的带复制功能的最少连接
说明:基于局部性的带复制功能的最少连接调度算法也是针对目标IP地址的负载均衡,该算法根据请求的目标IP地址找出该目标IP地 址对应的服务器组,按“最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接”原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除, 以降低复制的程度。坑:奥山40人战场,开场之后全场只有不到20个人,这种情况就可以叫坑。坑的意思就是指开了局的战场,也就是新场的反义词。
挖坑:国家队排到一个场,但是这个场已经有20人左右(非国家队队员,也就是所谓的野人),这个时候国家队的队员最多进去20人,这个时候国家队一般都选择不进,这个时候国家队20多人一起丢掉队列就会造成这个战场一下子多出了20多个位置,一般来说玩家单排是没有这么快就可以进满这个战场,所以造成了这个战场开局认输还是不满,这就是国家队所说的挖坑。
填坑:国家队无论喊排还是团排,都一样是40+人一起排战场,这样根据服务器分配原则就很有可能多数人分在一个场里,而一个战场要同时容纳这么多人一般只有新场,所以国家队这种排法一般都能排到新场,但是也不排除有可能排到旧场(开了局的场或者队员很少人排到这个场),这个时候你进去就算是填坑,因为这是一个没满人的场或者说开了局没满人的场。
坑是指地下的一个凹下去的地方,也就是没有填满的地方,所以用坑比喻没有满的战场。而用土(填坑的东西)比喻玩家,你进这个战场也就是你去填这个坑。
这个够明白了吧?呵呵,给我分吧
你好,很高兴回您的问题。
您说的要求,拆开来看,估计指的就是网服务器响应速度和安全性吧!
我结合自己做的网站和小程序来聊一聊:
我是搞了一台老马家的阿L云服务器,下载了DZ自行安装,后来又装了小程序插件。因为我的站点访问量不大(每天300IP左右),所以买了2核4G2M性能突发型的(后台其实现在可能改成无性能约束模式,只要一天重负载时间不长是不用额外收费的),新人买3年不到2000,打开网站和小程序,还是比较流畅的,感觉目前是够用的。
我的基本情况了解了,再来聊聊网服务器响应速度和安全性。
响应速度
其实响应速度又跟服务器硬件配置、带宽、和客户网络有关。
硬件配置:我上面说到的2核4G,就是我这台服务器分配2个核心和4G内存,核越多,内存越大,运算速度越快,跟我们平时使用的电脑是一样的。带宽:我上面说到的2M,就是给我这台服务器分配的带宽,网络带宽是指在单位时间(一般指的是1秒钟)内能传输的数据量。网络和高速公路类似,带宽越大,就类似高速公路的车道越多,其通行能力越强。客户网络:同样访问一个网站,用移动,电信、联通网络,或者地域不同,访问速度也有差异。安全性
一般独立服务器,安全这块是要自己配置的;一般来说,云主机安全性要比独立的物理服务器好多了,云服务器自带的防火墙或者杀毒软件。目前国家比较大的,T讯,阿L,天L,H为,个人觉得还是阿L稍好,省心一点。
至于服务器选择这块,本着物尽其用,够用就好的原则,根据自己用户访问量来做出选择。新开站初期,访问量不大,服务器性可以用那么强大。购入之前想想这几个问题:
1服务器运行什么应用?
2需要支持多少用户访问?
3需要多大空间来存储数据?
我的业务有多重要至于性能问题,我们认为需要评估用户数量才能决定。
如果不经过实际需求的评估,轻率的选择一台性能强劲、价格昂贵的服务器,无疑是会带来成本上的浪费。
总之,基本就是这样了,不知道我说明白了没有。
我是老段,一个40多岁还有做自媒体的老大叔,有关于电子,电脑,机床,数控,网络,自媒体方面的都可以问我,一起交流学习。
大哥,分配ip不是系统说了算,是DHCP服务器说了算,根据服务器分配规则,ip超时之前会自动续期,超时后才会重新向DHCP服务器申请IP,计算机5min后发送release报文释放IP,再重新申请时,DHCP服务器根据分配规则,发现该申请终端有ip申请记录,如果之前分配的ip还未被使用,则会分配之前该终端使用过的ip,如果已被使用,才会在ip地址池找是否有可用IP,有则分配,没有则发送一个分配失败的回复报文。具体可以看看DHCP的工作原理及地址分配原则。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)