1 、前言
微服务架构是现在很火的流行技术,大家都朝着微服务化的方向转型,但是我要给大家泼一泼冷水,也许有些架构根本满足不了微服务思想,只是新的第三方框架替换老框架的换汤不换药的做法,还有一些只是满足了现有公司的业务需求,如果公司朝着私有云,物联网发展,那么你原先的微服务的服务原子化拆分可能就要打破,就不能保证每个微服务清晰的任务划分。那么怎么样才能架构出微服务思想的框架呢?如果用第三方的就不能满足公司的方案需求扩展,就不能做到微服务化原子拆分,那么大公司都在推荐用某某微服务,服务网格。大家不要搞混了推荐和自己核心使用是两码事,你认为各个公司的云服务化是用什么架构,是用第三方的吗?肯定是用微服务化思想中间件,组件扩展的。
凯亚 (Kayak) 是什么?
凯亚(Kayak)是基于.NET6.0软件环境下的surging微服务引擎进行开发的, 平台包含了微服务和物联网平台。支持异步和响应式编程开发,功能包含了物模型,设备,产品,网络组件的统一管理和微服务平台下的注册中心,服务路由,模块,中间服务等管理。还有多协议适配(TCP,MQTT,UDP,CoAP,HTTP,Grpc,websocket,rtmp,httpflv,webservice,等),通过灵活多样的配置适配能够接入不同厂家不同协议等设备。并且通过设备告警,消息通知,数据可视化等功能。能够让你能快速建立起微服务物联网平台系统。
凯亚物联网平台:http://117.72.121.2:3100(用户名:fanly 密码:123456)
链路跟踪Skywalking V8:http://117.72.121.2:8080/
surging 微服务引擎开源地址:https://github.com/fanliang11/surging(后面surging 会移动到microsurging进行维护)
2 、交互模式通信
交互模式有以下几种方式:
• 请求/响应:客户端向服务器端发起请求,同步等待响应,等待过程可能造成线程阻塞。
• 通知(也就是常说的单向请求):客户端请求发送到服务端,服务端不返回请求响应。
• 请求/异步响应:客户端发送请求到服务端,服务端异步响应请求。客户端不会阻塞,而且被设计成默认响应不会立刻到达。
• 发布/ 订阅模式:客户端发布通知消息,被零个或者多个订阅者服务消费。
• 发布/异步响应模式:客户端发布请求消息,然后异步或者回调服务发回响应。
以上是几种交互模式,那么针对于服务之间的通信可以使用同步的请求/响应和请求/异步响应模式,框架采用rpc,webservice,rest 请求/异步响应和基于rabbitmq 的消息通信模式。
十几年前的架构做法是内部服务之间通过webservice,外部通过调用webapi 或者是ashx ,弊端就是需要配置服务地址很难维护,并且需要配置nginx反向代理做负载均衡,其实那时候就是微服务的简易版本呢,领域业务服务都是放在webservice,而聚合服务放在webapi, 后面居然出第三方api gateway,这种方案根本行不通,也许就是朝着老旧的设计理念替换下负载均衡,身份鉴权,但是没有统一的服务治理,RPC,网关这种做法只是换汤不换药而已。
3 、服务治理
服务自动注册与发现,不需要配置服务提供方地址,注册中心基于ServiceId 或者RoutePath查询服务提供者的地址和元数据,能够平滑添加或删除服务提供者,并且软负载均衡及容错机制,通过内部负载算法和容错规则的设定,从而达到内部调用的负载和容错
服务治理原理:
1.服务提供者启动服务,然后通过向注册中心注册提供的服务和容错规则
2.服务消费者通过向注册中心心跳获取服务和容错规则
3.注册中心向服务消费者返回服务和容错规则存储到本地缓存
4.服务者在调用过过程中通过负载算法定位服务地址放入到监控服务,并且返回健康的服务地址
5.健康服务会针对地址列表进行健康检查,把多次不健康的服务从注册中心移除
6.服务消费者通过设置的负载算法(哈希、轮询、随机、压力最小优先)来定位服务地址,从而通过服务地址去远程调用服务提供者
7.服务消费者在调用过程中,如果成功会从服务提供者返回数据,如果失败会通过容错规则的设定而发生熔断,从而保证整个调用的稳定性。
有大部分人估计使用开源的服务治理框架,就认为是微服务,其实不然还需要依据业务需要扩展中间件,组件来满足微服务原子化拆分。
4、中间件和组件
为了满足业务需求就需要扩展中间件,组件以及多种外部协议来解决各个行业的业务问题, 比如缓存中间件:
缓存中间件
对于服务所返回的数据,有些是不需要经常修改,可以通过缓存返回数据,比如商品应用,商品分类,商品列表、用户信息,订单信息,购物车等,通过以上需求我们就要对于proxy进行拦截,返回缓存或者删除缓存。
对于缓存会有以下疑问
- 数据一致性:对于服务是分布式部署在各台服务器上, 缓存存储读取也应该支持分布式,所以应该选择支持分布式的缓存框架,如:redis,couchbase,membercache
- 缓存命中率:在无命中的情况下,无法直接通过缓存获取到想要的数据,而直接通过调用远程服务获取数据,这样就会增加响应时间和影响吞吐量,所以我们必须引用工具进行监控
缓存降级
微服务的缓存降级就是针对于proxy进行拦截,如果有缓存数据,则返回缓存数据,否则调用Proceed方法调用远程服务。
在数据进行update,delete的时候就需要针对于依赖的缓存进行删除,可以通过proxy进行拦截的方式把缓存进行删除
缓存降级有以下优点
1.高性能:可以减少响应时间和提高吞吐量
2.高效:针对于业务逻辑的设计,无需考虑缓存,做到了无缝集成
以下通过示例来介绍如何使用
在业务接口方法上添加如下特性
消息中间件
比如消息中间件实现了EventBus,而EventBus组件扩展了基于RabbitMQ,Kafka的事件总线,支持多种绑定模式,包括Normal、Retry(死信队列)、Fail等。它主要用于处理高并发场景,如商品秒杀和抢购活动,能够在高流量访问下有效地管理消息队列
而针对于该组件有哪些应用场景呢?
- 商品秒杀和抢购
抢购/秒杀是如今很常见的一个应用场景,在高并发的流量访问下可以将用户放入到抢购队列中,购买成功则销毁消息。
- 最终数据的一致性
在大型业务中,系统一般由多个独立的服务组成,在分布式调用时候把消息放入到rabbitmq 队列中,再通过消息的幂等性来解决数据的最终一致性
- 订单失效处理
在购买商品/服务生成订单业务中,会设定支付时间,如果一直未支付,会直接关闭订单,而这个场景可以通过死信队列的来解决
协议主机
通过实现业务场景就需要实现使用不同的协议,比如物联网就需要mqtt,tcp,udp,coap等协议
behaviors是协议服务主机引擎特性, 每个扩展的主机都包含一个 behavior, 可以包含属性、数据、标识和方法,组件引用它时,它的属性、数据和方法会被合并到组件中,对于各自的behavior会在启动的时候进行初始化生成ServiceEntries。里面包含了类型,routepath, behaviors. 以下各个协议服务主机的behavior
BackgroundServiceBehavior:继承IServiceBehavior, 后台托管服务,可以构建后台定时任务
UdpBehavior:继承IServiceBehavior,可以集成UDP协议
WSBehavior:继承于IServiceBehavior,可以集成ws协议
GreeterBehavior: 继承于IServiceBehavior和Protos生成的GreeterBase,可以集成Grpc
MqttBehavior:继承于ServiceBase,可以集成MQTT协议
DnsBehavior:继承于IServiceBehavior,可以集成DNS
5.网关
API 网关是服务提供者的访问入口,主要起到隔离外部访问与内部系统的作用。它主要解决服务消费者的身份认证、监控、负载均衡、缓存、限流等问题。
作用和价值
对于API网关主要起到以下作用:
系统隔离:隔离外部访问与内部系统
业务解耦:解耦各层的相互依赖,快速应对业务变化,使得微服务能够独立灵活部署,统一管理
灵活配置:对于微服务水平和垂直扩展能顺利进行而搭设的工作平台,平台能对于服务进行灵活配置。
系统隔离
内部服务与外网都是隔离的,为了安全考虑,应用服务都是运行在内网,不允许外部访问,这时候API网关通过身份验证、数据安全、容错降级等规则,对访问进行了初步的过滤,从而达到灵活动态配置,保证了数据的安全性和系统的可靠性。
系统模块的解耦
微服务所面向的角色包括服务提供者,服务消费者,服务运维等,各个角色都有各自的述求,为了满足各个角色的需求和依赖关系,就需要网关动态灵活配置,让各方专注于自己的领域需求。主要从以下几点进行解耦
解耦业务与非业务功能
在满足实现业务功能外,还面临非业务的功能性需求,比如突发性大规模服务访问,黑客攻击,身份验证,数据的流量监控等,这些非业务的功能需求,不能与业务服务耦合在一起,需要解耦成独立的系统,由专业人员和专业团队进行处理
解耦服务消费者与服务提供者
对于服务提供者主要是对业务进行实现,而业务的快速变化,为不了不破坏业务的稳定性,这时候就需要中间层定义统一的接口、协议和报文,以满足服务消费者多变的需求。
业务和非业务可配置化
网关除了请求路由、转发外,还需要负责数据安全、鉴权、限流、监控等,往往随着业务的变化不断调整,比如访问大规模增长,这时候就需要考虑发生错误能及时熔断降级,或者分流,限流,而这时候就需要网关提供可配置化的界面,便于修改,而对于网关来说更应该提供插件化的机制来支持可配置化的功能性动态扩展。
网关的价值
网关对于系统进行了隔离,保证了服务的安全和可靠性,对于运维也减少维护成本和变更流程。服务提供者和消费者也能减少耦合,还能够独立进行部署,同时通过熔断也避免了服务大规模的瘫痪,节约服务的维护开发成本,减少上线风险。
对于以上特点网关还可以加载聚合服务,服务路由编排转化等功能
6.服务拆分
微服务应该是可以自由组合拆分,对于每个业务都是独立的,针对于业务模块的 CRUD 可以注册为服务,而每个服务都是高度自治的,从开发,部署都是独立,而每个服务只做单一功能,利用领域驱动设计去更好的拆分成粒度更小的模块业务微服务
对于服务原子化拆分可以分为四种类型,分别为接口服务,业务服务,聚合服务,中间服务
接口服务
提供给调用方进行调用,如果只引用了接口模块就是远程调用,引用了业务模块就是本地调用,并且还可以通过接口生成swagger 文档
业务微服务
针对于领域驱动设计,通过领域服务和仓储对于领域对象的CRUD,并通过转化成实体模型返回给调用方
聚合服务
在构建分布式系统时,特别是在微服务架构中,经常会遇到需要将多个服务的数据聚合到一起以满足前端或者其他服务的需求的场景。这种需求可以通过中间服务(也称为聚合服务)来实现。中间服务主要负责从多个微服务中获取数据,然后将这些数据整合成一个单一的数据结构,最后将这个数据结构提供给调用者。
聚合服务放在网关,然后再远程调用多个业务微服务。
中间服务
中间服务通常指的是那些位于客户端(如前端应用或移动应用)和 业务微服务之间的服务。这些服务的主要职责是协调请求、转换数据格式、聚合数据、执行安全验证、日志记录,协议扩展以及可能的缓存等。
中间服务放在网关,然后再远程调用多个业务微服务。
6.总结
通过以上描述,再结合自己的情况,是不是满足微服务思想,还是新的第三方框架替换老框架的换汤不换药的做法,还是ESB的做法的衍生,也请大家能熟知微服务思想,其实实现并不容易
