本次分享的技术大纲以下:前端
挑战1-- 研发成本高nginx
主要体如今以下几个方面:数据库
在实际项目分工时,开发都是各自负责几个功能,即使开发之间存在功能重叠,每每也会选择本身实现,而不是类库共享,主要缘由以下:后端
跨地域、跨开发小组协调很困难,业务团队可能跨地域研发,内部一般也会分红多个开发小组,各开发小组之间的协调和沟通成本很是高。浏览器
代码重复率变高以后,已有功能变动或者新需求加入都会很是困难,以充值缴费功能为例,不一样的充值渠道开发了相同的限额保护功能,当限额保护功能发生变动以后,全部重复开发的限额保护功能都须要从新修改和测试,很容易出现修改不一致或者被遗漏,致使部分渠道充值功能正常,部分存在Bug的问题,示例以下:安全
挑战2-- 运维效率低网络
在传统的MVC架构中,业务流程是由一长串本地接口或者方法调用串联起来的,臃肿而冗长,并且每每由一我的负责开发和维护。随着业务的发展和需求变化,本地代码在不断的迭代和变动,最后造成了一个个垂直的功能孤岛,只有原来的开发者才理解接口调用关系和功能需求,一旦原有的开发者离职或者调到其余项目组,这些功能模块的运维就会变得很是困难:数据结构
当垂直应用愈来愈多时,连架构师都没法描述应用间的架构关系,随着业务的发展和功能膨胀,这种架构很容易发生腐化。架构
如何解决传统单体架构面临的挑战?app
解决对策:一、拆分 二、解耦 三、透明 四、独立 五、分层。
服务的订阅发布机制
它的核心理念是实现服务消费者和服务提供者的解耦,让服务消费者可以像使用本地接口同样消费远端的服务提供者,而不须要关心服务提供者的位置信息,实现透明化调用。
关键技术点:服务的订阅、发布机制、服务的健康状态检测和高HA。
经常使用的服务注册中心有Zookeeper、ETCD,以及基于数据库的配置中心。
你们在技术选型的时候,须要根据本身的业务实际状况进行选择。例如超大规模集群,服务实例数超过10W,Zookeeper就会存在性能问题。
如今开源的分布式配置服务不少,如无特殊需求,建议选择开源方案。
服务化实践-零侵入
实际上,彻底的零侵入很难作到,即便是声明式配置,配置自己也是代码的一部分,只不过相比于代码类库依赖,它不是编译器依赖。
一种好的作法是,服务的发布和消费经过声明式或者注解的方式,而不是直接调用服务框架的接口,例如Thrift。客户端须要调用Thrift提供的类库访问服务端,这就是代码API级的依赖,对业务代码侵入比较大。
一种比较成熟的实践是 利用Spring的扩展机制,经过XML的方式实现服务的发布和消费。
服务化实践-容错和路由
单体应用服务化以后,一般采用分布式集群的部署模式。
这会带来两个问题:
大部分的容错和路由策略能够抽象到分布式服务框架中,经过策略配置的方式提供给用户使用,下降用户的开发成本。
从业务扩展性角度看,服务框架一般会提供扩展点,供业务作路由和容错定制。例如,业务但愿根据手机号码和地市进行路由:
服务化实践-本地短路策略
在电信行业中,小机仍是很广泛,应用一般会合设,例如服务提供者和消费者部署到同一台主机上。
为了提高性能,下降时延,每每会提供本地短路策略,具体策略以下:
服务化实践-多样化调用方式
服务的调用方式,主要有三种:同步服务调用、异步服务调用、并行服务调用。最经常使用、简单的就是同步服务调用。
异步服务调用的工做原理以下:
详细步骤以下:
并行服务调用,目的是为了提高服务调用的并行度,下降E2E时延。
服务化实践-高性能、低时延
服务框架的性能,主要强调三个要素:一、I/O通讯;二、序列化框架;三、线程调用模型。
若是使用Java语言,I/O框架推荐 Netty。
序列化框架推荐:Thrift、Avro序列化框架、PB等。线程调度模型建议参考Reactor。
一种线程模型的参考实现方式:Netty的线程模型
服务化实践-故障隔离
故障隔离很是重要,因为常常会采用同步服务调用模式,核心服务和非核心服务共用同一个线程池和消息队列,非核心服务处理慢每每会阻塞核心服务,致使雪崩现象。
故障隔离的核心技术点以下:
1. 支持服务部署到不一样线程/线程池中
2. 核心服务和非核心服务隔离部署
服务化实践-服务治理
随着业务规模的不断扩大,小服务资源浪费等问题逐渐显现,须要可以基于服务调用的性能KPI数据进行容量管理,合理分配各个服务的资源占用,提升机器的利用率。
线上业务发生故障时,须要对故障业务作服务降级、流量控制、流量迁移等,快速恢复业务。
随着开发团队的不断扩大,服务的上线愈来愈随意,甚至发生功能相同、服务名不一样的服务同时上线。上线容易下线难,为了规范服务的上线和下线,在服务发布前,须要走服务预发布流程,由架构师或者项目经理对须要上线的服务作发布审核,审核经过的才可以上线。
为了知足服务线下管控、保障线上高效运行,须要有一个统一的服务治理框架对服务进行统1、有效管控,保障服务的高效、健康运行。
服务治理是分布式服务框架的一个可选特性,尽管从服务开发和运行角度看它不是必须的,可是若是没有服务治理功能,分布式服务框架的服务SLA很可贵到保障,服务化也很难真正实施成功。
从架构上看,分布式服务框架的服务治理分为三层:
第1层为服务治理展现层,它主要由服务治理Portal组成,提供可视化的界面,方便服务运维人员进行治理操做。
第2层为服务治理SDK层,它主要由以下几部分组成:
第3层为后台服务治理服务层:它一般由一组服务治理服务组成,能够单独部署,也能够与应用合设。考虑到健壮性,一般选择独立集群部署。治理服务的可靠性由分布式服务框架自身来保证,治理服务宕机或者异常,不影响业务的正常使用。服务治理服务一般并不随服务框架发布,治理服务是可选的插件,单独随服务治理框架交付。
服务化实践-高可靠性
关键技术点设计以下:
服务化会带来不少收益,可是它却不是银弹。
服务化不是银弹-时延问题
在服务化以前,业务一般都是本地API调用,本地方法调用性能损耗较小。服务化以后,服务提供者和消费者之间采用远程网络通讯,增长了额外的性能损耗。
服务化不是银弹-问题定位
在分布式环境下,如何高效的进行问题定界定位和日志检索
服务化不是银弹-事务一致性
服务化、分布式部署以后,有逻辑关联关系的多个数据库操做被打散到集群中各个独立的服务实例中,引入分布式环境下的事务一致性问题。
服务化不是银弹-先后台直接通讯问题
先后台直接通讯问题以下:
存在的问题以下:
服务化不是银弹-团队协做问题
微服务的划分原则是难点,根据华为的经验:微服务划分不是一步到位,而是不断的迭代和演进,最终找到适合本身团队和业务的微服务划分原则。
将来演进方向-基于Docker部署微服务
使用Docker部署微服务的优势总结:
将来演进方向-云端微服务
利用云平台的弹性资源调度,动态性等,能够实现微服务的Dev&Ops
最后咱们一块儿回顾下服务化的演进历程:
Q&A
Q1:上面提到服务化缺点的第三条接口变动问题,请问微服务是如何解决这个问题的呢?或者说微服务相比之下什么优点会避免这个问题?
A1:根据咱们团队的经验,主要从以下几个方面下降影响:一、微服务的接口就是契约,制定 接口兼容性规范;涉及到技术和管理两个层面;二、微服务鼓励只作一件事情,所以它更加稳定;三、基于消费者契约测试,快速发现兼容性问题。
Q2:微服务架构里,分布式事务如何作的,对数据一致性要求较高的系统是否适合拆分红微服务,或者说微服务的粒度如何把握?
A2:分布式事务是难点,策略以下:1)若是业务上可以承受非强一致性,建议经过事务补偿的方式作最终一致性,能够基于MQ等中间件来实现;2)若是是转帐、实时计费、充值等对实时性要求高的,每每选择强一致性事务,就须要引入TCC等分布式事务框架。不管如何,只要作分布式,事务一致性就会成为问题,跟是不是微服务没必然关系。
Q3:生产环境中的服务注册中心必然是共享的,那如何去作灰度发布或者A/B Test呢?
A3:一种比较好的服务灰度策略是:1)服务框架提供灰度规则框架,包括后台引擎和前台Portal,由业务配置灰度规则;2)分布式服务框架支持灰度规则推送和业务自定义路由;3)前端SLB ,例如Ngix作灰度插件,接收灰度规则。消息从前端门户接入到后端服务路由,都支持基于规则的路由分发策略,实现灰度发布。
Q4:Netty的无锁化串行会比有锁的并行性能更高吗?有案例吗?华为如今都是用Docker部署应用吗?
A4:Netty的无锁化串行性能问题:1)在实际项目中,线程池争用模式和串行模式咱们都使用过,Netty的无锁化串行模式性能更高。Docker部署应用:华为的公有云和私有云都支持基于Docker部署应用,由客户根据须要自主选择。
Q5:IO通讯是怎么保证每次链接成功的呢?
A5:NIO通讯自己并不保证每次链接都成功,它的链接是异步的,你能够根据以下两种策略得到异步连接的结果:1)发起链接以后主动调用同步方法等待结果返回,阻塞式;2)获取异步链接Future,添加Listener监听器监听链接结果,这种模式是异步回调,不会阻塞当前线程。
Q6:使用zk做为服务注册中心,对与某个服务当客户端链接数不少时候节点变化会引发羊群效应,怎么处理这种问题呢?或者说如何避免这种问题呢?
A6:这个问题真是好!一般而言,你们会使用服务注册中心作服务可用性检测,若是发现某个服务节点不可用,就会将其从注册中心中删除。可是,有一种场景是ZK检测的结果跟客户端和服务端实际的链接状态不一致。从ZK看,服务提供者可使用。可是因为服务消费者跟提供者之间的链路已经中断,跟ZK的链路倒是正常,这种状况下就会出现状态不一致问题。因此,只依靠ZK作状态检测还不够,须要服务提供者和消费者的链路层作双向心跳检测。
Q7:我如今作的系统是zk作注册中心服务把地址注册上去(临时节点),客户端拿地址请求,http的,如今发现若是是公网调用的话,对公网资源要求还挺多的,zk公网, 应用公网;为了减小对公网需求,中间加一层nginx,把nx地址注册上去,不过又得加个http探测监控程序,异常还得删掉注册数据,不知道这种作法是否稳当?
A7:Ng监听ZK注册的服务提供者URL便可,问题不大。
Q8:用Netty作同通讯框架,监控上报应该怎么设计更完善?
A8:建议的方式以下:Netty自身不用告警,监听Netty的异常事件,而后经过MQ吐出去,监控系统订阅通讯框架的事件主题,实现通讯框架和监控系统解耦。
Q9:SOA和微服务架构的区别和联系是?看起来好像啊!
A9:1) 服务拆分粒度:SOA首先要解决的是异构应用的服务化;微服务强调的是服务拆分尽量小,最好是独立的原子服务;
2) 服务依赖:传统的SOA服务,因为须要重用已有的资产,存在大量的服务间依赖;微服务的设计理念是服务自治、功能单一独立,避免依赖其它服务产生耦合,耦合会带来更高的复杂度;
3) 服务规模:传统SOA服务粒度比较大,多数会采用将多个服务合并打成war包的方案,所以服务实例数比较有限;微服务强调尽量拆分,同时不少服务会独立部署,这将致使服务规模急剧膨胀,对服务治理和运维带来新的挑战;
4) 架构差别:微服务化以后,服务数量的激增会引发架构质量属性的变化,例如企业集成总线ESB(实总线)逐渐被P2P的虚拟总线替换;为了保证高性能、低时延,须要高性能的分布式服务框架保证微服务架构的实施;
5) 服务治理:传统基于SOA Governance的静态治理转型为服务运行态微治理、实时生效;
6) 敏捷交付:服务由小研发团队负责微服务设计、开发、测试、部署、线上治理、灰度发布和下线,运维整个生命周期支撑,实现真正的DevOps。
总结:量变引发质变,这就是微服务架构和SOA 服务化架构的最大差别。
Q10:若是要将现有单机服务重构到微服务,应该考虑哪些问题?数据迁移的安全问题怎么解决?有什么实践方案吗?
A10:须要考虑的问题以下:1)当前单机应用是否可以知足业务发展须要,有没有必要作服务化改造和分布式部署;2)评估迁移的工做量,以及人员技能培训等。3)自研服务框架仍是使用开源的方案。
数据迁移安全问题:若是内网,一般不会涉及到复杂的安全控制问题;若是跨公网,建议加入API Gateway统一作安全管控。
实践方案:公开的资料,能够参考淘宝的服务化实践、京东的服务化实践等。其实华为也有,不过遗憾的是目前政策不容许公开出来。
Q11:麻烦李老师介绍下大家华为内部基于netty作socke通讯的协议设计的最佳实践。
A11:这个问题很大,简单介绍下思路。在11年和13年的时候我分别主持设计了华为基于Mina和Netty的统一NIO通讯框架。设计要点以下:1)要熟悉Netty的线程调度模型、经常使用的类库等,可以熟练使用Netty;2)NIO通讯框架的分层原则,哪些该作、哪些不应作,须要识别出来;3)扩展点,预留足够的扩展点给上层应用协议栈作扩展;4)能够内置配置化的安全策略、握手认证、心跳检测等机制;5)可服务性设计,包括日志、性能KPI指标等。