9月23日,数人云&又拍云在北京联合举办了将微服务进行到底的线下沙龙活动,数人云产品总监了哥(邱戈川)作了高并发微服务平台实践的分享,从微服务的优点出发进行了深刻探讨,如下是本次分享的实录。前端
说到微服务,在和你们讨论时发现最大的问题是,是否要落地实践微服务?由于不少企业并无达到所需的规模,因此,在准备实践微服务以前须要考量的几个问题是:数据库
若以上问题都不存在,建议仍是以三层结构的模式,不要给本身挖坑跳不出来,并不是全部企业度适合微服务。后端
若是以传统的RPC结果去应对大规模互联网架构,对于一些企业并不适用,不少RPC结构并不是为了高吞吐而是为了快速响应,由于不少时候须要先后端的资源一致,不过一些企业有历史包袱,前端接受请求和后端的服务资源不能彻底匹配,因此此时,不能用简单的RPC方式去解决。多线程
业界作微服务一般容易忘了比较重要的一件事:服务治理,用SpringCloud或Dubbo多数用的是一个开发框架将客户端和服务端调通,基本上是人为经过服务注册发现的方式找到服务以后再完成调用,一个很大的误区是,认为这就是微服务了。架构
另外不少企业不但愿丢消息,也并不须要很高的快速响应,来了客户请求,宁愿等一下也是能够的,如果这种请求,RPC也并不必定彻底适合。并发
业务逻辑是否须要每次都进行更改,互联网脚骨里面很重要的一点是业务开发一直在持续迭代,但传统企业很难作到,由于有预算资金、业务规划等方面的约束,并且还须要保留以前已经作好的系统。框架
微服务其实很是复杂,并非全部的人、企业均可以搞定,入坑以前必定要进行完整的考虑。运维
传统企业最容易面临的问题首先是业务模式上的变化,一些企业原有的模式是人和人打完交道后人为在系统进行操做录入然后走相关流程,不少业务模式都是基于这种方式去走,但问题是一些系统在开发时就已经肯定了用户的访问规模,并发程度等,若系统是这种条件下,其实一个简单的Tomcat就能够搞定,哪怕用两个或三个,也能够。异步
但有的企业在这种情景下,搞了一堆小型机,这是比较要命的问题,所以在这种条件下,不要去作微服务,但若是业务开发模式发生改变,要向互联网转型,一些出口要往互联网开,不管是电脑端或移动端,只要往互联网开放,就要去考虑是否须要走互联网机构或微服务架构的问题了。数据库设计
不要把原有的系统直接放出去,须要在中间环节考虑保护性和吞吐性的问题,这是业务模式的变化,当业务模式没有变换前不要轻易地去改变架构,并非说微服务要将原来的体系所有推翻,这是不合理的。
〓 业务开发的变化
还有一点是业务开发的变化,以前提过,不少传统企业须要半年或一年的规划,但如今是两周一个迭代上线,一些公司如豆瓣等,一天变三四次都有,因此须要看总体变化规模有多快,若没有这个变化,慢慢作均可以,也不必定须要微服务了。
〓 用户行为的变化
最重要的一点是整个用户行为的变化,不少时候,旧系统访问行为是在很窄的范围内,例如,某个普通系统一般美妙十几二十个TPS,咱们看到不少文章都提到一天的访问量是几百万次,会以为组ode很大,但去算一下,若24小时按照每秒是多少次?实际上不多,一天几百万次并不表明访问量很高,另外,互联网模式下,用户规模和访问时间都发生了变化,因此访问的次数分布也会发生很大的变化,特别是将出口开到互联网后,一些业务性的攻击也会来临,这些是不少传统企业没法应对的。
〓 业务对原有架构的冲击
上图是一个简单的传统三层架构,从Nginx或F5这些负载金恒进来,一些大型企业都是买的硬件F5,中间件走的是Weblogic或Websphere,而后再到数据库,只要是这样的架构,即使买来很好的WEB服务系统,但访问模式变了,最容易挂掉的地方是数据库,曾经有个合做伙伴作了一次店庆促销就是这样,互联网公司作促销都是先作几天预热,而后再去开卖,但在预热阶段就已经挂掉了,由于预热要派卷,数量有限同一时间用户去抢卷,并发量就会突增,这是传统架构比较难处理的地方。
〓 对运维形成的冲击
给运维带来比较大的冲击是:曾经运维管理都是有特定的时间段,但如今须要24小时全天候值守,所以带来的问题是在线升级,传统的运维方式是停机、换包、改配置、从新上线,发现问题后须要从新下线反复上一个循环,如今须要所有在线滚动升级、灰度测试等,另一个给团队带来的冲击是一些公司依赖于外包,以前咱们的客户有不少状况是一个供应商拿着SpringCloud作开发,另一个拿着Dubbo作开发,最后运维不知道该如何去统一运营,由于两种模式不同,最后出维内托的时候抓包对包都不知道如何去作。
如今愈来愈多的公司要求在大的层面统一基础框架也是这个缘由。
〓 水平扩展是否可行
业界不少容器公司都说能够帮助应对大规模的攻击,其实主要就作了一件事:作水平扩展。Weblogic、Websphere打包方进容器,须要时就扩展,但扩展的越多,死的越快,由于数据库的强一致性依赖,前面接受更多请求数据库更加顶不住,因此在互联网架构下,任何一个公司都不敢直接将数据库强关联的系统对外暴露出去,因此去IOE的概念是把数据库用的愈来愈弱,在互联网架构里数据库设计的几个范式是要被打破掉的,互联网机构里面是有很大的冗余度,例如先后端都有用户信息,另外就是这种架构下业务是一个总体性,变更起来会很麻烦。
〓 微服务体系
提及微服务,上图是从Microservice.io截过来的,核心的概念是将系统拆分,每一个组件都有本身的库,只要将库拆了,库与库之间可能要作相关的一致性同步处理,限于时间问题,今天不作扩展。
〓 微服务与RPC
SpringCloud也好,Dubbo也好,实际上只有Client和Service两层架构,中间的Service Mesh是由Google和IBM推出的最近比较流行的一个概念,实际上已经有不少互联网公司已经在应用这个概念,它们只是将其抽出做为独立的概念,而后推到了CNCF,比较热门开源的有Istio、Linkerd等。
原来Client到Service端的微服务架构有个较大的问题是将不少的服务治理放到客户端,客户端要作服务治理升级,全部的客户端都须要进行升级,带来的运维复杂度和错误率方面提高,因此Service Mesh核心思想是将不少服务治理抽到中间去作,所以微服务治理愈来愈多作中间化处理,并非在客户端和服务端作治理,如今这个概念比较流行,但也暂时不去作扩展。
微服务架构是否等于作RPC架构?这是一个值得讨论的问题。
〓 微服务是一个体系
须要注意的是,微服务是一个体系,这也是为何前文和你们说不要过多地去考虑微服务的缘由,由于很难有公司能自主构建出如此庞大的体系,不少大型的互联网公司都要花费两到三年的时间才能将整个体系构建的比较完整,让业务开展顺畅里面有太多的东西须要去作,虽然一般只看到一个开发框架和服务注册和发现,但后面有不少的东西实际上都没有去作。
〓 微服务后的开发方式转变
微服务后整个开发模式会发生变化,不要认为微服务只是架构上的变化,这是一个很大的误区,微服务进来之后,不仅仅只是架构上的变化,更多地是组织和流程都发生了改变,CI/CD和DevOps最近两年比较火其实和微服务有很大的关系,这个概念已经有近十年的时间了, 但不少事情都没有用,道了微服务才去考虑这个问题,由于服务数量持续增大痛点才会出现,团队的构建不像之前那种传统的有开发部门、运维部门。测试部门等,如今越多倾向多功能团队的缘由就是由于须要快速迭代、测试开发、以及产品、运营做为一个总体团队来作业务开发。
〓 开发团队的适应
上图是团队混搭的模式,必定要作到全功能集合,不可能再去作某个只能划分,这对不少公司是一个挑战,由于这样的设计,不知道公司部门领导什么设置,是设成开发部去领导仍是测试部去领导,不少公司不肯改变跟这个也有必定的关系。
〓 传统企业微服务如何起步
前面讲得比较传统,阿里提的Dubbo有5年以上了,体系都比较大,虽然开发模式比较简单,但总体体系很是庞大的后果是迭代速度不必定彻底适合中小型企业,由于应对场景不一样,但愿在微服务理念下能构建一个更小的体系,去应对吞吐这个主流的场景,特别是抢红包或者一些优惠券的场景,而不但愿去用一个大的完整的体系,由于没法快速构建出来。
须要将架构构建的更简单一些,不须要太多的东西,架构上面前端没有变化是F5或其余的软LB的方式,从前台、中台、后台的概念来讲,前台基本用Tomcat去顶,这个没有太好的方式,由于你们都知道,每个需求对于Java体系来讲,一个请求就是一个线程,因此要支撑足够的并发和吞吐,就要有足够的线程,因此只能用更多的Tomcat去顶这个线程数,若是是容器化的方法,就打开足够多的Tomcat容器实例便可,因此容器不少适合你们用的就是它这一点,快速开足够多的实例数。
但不可能将全部的流量如RPC那样直接传到到后端,因传统系统是顶不住的,一些企业很难去改造传统的业务系统,好比下面有财务或帐务处理等不可能改变,大的互联网企业在进行微服务架构改造时,是一整套系统所有概念的,这是很伤筋动骨的事情,可是没有更好的办法,惟一可以作的就是在中间层加一层消息,好处是不须要前端那么多的实例数,后端能够用更少的实例数,慢慢去消费最后将信息反馈出去,这样能够保护好下面传统的系统,特别是保护好数据库,这也是一个比较容易考虑的架构。
然后,微服务体系里面须要考虑如何作动态的管理,一些监控的体系,而后与容器作结合,将操做流程作的更简单,因此将架构简单化时会这样去考虑。
〓 微服务支持高并发平台的愿景
实际上须要构建的是这样的一个系统:将开发作的简单一点,有几个接口杰克,你们用SpringCloud的目标其实只是认为那是比较好开发的框架, 不须要考虑不少通讯上的问题。另外能够作到高可用,支持更多的并发,同事是一个平台作统一配置、监控和管理,尽量作高吞吐数据尽量地不丢弃而且能跟容器作结合从而轻松运维。
〓 基于消息的微服务架构
咱们将这个系统构建出来,实际框图就比较简单了,中间须要一个消息队列,须要一个Kafka、它能够去顶高吞吐的事情,Kafka刚发布了0.1的版本,能够做为所谓的Exactly Once,一个消息只执行一次,客户端和服务端提供服务无注册和服务发现,这和RPC是一样的道理,可是这里的服务发现作了改变,通常的RPC微服务都死将IP和端口注册上去,而后再把IP和端口列表拿回来随机的分发,可是消息微服务不关心IP和端口,关心的只是服务名称对应的消息Topic,发给消息给一个服务,经过服务名称发现服务的Topic,而后发送消息到这个Topic便可。
〓 服务高可用
前文提到,高可用是一个很简单的事情,一般作法是本身有调度器,会箭筒Zookeeper节点,全部的服务运行起来时都会注册到Zookeeper的这个节点上,调度器就可知道Zookeeper这个服务已经有两个实例,它会统治这两个实例跑哪些任务。
当掉线时Zookeper上面的这个实例的临时节点会被清掉,这时调度系统就能知道有节点掉线,将它所有迁移到没有掉线的街上,这样比较容易作高可用,高可用的机制大体如此,因此想作高可用,就须要引用一个协调的集群如Zookeeper、Etcd等来作。
〓 动态治理控制
另外要作一些动态性的治理,最容易考虑的问题是要不要作多级别的超时,一般一个客户端设定默认超时便可,但客户端调A服务和B服务的超时是不同的,这样多级别的设置不可能放到配置文件里面去,能够作的事情所有经过统一的平台动态去作,而后实时下发,这也是一个很重要的概念,全部的服务治理都是动态化,配置界面针对客户端调用某一个服务单独去配超时,全部更新会实时生效,由于全部的协调集群均可以作到动态推送。
〓 客户端禁用
还能够作服务的禁用管理,不少微服务的客户端将接受的请求直接打到后面将后面的服务冲垮,此时要紧急停某个客户端才能够,早前的反射弧是要找到机器而后想办法登陆机器将服务删掉,如今用了框架以后,只要发送一个指令,每次发消息判断哪一个指令说是否是禁用,若禁用就不调用服务,全部的消息在客户端报错出去,这样能够实时保护客户端的东西,在整个平台里若开了API,就能作紧急预案,若是发现某个紧急状况,能将客户端全部的请求屏蔽掉,作降级必定要考虑这样的问题,不少公司不知道降级如何作,其实降级就是在什么条件下,将哪些服务关掉,而后可以有首段能够动态将某些服务逐步恢复过来这就是所谓的降级预案的作法。
〓 客户端按照比重路由
既然能够管控发送,也能够协调客户端往哪一个服务端发送的比例,按照比重去发送,这是比较常见的概念,按比重发送通常在生产环境用的比较少,不少时候作在线压测用,在线流量不必定可以压到某一台机器上,因此须要将全部的流量都导入到那台机器,这也才能知道在线系统可以支撑多大量,由于不少开发环境单独行压测是很难支撑这个测试。
〓 自身管理Dashboard
作Java要考虑的问题是包依赖的冲突,在架构里将架构依赖和业务依赖脱离开,这是须要考虑的问题。
将不少东西统一在一块儿,不想搞那么多的事情,就须要作不少的Dashboard,愈来愈重要一点是考虑每一作一个业务都要想一想业务有多少指标,这些指标是什么样子,而后将指标汇总画图,因此你们作系统必定要考虑这个事情,Dashboard是愈来愈重要的概念尽管可能会花费一些力气,但当出现问题时能及时发现,若没有就等同于瞎子和聋子。
〓 兼容Prometheus的Metrics
固然自行作是一方面,可能作图形等会比较麻烦,其实不少中后段的同事并不肯意作话题的事,有个更好的方式是按Prometheus的方式将全部的东西都吐出来将全部的指标全部的数据所有吐出去,吐完以后再用Grafana画,能够节约不少事情,因此要梳理好指标,将全部的东西所有吐出去,如今比较好的是Prometheus在整个中小型规模里面比较容易接受,愈来愈成为一个事实的规范。
〓 服务依赖拓扑
当谈到微服务比较容易谈到的一点是,必定要作APM,但消息量化比较大,须要一一对应日志分析后才能把依赖找出来,这样的复杂度相对高,但用消息作的好处是经过消息配置找到全部服务的依赖,根本不须要作任何的分析就把服务依赖找到了,这样出问题便可很容易发现,因此这种服务依赖比较容易作,但想真正作调用链,将调用链日志找出来就要单独考虑上APM的事情,因此系统到了哪一个规模再去考虑其对应的问题,不可能如今没有这个规模就一下将庞大系统搭建起来,由于可能一天下来就是一百屡次调用,出问题时找下日志就能够搞定的问题,但上一个APM没有经验那就可能将本身搞死了,因此就是说如今也是这样的方式简单的依赖方式,但作APM这个事情也能够考虑要把扣子留给APM,后面对接到APM便可。
中国人开源APM并很少,如今基本上能看得见的中国人作的APM开源系统就是Skywalking,你们能够搜一下,同时支持SpringCloud和Dubbo,是Opentracing的标准。
〓 系统无侵入性扩展架构
接下来,要考虑怎么作无侵入扩展,若你们用传统的RPC的方式作微服务,最大的问题是若是出现业务的变化都要作什么事情呢?通常都是增长接口重构系统,增长某个环节,但对于不少企业很难的缘由是下面有不少的系统都是一个固有系统,不可能扔掉重来,互联网公司喜欢扔掉再重来一次,可是传统企业很难作到,因此考虑用消息作微服务时,能不可以作到能够无侵入插入一些额外的逻辑?
如今都在谈大数据,不管是否有需求,一天十万行数据也要作大数据,都已经到了这个程度,这时玩大数据就须要作大数据的采集,有不少种手段,包括用Java Agent插入,强行插进去代码作也能够,但用消息有一个好处,将不一样逻辑的处理模块都挂在消息集群下面,只要把消息都在这些模块中流转一次便可。
〓 扩展机制:Filter Chain
咱们提出一个概念叫FilterChain,意思是每一个Filter都被认为是消息服务,消息服务启动时会注册上系统,当注册上来系统就知道这个Filter已经挂载上来,在配置上高速哪一个客户端发到服务端时要通过那些Fitler,把这个配置配置好,就把它通知到客户端的SDK里面,开发商仍是从客户端发送到服务端,但框架发消息会看这个Filter Chain到底往哪里走,而后将消息按照这个规则往下一层一层传递,传递的过程当中也会把下一级的规则一直往下传,最后没有Filter了再发到服务端。
传递的每个环节是能够并行或串行的,举个例子,若是发到下一个环节只是作数据收集,根本不关心数据包是否合法,这个时候数据采集环节是能够将消息并行直接转到下一个环节处理的,若是要作审计,看看那个包是否合法,实际必定要等那个结果才能往下传,这时要作串行,所以是一个比较好的概念,但要是RPC的方式实现这个理念,仍是比较麻烦的。
〓 消息流转
消息流转是比较简单的,首先配置怎么作这个事情,剩下的事情SDK根据Filter Chain的顺序一层层往下走便可,代码实现并不复杂。
〓 三种调用模式
既然提到开发上会不会很复杂这个问题,咱们的作法是从新封装消息的交互,咱们是想作到开发是阻塞应答的模式,下面是消息异步传递,但实际上更好的方式是开发也是异步回调,这样的方式处理消息,会节约不少线程的资源。
〓 更多
固然还能够作更多的事情,包括有统一的平台能够逐渐扩展这些功能,IDC的问题,像是这里面多IDC处理反而更简单,根据配置将消息发送到不一样的IDC的Kafka集群便可,无需作特别的处理。
〓 为何要容器化
另外须要考虑容器化,如今容器化部署能提供更多的灵活性和弹性,简化运维等,一年前谈容器化都在观望,而如今都已经开始作了。
〓 自动调度理念
这个框架还有一个好处,将容器资源调整和消息系统两边一块儿作伸缩调度,众所周知,若是用Kafka,吞吐量是靠它的分区概念去作的,能够把Topic分不少的区供更多的消费者调用,容器是靠增长实例的方式去作扩容,因此想调度每个服务扩容时,会同步调整Kafka的分区和容器实例。
〓 问题思考
因此回到最后一个问题,不要认为一作微服务就要经过RPC的方式作,经过消息的方式也能够,另外要更多考虑吞吐的问题,由于把系统放出互联网以后,容易遇到整个数据库顶不住的问题,由于之前的作法一般为了保护下面系统,RPC一般开一个限流,一限流至关于把前端也限住了,因此消息服务也是跟RPC不同的地方,由于有了消息能够缓冲,消息接受就能够不停,你们知道Kafka的消息都是罗盘的,而后再往下走。
其实消息微服务最好的地方,是能够中间插入逻辑不影响已经开发好的服务,这个对于企业应用是很关键。
一体化异步微服务平台基于容器云平台打造,支持同步和异步模式,具备高可用、高并发、无入侵性扩展业务、服务依赖实时跟踪以及自动伸缩等特性,无缝融合物理机、虚拟机及容器,从而实现微服务统一管理、配置、监控。
以上内容整理自了哥(邱戈川)在9月23日Meetup上分享的分享,但愿对想采用微服务架构的企业有所帮助。
注:一些图片来自于互联网。