关于微服务跟高并发的一些东西
微服务微服务的意义例如我们在开发一个基础的商场系统时,可能分为 用户模块、商品模块、订单模块、活动模块 等,系统建设初期,我们也许为了快速上线和节约成本,那么就会采用直接把一整套的模块代码,全部写在一个项目代码中。 而在后期流量上来后,我们会发现,经常因为某个模块的的功能模块失效,导致整个服务瘫痪。例如 活动模块 和 商品模块 是最容易在高流量下瘫痪的模块。 举个例子,在 2018 年的双十一活动
微服务
微服务的意义
例如我们在开发一个基础的商场系统时,可能分为 用户模块、商品模块、订单模块、活动模块 等,系统建设初期,我们也许为了快速上线和节约成本,那么就会采用直接把一整套的模块代码,全部写在一个项目代码中。 而在后期流量上来后,我们会发现,经常因为某个模块的的功能模块失效,导致整个服务瘫痪。例如 活动模块 和 商品模块 是最容易在高流量下瘫痪的模块。 举个例子,在 2018 年的双十一活动中,某商场系统花了很多钱去做广告,导致很高流量直接进入到商场系统当中,而在此之前,也没做服务拆分,那么 活动模块 的高流量导致 数据库 和 带宽 完全无法支撑,最终整个商场系统全部进入黑洞状态,用户既无法进入活动页面,就连正常的商场首页也无法打开。 后面,在 EasySwoole 项目组 的建议下,将商场系统进行了 模块化服务拆分,例如,活动系统 就是一个独立的服务,用户参与活动的时候,直接从客户端调用活动服务接口,活动服务需要验证商品和用户数据的时候,又通过 RPC 调用 进行服务间的数据交互。 从而实现压力的分摊,不再让全部的服务压力都堆积到 单台服务器 或 数据库 上,且在最糟糕的情况下,即使活动模块瘫痪,也不会导致整个商场系统不可用。
因此微服务的主要意义在于:流量分压、模块高度自治、服务隔离保护。
(引用网上)
什么是微服务框架
实际上,所谓的 微服务框架,是一种错误的说法,微服务是一种架构性上的概念,与框架无关。例如,在上述的案例当中,我们服务间的互相调用,可以用 HTTP 协议 或者是 原生 TCP 协议 来实现,因此实际上,微服务和框架没有一点关系。而如果真的要牵强地说是微服务框架的话,那其实无非是类似某些框架做了一些组件的封装,让你更加方便的实现 RPC 调用。不管什么框架只是提供了 RPC 封装、基础的服务发现 和 注册中心。但是实际上,这仅仅是工具,真正的微服务,最核心的其实是 如何做好服务间的最小粒度切分,其实这个 服务切分 是属于架构规划上的范畴。
微服务的缺陷
实际业务中,我们的应用服务是可以实现线性水平拓容的,不管是使用的是哪种语言哪个框架,对于纯应用类(即无数据操作)服务器cpu 升高可以直接通过负载均衡添加机器就可以提高并发,但是对于数据集群,我们是没有办法获得线性拓容的效果的,原因很简单因为数据集群多了后数据的一致性就没法保证了,所以微服务的难点就在于数据的拆分,我们希望通过微服务获得更好的性能,一般来说应用的性能瓶颈都在数据库层,所以拆分应用的根本目的可以说是拆分数据库(当然也有纯计算的微服务),因为数据库不拆分,微服务再多最后还是集中到一个数据库里,并发一样上不去;拆分数据库后就会不可避免的出现有些业务不知道放到哪个服务才合适,因为不管你往哪里放都有可能出现跨库join的情况,微服务是不能直接操作不在自己服务里的数据库的,这就很考验服务的拆分了;
另外,当服务拆分成很多微服务后,每个微服务都是需要基础类库跟运行环境的,如果一些没有并发要求的服务被拆的很细,那就会冗余出很多相同的基础类库,更新一些类库时会不可避免的要同步到其他服务上,这时候就要考虑拆分是否具有必要性了;
其实单体服务就像超市,有卖菜的,卖水果的,买衣服等,当某个服务部人流很多时 我们自然就想到把它单独出去,这样也避免超市的其他服务被搞乱,但是如果一个服务不是说很多人,那把服务拆分出去是很亏的,因为你要再租一个店铺,在搞水电,收银台等,这些都是可以跟原有超市公用的,所以该不该拆,还得根据实际业务慎重分析后操作,千万不要为了微服务而拆成微服务,只会得不偿失!!!
什么时候需要微服务
1:如果业务没有性能的压力,只是为了解耦模块,提高服务自治能力,那拆分就应该属于产品层面的事,这种情况肯定是越早拆分越好,避免后面项目越来越臃肿,拆分难度更大
2:如果项目中某些模块并发压力很高,或者说某些模块很耗cpu,但是对数据的依赖并不大,这样的模块肯定也越早拆分出去是越好的,比如说项目中图片处理的业务,计算密集型
3:项目整体比较大,多个业务点并发都比较高,并且各业务点数据耦合度不是很高,这样的情况由于多点业务高并发集中起来整个项目并发就变得更难承受了,也是需要尽快缕清业务,进行业务拆分的
4:项目不算特别大,只是并发很高,这种情况一般是不建议进行业务拆分的,因为微服务并不是解决高并发的根本手段,就算你拆到更小的服务了,更小的服务并发很高怎么办呢? 项目不大 就当单体微服务去解决高并发,解决高并发的方向是集群+缓存+异步
服务限流
服务限流不是针对微服务,单体服务一样需要限流的
再举一个我们生活中的例子:一些热门的旅游景点,往往会对每日的旅游参观人数有严格的限制,比如厦门的鼓浪屿、北京的故宫等,每天只会卖出固定数目的门票,如果你去的晚了,可能当天的票就已经卖完了,当天就无法进去游玩了。 为什么旅游景点要做这样的限制呢?多卖一些门票多赚一些钱岂不是更好?
其实对于旅游景点而言,他们也很无奈,因为景点的服务资源有限,每日能服务的人数是有限的,一旦放开限制了,景点的工作人员就会不够用,卫生情况也得不到保障,安全也有隐患,超密集的人群也会严重影响游客的体验。 但由于景区名气大,来游玩的旅客络绎不绝,远超出了景区的承载能力,因此景区只好做出限制每日人员流量的举措。
同理,在 IT 软件行业中,系统服务也是这样的。如果你的系统理论上单位时间内可服务 100W 用户,但是今天却突然来了 300W 用户,由于用户流量的随机性,如果不加以限流,很有可能这 300W 用户一下子就压垮了系统,导致所有人都得不到服务。 因此为了保证系统至少还能为 100W 用户提供正常服务,我们需要对系统进行限流设计。
有的人可能会想,既然会有 300W 用户来访问,那么为什么系统不干脆设计成能足以支撑这么大用户量的集群呢? 这是个好问题。如果系统是长期有 300W 的用户来访问,肯定是要做上述升级的,但是常常面临的情况是,系统的日常访问量就是 100W,只不过偶尔由于一些不可预知的特定原因导致的短时间的流量激增,这个时候,公司往往出于节约成本的考虑,不会为了一个不常见的尖峰来把我们的系统扩容到最大的尺寸。
如何限流 :在实际的应用当中,流量入口应该是:
防火墙 --> API 网关 -> 服务
因此,实际上我们是有三个地方可以进行限流。那么,防火墙 和 API 网关 我们则另说,那是运维做的事情。我们要说的是 在应用服务应用层也需要自己的限流,下面有Swooles实现的令牌桶算法限流模块
Swoole 令牌桶限流
熔断保护
这个模式是需要系统在设计之初,就要把 熔断措施 考虑进去。当系统出现问题时,如果短时间内无法修复,系统要自动做出判断,开启熔断开关,拒绝流量访问,避免大流量对后端的过载请求。系统也应该能够动态监测后端程序的修复情况,当程序已恢复稳定时,可以关闭熔断开关,恢复正常服务。
服务降级
将系统的所有功能服务进行一个分级,当系统出现问题,需要紧急限流时,可将不是那么重要的功能进行降级处理,停止服务,这样可以释放出更多的资源提供给核心功能去使用。
例如在电商平台中,如果突发流量激增,可临时将商品评论、积分等非核心功能进行降级,停止这些服务,释放出机器和 CPU 等资源来保障用户正常下单,而这些降级的功能服务可以等整个系统恢复正常后,再来启动,进行补单/补偿处理。 除了功能降级以外,还可以采用不直接操作数据库,而全部读缓存、写缓存的方式作为临时降级方案。
延迟处理
这个模式需要在系统的前端设置一个流量缓冲池,将所有的请求全部缓冲进这个池子,不立即处理。然后后端真正的业务处理程序从这个池子中取出请求依次处理,常见的可以用队列模式来实现。这就相当于用异步的方式去减少了后端的处理压力,但是当流量较大时,后端的处理能力有限,缓冲池里的请求可能处理不及时,会有一定程度延迟。
特权处理
这个模式需要将用户进行分类,通过预设的分类,让系统优先处理需要高保障的用户群体,其它用户群体的请求就会延迟处理或者直接不处理。
更多推荐
所有评论(0)