看服务治理的时候发现的大神文章,写的太好了前端
原连接:http://javatar.iteye.com/blog/1345073java
在大规模服务化以前,应用可能只是经过RMI或Hessian等工具,简单的暴露和引用远程服务,经过配置服务的URL地址进行调用,经过F5等硬件进行负载均衡。
(1) 当服务愈来愈多时,服务URL配置管理变得很是困难,F5硬件负载均衡器的单点压力也愈来愈大。
此时须要一个服务注册中心,动态的注册和发现服务,使服务的位置透明。
并经过在消费方获取服务提供方地址列表,实现软负载均衡和Failover,下降对F5硬件负载均衡器的依赖,也能减小部分红本。
(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪一个应用要在哪一个应用以前启动,架构师都不能完整的描述应用的架构关系。
这时,须要自动画出应用间的依赖关系图,以帮助架构师理清理关系。
(3) 接着,服务的调用量愈来愈大,服务的容量问题就暴露出来,这个服务须要多少机器支撑?何时该加机器?
为了解决这些问题,第一步,要将服务如今天天的调用量,响应时间,都统计出来,做为容量规划的参考指标。
其次,要能够动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程当中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。
(4) 规模继续扩大,应用之间再也不是扁平的对应关系,开始分层,好比核心数据层,业务集成层等,就算没有出现循环依赖,也不容许从低层向高层依赖,以避免后续被逼循环依赖。
这时,须要在注册中心定义架构体系,列明有哪些层的定义,每一个服务暴露或引用时,都必须声明本身应用属于哪一层,这样注册中心能更快的发现架构的腐化现象。
(5) 服务多了,沟通成本也开始上升,调某个服务失败该找谁?服务的参数都有什么约定?
这时就须要登记每一个服务都是谁负责的,并创建一个服务的文档库,方便检索。
(6) 慢慢一些敏感数据也都服务化了,安全问题开始变得重要,谁能调该服务?如何受权?
这样的服务可能须要一个密码,访问时需带着此密码,但若是用密码,要改密码时,就会很不方便,全部的消费方都要改,因此动态生成令牌(Token)可能会更好,提供方将令牌告之注册中心,由注册中心决定是否告之消费方,这样就能在注册中心页面上作复杂的受权模型。
(7) 就算是不敏感的服务,也不是能任意调用,好比某服务忽然多了一个消费者,这个消费者的请求量直接把服务给拖跨了,其它消费者跟着一块儿故障。
首先服务提供方须要流控,当流程超标时,能拒绝部分请求,进行自我保护。
其次,消费者上线前和提供者约定《服务质量等级协定(SLA)》,SLA包括消费者承诺天天调用量,请求数据量,提供方承诺响应时间,出错率等,将SLA记录在监控中心,定时与监控数据对比,超标则报警。
(8) 虽然有SLA约定,若是不能控制,就只是君子协定,如何确保服务质量?
好比:一个应用很重要,一个不那么重要,它们调用同一个服务,这个服务就应该向重要应用倾斜,而不是一视同仁,当支撑不住时,应限制不重要应用的访问,保障重要应用的可用,如何作到这一点呢。这时,就须要服务路由,控制不一样应用访问不一样机器,好比:
应用分离:
consumer.application = foo => provider.host = 1,2,3
consumer.application != foo => provider.host = 5,6
读写分离:
method.name = find*,get* => provider.host = 1,2,3
method.name != find*,get* => provider.host = 5,6
(9) 服务上线后,须要验证服务是否可用,但因防火墙的限制,线下是不能访问线上服务的,不得不先写好一个测试Main,而后放到线上去执行,很是麻烦,而且容易忘记验证。
因此线上须要有一个自动运行的验证程序,用户只需在界面上填上要验证的服务方法,以及参数值和指望的返回值,当有一个服务提供者上线时,将自动运行该用例,并将运行结果发邮件通知负责人。
(10) 服务应用和Web应用是有区别的,它是一个后台Daemon程序,不须要Tomcat之类的Web容器。但因公司以前以Web应用为主,规范都是按Web应用的,因此不得不把服务跑在一个根本用不上的Web容器里,而搭一个这样的Web工程也很是费事。
因此须要实现一个非Web的容器,只需简单的Main加载Spring配置便可,并提供Maven模板工程,只需mvn dubbo:generate 便可建立一个五脏俱全的服务应用。
(11) 开发服务的人愈来愈多,更注重开发效率,IDE的集成支持必不可少。
经过插件,能够在Eclipse中直接运行服务,提供方能够直接填入测试数据测试服务,消费方能够直接Mock服务不依赖提供方开发。
(12) 由于暴露服务很简单,服务的上线愈来愈随意,有时候负责服务化的架构师都不知道有人上线了某个服务,使得线上服务鱼龙混杂,甚至出现重复的服务,而服务下线比上线还困难。
须要一个新服务上线审批流程,必须通过服务化的架构师审批过了,才能够上线。
而服务下线时,应先标识为过期,而后通知调用方尽快修改调用,直到没有人调此服务,才能下线。
(13) 因服务接口设计的经验一直在慢慢的积累过程当中,不少接口并不能一促而蹴,在修改的过程当中,如何保证兼容性,怎么判断是否兼容?另外,更深层次的,业务行为兼容吗?
能够根据使用的协议类型,分析接口及领域模型的变动是否兼容,好比:对比加减字段,方法签名等。
而业务上,可能须要基于自动回归测试用例,造成Technology Compatibility Kit (TCK),确保兼容升级。
(14) 随着服务的不停升级,总有些意想不到的事发生,好比cache写错了致使内存溢出,故障不可避免,每次核心服务一挂,影响一大片,人心慌慌,如何控制故障的影响面?服务是否能够功能降级?或者资源劣化?
应用间声明依赖强度,哪些功能强依赖,哪些弱依赖,而后基于依赖强度,计算出影响面,并按期测试复查,增强关键路径上的服务的优化和容错,清理不应在关键路径上的服务。
提供容错Mock数据,Mock数据也应能够在注册中心在运行时动态下发,当某服务不可用时,用Mock数据代替,能够减小故障的发生,好比某验权服务,当验权服务所有挂掉后,直接返回false表示没有权限,并打印Error日志报警。
另外,前端的页面也应采用Portal进行降级,当该Portal获取不到数据时,直接隐藏,或替换为其它模块展现,并提供功能开关,可人工干预是否展现,或限制多少流量能够展现。
(15) 当已有不少小服务,可能就须要组合多个小服务的大服务,为此,不得不增长一个中间层,暴露一个新服务,里面分别调其它小服务,这样的新服务业务逻辑少,却带来不少开发工做量。
此时,须要一个服务编排引擎,内置简单的流程引擎,只需用XML或DSL声明如何聚合服务,注册中心能够直接下发给消费者执行聚合逻辑,或者部署通用的编排服务器,全部请求有编排服务器转发。
(16) 并非全部服务的访问量都大,不少的服务都只有一丁点访问量,却须要部署两台提供服务的机器,进行HA互备,如何减小浪费的机器。
此时可能须要让服务容器支持在一台机器上部署多个应用,能够用多JVM隔离,也能够用ClassLoader隔离。
(17) 多个应用若是不是一个团队开发的,部署在一台机器上,颇有能够误操做,停掉了别人的服务。
因此须要实现自动部署,全部的部署都无需人工干扰,最好是一键式部署。
(18) 机器老是的闲时和忙时,或者冗余机器防灾,如何提升机器的利用率?
即然已经能够自动部署了,那根据监控数据,就能够实现资源调度,根据应用的压力状况,自动添加机器并部署。
若是你的应用是国际化的,有中文站,美国站之类,由于时差,美国站的机器晚上闲的时候,可能正是中文站的白天忙时,能够经过资源调度,分时段自动调配和部署双方应用。 安全