"Architect" Journal Abstract (2015) 1

First, the architecture should be a process of continuous evolution from simple to complex . Engineering thinking drives people to develop an idealized system. However, the best architecture is often not the most ideal architecture, but the most suitable architecture. We have seen many cases where precious time is wasted due to over-architecture design, and even more so due to too many unrealistic assumptions that cause the architecture to fail to settle. The term for this phenomenon is called "analysis paralysis" .

    Therefore, an excellent architecture should combine business goals and seek an optimal point among trade-offs.

 

2. Distributed systems are divided into four dimensions in terms of scalability :

    1. Performance scalability: The performance cannot be scaled linearly, but try to use components with concurrency and asynchrony. A work queue with completion notifications is preferable to a synchronous connection to the database.

    2. Availability is scalable: CAP theory shows that distributed systems cannot provide guarantees of consistency, availability, and partition fault tolerance at the same time. Many large-scale web applications sacrifice strong consistency for availability and partition tolerance, which rely on eventual consistency for guarantees.

    3. Maintain scalability: When monitoring and updating applications using platforms and tools, automate as much as possible.

    4. Cost scalability: When designing a system, there is a trade-off between reusing existing components and developing completely new components.

 

    Based on the above content, 10 design principles are summarized:

    1. Avoid a single point of failure: Everything must have two. This adds cost and complexity, but offers benefits in availability and load performance.

    2. Scale horizontally: not scale up.

    3. Minimize the work that needs to be done in the core of the application. (The function of the program should be as clear and simple as possible, and do not let one component assume too many functions)

    4. API first: treat the application as a service that provides an API, and does not assume the type of client of the service (mobile application, web site, desktop application)

    5. Always cache.

    6. Provide data as new as possible: Users may not need to see the latest data immediately, but eventual consistency can lead to higher availability.

    7. Design with maintenance and automation in mind: Don't underestimate the time and effort required for application maintenance.

    8, rather asynchronous, asynchronous.

    9. Strive to be stateless: state information should be kept in as few places as possible, and it should be kept in specially designed components.

    10. Prepare for failure: Minimize the impact of failure on end users.

"Architectural Principles for Highly Scalable Distributed Applications" (November 2015)

3. Challenges faced by traditional architecture :

    1. Stability: Traditional monolithic applications stack all services together, which may affect the core services of the system due to problems with some unimportant services. In addition, the system has different requirements for services, and separate deployment can reduce the mutual influence between them.

    2. Maintainability: Multiple services are stacked together, increasing the maintenance cost of the code.

    3. API version iteration: In a single application, a system will correspond to many APIs, and according to the continuous iteration of the business, many versions of APIs will definitely be derived. The upgrade and maintenance of APIs require corresponding version management.

    4. Continuous integration: Due to the large size of the monolithic application, there are many dependencies within the application, and the business logic of the design is also relatively complex. In the CI process, if there is no good agreement, there will be more failures; in addition, because the code base is relatively large, the construction time will be very long, and troubleshooting will be difficult.

 

    Understanding of Microservices:

    1. In the concept of microservices, there are two key points, rapid release and decoupling. Both of these points can correspond to the architectural principles in OO. One is single responsibility, which is to make one thing the best, and the other is separation of concerns. Conway's Law states: When designing the architecture of a system, the resulting design is equivalent to the communication structure within and between organizations. Corresponding here, that is to say, microservices have a very close relationship with the company's organizational structure.

    2. The production process of microservices-innovated software, including development, testing, and deployment stages. However, the segmentation of services is not to adhere to the single principle, because it is impossible for future services to be completely vertically segmented.

    3. First of all, microservices do not refer to the code itself, it includes a series of workflows from code development to deployment to operation and maintenance. Secondly, when it comes to service splitting, it should be noted that the SLA of the service is different, and the splitting needs to consider which services are and which are secondary services. The bottom-level service directly determines the stability of the upper-level service.

    4. Serviceization is a form of componentization, and all components come from refactoring. The process is written from top to bottom. When it is written to a certain level, it will encounter the problem of separation and decoupling, and then it will be componentized, and then refactoring will occur.

    5、如康威定律说,系统架构和团队的组织架构有直接的关系。但并不是说为了微服务而调整组织架构,一般是考虑到业务的需求才调整团队的组织架构。团队与团队之间不要有太多的依赖。微服务涉及到你能否快速提供环境的能力、文化的改变、快速部署、监控等多方面的能力,当这些条件都具备之后,再考虑是否微服务。

 

    服务治理:

    1、有三个需要注意的,一是接口的统一性,如果没有接口规范,那么效率马上就会下降。之前可以像游击队一样打,但是人多了之后,还是像正规军一样战斗力会比较强;二是容错一定要做好,这块可以参考Netflix开源的几个组件。容错如果没有做好,在服务化这样的系统里,很有可能造成雪崩效应,容错的方案也有很多,比如限流、回退、隔离、熔断;三是监控,在微服务出错之后,团队需要快速定位出错的位置和原因。

    2、服务治理,可以选择比较良好的服务框架,比如Dubbo等。

    3、服务方需要指导服务会被多少人调用,被那些业务调用,每个时间点上的状态是怎么样的。另外,阿里的eagleeye和点评的CAT监控系统,支持对服务调用链和依赖关系进行可视化监控,可以参考学习。

    4、微服务中,服务的测试是个非常大的挑战。服务与服务之间会存在依赖,所以环境的搭建可能会涉及到多个团队,这个时候就需要能够快速的部署环境,当然现在比较推荐的方案是容器。(Docker)

    5、微服务,其实对应的是微业务,为了适应业务的多变、面向最终用户的个性化需求。而微服务的力度,很大程度上是取决于完成一项业务所要设计的数据存储所在的区域。微服务的监控,包括业务、应用、系统多个层次,日志、Metrics、调用链、告警等多个维度。

    6、提到监控,大家一般都是从系统、应用等层面去考虑。

《先把平台做扎实,再来微服务吧》(2015年11月)

四、大规模弹性架构的主要设计目标是系统的高可用和高扩展性:根据系统的实际需要,系统自动弹性分配资源。在需求量大,比如峰值的时候,系统自动调配足够的资源;在访问量小,系统自动释放出部分资源,从而实现资源的按需分配。那么大规模弹性架构的基本原理是什么?其主要是利用高性能虚拟化技术,实现计算、存储和网络资源的统一调度和弹性分配。

    1、实现动态部署:为了应对突发峰值访问量或者可能的网络攻击,需要在应用服务器内部部署一些监控程序,由主控程序判断当前整个集群的负载情况,自动增加或者减少服务节点,并且自动部署应用程序,从而从容的应对突增的业务流量。

    2、实现故障自动恢复。当一台物理机损坏时,系统需要自动监测到硬件故障,并且在第一时间内,把云服务器迁移到新的宿主机器上,同时硬盘数据需要保持最后一刻的状态。

《卷首语》(2015年12月)

五、根据负载均衡LB所在位置的不同,目前主要的服务注册、发现和负载均衡方案有三种

    第一种是集中式LB:在服务消费者和服务提供者之间提供一个独立的LB层,此LB通常有专门的软硬件来实现(F5、LVS、Haproxy,nginx等)。LB上有所有服务的地址映射表,通常有运维配置注册,当服务消费放调用某个目标服务时,它向LB发起请求,由LB以某种策略(比如Round-Robin)做负责均衡后将请求转发到目标服务。LB一版具备健康检查能力,能自动摘除不健康的服务实例。服务消费方如何发现LB呢?通常的做法是通过DNS,运维人员为服务配置一个DBS域名,这个域名指向LB。

    集中式LB方案实现简单,容易做到集中式访问控制,这一方案目前还是业界主流。集中式LB的主要问题是单点问题,所有的服务调用流量都经过LB,当服务数量和调用量大的时候,LB容易成为瓶颈;此外,LB在服务消费方和提供方之间增加了一跳(hop),有一定的性能开销。

    第二种是进程内LB方案,针对集中式LB的不足,进程内LB方案将LB的功能以lib库的方式集成到服务消费放进程内(比如JVM内),该方案也被称为软负载或者客户端负载方案。这一方案需要一个服务注册表(Service Registry)配合支持服务自注册和自发现,服务提供方启动时,首先将服务地址注册到服务注册表(同时定期报心跳到服务注册表以表明服务的存活状态,相当于健康检查),服务消费方要访问某个服务时,它通过内置的LB组件向服务注册表查询(同时缓存并定期刷洗、同步)目标服务地址列表,然后以某种负载均衡策略选择一个目标服务地址,最后向目标服务发起请求。这一方案对服务注册表的可用性要求很高,一般采用能满足高可用分布式一致的组件(zookeeper)。

    进程内LB方案是一种分布式方案,LB和服务发现能力被分散到每一个服务消费者进程内部,同时服务消费方和服务提供者之间是直接调用,没有额外开销,性能相对较好。它的问题出现在:1)类库的升级需要协同服务提供方、服务消费方一起进行,推动阻力很大。 2)服务注册中心的可用性需要有较高的保证 3)客户端对服务的均衡策略需要自助开发。

 

    进程内LB的案例是Netfflix的开元服务框架,对应的组件分别是:Eureka服务注册表,Karyon服务端框架支持服务自注册和健康检查,Ribbon客户端框架支持服务自发现和软路由。另外,阿里开源的Dobbo也采用了类似的机制。

    第三种是主机独立的LB进程方案,该方案是针对第二种方案的不足而提出的一种折中方案,原理和第二种方案基本类似,不同之处是,他将LB和服务发现的功能从进程内移出来,变成朱姐上的一个独立进程,主机上的一个或者多个服务要访问目标服务时,它们都通过同一主机上的独立LB进程做服务发现和负载均衡。(简而言之,就是将LB进程单独部署为每个服务消费方的本地机器上)这种方案也是分布式方案,没有单点问题,一个LB进程挂了只会影响该主机上的服务调用方,服务调用方和LB之间是本地“进程间”调用,性能较好(无网络开销);同时,该方案还简化了服务调用方,不需要为不同的语言开发客户端lib,LB的升级不需要服务调用方改代码;但是它的不足就是部署复杂,环节较多,对问题排查不便。(类似于每个服务消费方的本地部署一个Haproxy、nginx)。

 

    服务容错:

    当企业微服务化以后,服务之间会有错综复杂的依赖关系,例如,一个前端请求一般会依赖于多个后端服务,技术上称为1->扇出(fan-out),在实际的生产环境中,服务往往不是百分之百的可靠,服务可能会出错或者产生延迟,如果一个应用不能对其依赖的故障进行容错和隔离,那么该应用本身就出在被拖垮的风险中,在一个高流量的网站中,某个单一祸端一旦繁盛延迟,可能在数秒内导致所有应用资源(线程、队列等)被耗尽,造成所谓的雪崩效应(Cascading-failure),严重时可能导致整个网站瘫痪。

    1)电路熔断器模式(Cicuit Breaker Pattern):该模式的原理类似于家里的电路熔断器,如果电路发生短路,熔断器能够主动熔断电路以避免灾难性损失。在分布式系统中应用电路熔断模式后,当目标服务慢或者大量超时时,调用方能够主动熔断,以防止服务被进一步的拖垮;如果情况又好转了,电路又能自动恢复,这就是所谓的弹性容错,系统有自恢复能力。

    正常情况下,电路处于关闭状态,如果调用持续出错或者超时,电路被打开进入熔断状态,后续一段时间内的所有调用都会被拒绝(Fail Fast),一段时间后,保护器会尝试进入版熔断状态,允许少量请求进来尝试,如果调用仍然失败,则继续回到熔断状态,如果调用成功,则回到电路闭合状态。

 

    2)舱壁隔离模式:该模式像舱壁一样对资源或者失败单元进行隔离,如果一个船舱进水,只损失一个船舱,其他船舱不受影响。线程隔离(Thread isolation)就是船舱隔离模式的一个例子,假定一个应用程序A调用了“S1/S2/S3”三个服务,且部署A的容器共有120个工作线程,采用线程隔离机制,可以给S1/S2/S3的调用各分配40个线程,当S2慢了,给S2分配的40个线程因为慢而阻塞并且最终耗尽,线程隔离可以保证给S1/S2/S3分配的80个线程可以不受影响;如果没有这种隔离机制,当S2慢的时候,120个工作线程会很快全部被对S2的调用耗尽,整个应用程序会全部慢下来。

    3)限流(Rate limiting):服务总有容量限制,没有限流机制的服务很容易在突发流量的时候被冲垮。限流通常指对服务限定并发访问量,比如单位时间内只允许100个并发调用,对超过这个限制的请求要拒绝并回退。

    4)回退(fallback):在熔断或者限流发生的时候,会触发回退机制,回退是系统的弹性恢复能力,常见的处理策略有,直接抛出异常,也成为快速失败(Fail Fast),也可以返回空值或者缺省值,还可以返回备份数据,如果主服务熔断了,可以从备份服务获取数据。

 

    目前比较主流的微服务框架有Netflix的Karyon/Ribbon,Spring Boot/Cloud,阿里的Dubbo。

    目前比较成熟的“运行时配置管理”组件有Spring Cloud Config。

    Netflix的微服务框架(这些框架已经开源,并集成在了Spring Cloud中):

    1、Eureka:服务注册发现框架。

    2、Zuul:服务网关。

    3、Karyon:服务端框架

    4、Ribbon:客户端框架。

    5、Hystrix:服务容错组件。

    6、Archaius:服务配置组件。

    7、Servo:Metrics组件

    8、Blitz4j:日志组件。

 

    对于一些打算构建微服务框架体系的公司来说,充分利用或者参考借鉴Netflix的开源微服务组件(或者Spring Cloud),在此基础上进行必要的企业定制,无疑是通向微服务架构的捷径。

《实施微服务,我们需要哪些基础框架?》(2015年12月)

 

六、互联网时代的产品通常有两类特点:需求变化快和用户群体庞大。在这种情况下,如何从系统架构的角度出发,构建灵活、易扩展的系统,快速应付需求的变化;同时,随着用户量的增加,如何

保证系统的可伸缩性、高可用性,成为系统架构师面临的挑战。

 

    早在1996年,Gartner就提出面向服务架构(SOA)。SOA阐述了“对于复杂的企业IT系统,应按照不同的、可重用的粒度划分,将功能相关的一组功能提供者组织在一起为消费者提供服务”,其目的是为了解决企业内部不同IT资源之间无法互联而导致的信息孤岛问题。

    

    事实上,微服务架构并不是一个全新的概念,其思想与SOA几乎一致,它们之间的主要区别:

    SOA实现                                                      微服务架构实现

    企业级,自顶向下开发                                团队级,自底向上开展

    服务有多个子系统组成                                一个系统被拆分为多个服务

    粒度大                                                       粒度细

    企业服务总线,集中式的服务架构               无集中式总线,松散的服务架构

    集成方式复杂--ESB/WS/SOAP                   集成方式简单---HTTP/REST/JSON

    单体系统架构,相互依赖,部署复杂            服务都能独立部署

    

    由此可见,相对于传统的SOA服务实现方式,微服务更具有灵活性、可实施性以及可扩展性,其强调的是一种独立测试、独立部署、独立运行的软件架构模式。

    

    ThoughtWorks首席科学家马丁-福勒对微服务的一个描述如下:

    “微服务架构师一种架构模式,它提倡将单一应用程序划分为一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTFul API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应该尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建”。

    

    总结下来,微服务架构中的核心部分包括如下几点:

    1)小,且专注于做一件事情

    2)独立的进程中

    3)轻量级的通信机制

    4)松耦合、独立部署

    《解析微服务架构(二)微服务架构综述》(2015年8月) 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326645384&siteId=291194637