并发网络编程设计

5种网络I/O模型

网络IO过程

阻塞式IO

阻塞IO

描述:
	当用户进程调用了recv()/recvfrom()这个系统调用,kernel就开始准备数据。
	用户进程被挂起,直到数据被拷贝到操作系统内核的缓冲区中,
	然后从kernel中拷贝到用户内存,kernel返回结果。
	这时用户进程才解除block的状态,被唤醒,重新运行。
特点:
	阻塞IO方式,编程简单,适合教学。
	缺点在于如果套接字上没有数据,进程将一直阻塞。
	这时其他套接字上有数据也不能进行及时处理。
	如果是多线程方式,除非连接关闭否则线程会一直存在,
	而线程的创建、维护和销毁非常消耗资源,所以能建立的连接数量非常有限。

非阻塞IO

非阻塞IO

描述:
	这是一个轮询的过程。每次用户询问内核是否有数据报准备好(文件描述符缓冲区是否就绪)。
	当数据报准备好的时候,就进行拷贝数据报的操作。
	当数据报没有准备好的时候,不阻塞程序,
	内核直接返回未准备就绪的信号,等待用户程序的下一次轮询。
特点:
	代码编写相对简单,进程不会阻塞,可以在同一线程中处理所有连接。
	缺点在于需要频繁的轮询,比较耗CPU,在并发量很大的时候将花费大量时间在没有任何数据的连接上轮询。
典型非阻塞示例:

while(true){

   data = socket.read();

   if(data!= error){
       process();
       break;
   }
}

I/O复用

IO复用

描述:
	应用进程阻塞于select/poll/epoll等系统函数等待某个连接变成可读(有数据过来),再调用recvfrom从连接上读取数据。
	虽然此模式也会阻塞在select/poll/epoll上,但与阻塞IO模型不同它阻塞在等待多个连接上有读(写)事件的发生,
	明显提高了效率且增加了单线程/单进程中并行处理多连接的可能。
特点:
	通过一个线程就可以管理多个socket,只有当socket真正有读写事件发生才会占用资源来进行实际的读写操作。
	因此,多路复用IO比较适合连接数比较多的情况。
	缺点在于当 select/poll/epoll 管理的连接数过少时,这种模型将退化成阻塞 IO 模型。
	并且还多了一次系统调用:一次 select/poll/epoll 一次 recvfrom。
	一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。

信号驱动IO

信号驱动IO

描述:
	当用户线程发起一个IO请求操作,会给对应的socket注册一个信号函数,然后用户线程会继续执行,
	当内核数据就绪时会发送一个信号给用户线程,
	用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作。
特点:
	这是一种非阻塞的模式非阻塞。
	缺点在于前一个通知信号没被处理的情况下,后一个信号来了也不能被处理。
	信号量大的时候会导致后面的信号不能被及时感知。

异步IO

异步IO

描述:
	应用线程通过aio_read告知内核启动某个操作,
	并且在整个操作完成之后再通知应用进程,包括把数据从内核空间拷贝到用户空间。
特点:
	没有任何阻塞,充分利用系统内核将IO操作与计算逻辑并行。
	缺点在于编程复杂、操作系统支持不好。
	只有 windows 下的 iocp 实现了真正的 AIO。linux 下在 2.6 版本中才引入,并不完善。

常见并发服务器方案

迭代式服务器

迭代式服务器程序框架:

int listenfd, connfd;
listenfd = socket( ... );
bind(listen, ... );
listen(listenfd,LISTENQ);
for(;;)
{
    connfd = accept(listenfd, ... );
    doit(connfd);
    close(connfd);
}
特点:
	无法充分利用多核CPU,不适合执行时间较长的任务

并发式服务器

多进程并发服务器程序框架:

bind(srvfd);  
listen(srvfd);  
for(;;){  
    clifd=accept(srvfd,...); 
    ret=fork();  
    switch(ret)  
    {  
      case -1:  
        _exit(1);    
        break;  
      case 0:       
        process(clifd);  
        break;  
      default:    
        close(clifd);  
        continue;  
    }  
}  

多线程并发服务器程序框架:

void *thread_callback( void *args ) 
{  
     int clifd = *(int *)args ;  
     thread_handler(clifd);  
}void thread_handler(clifd){  
    read(clifd,buf,...);       
    do_somthing(buf);    
    write(clifd,buf)        
}int main()
{
    bind(srvfd);  
    listen(srvfd);  
    for(;;){  
        clifd = accept();  
        pthread_create(...,thread_callback,&clifd);  
    }  
}
特点:
	one connection per process/one connection per thread,系统资源有限利用率低,
	无法处理大量并发连接。创建进程(线程)增加了响应延迟。

prefork or pre threaded

特点:
	预先创建服务进程(线程)池,当连接到来时子进程(线程)竞争服务。
	与并发服务器相似,同样存在并发连接数不足的问题。但响应延迟更低
prefork流程:

1)父进程listen,创建pipe(下面所有父子进程之间的通信都用该pipe)
2)父进程预fork n个子进程
3)各个子进程accept(listenfd),即所有子进程竞争accept请求。
	由于listenfd是在fork之前就有的,所以所有子进程都可以访问到,不需用到“进程间文件描述符传递”问题;
4)子进程每accept到一个请求都告诉父进程,父进程把请求数加1;
	子进程没完成一个请求,父进程把请求数减1;
	当父进程发现请求数 >= 子进程数时,父进程创建新的子进程,并把子进程数加1(当然子进程数有个预先上限);
	当父进程发现子进程数大于请求数加1时,父进程杀死多余的子进程。

Reactor模式

针对传统阻塞I/O服务模型的缺点,比较常见的有如下解决方案:
	1)基于I/O复用模型:多个连接共用一个阻塞对象,应用程序只需要在一个阻塞对象上等待,无需阻塞等待所有连接。
	当某条连接有新的数据可以处理时,操作系统通知应用程序,线程从阻塞状态返回,开始进行业务处理;
	2)基于线程池复用线程资源:不必再为每个连接创建线程,
	将连接完成后的业务处理任务分配给线程进行处理,一个线程可以处理多个连接的业务。

I/O复用结合线程池,这就是 Reactor 模式基本设计思想:

Reactor模式

Reactor模式简介:
	是指通过一个或多个输入同时传递给服务处理器的服务请求的事件驱动处理模式。
	服务端程序通过I/O复用的方式处理传入多路请求,并将它们同步分派给请求对应的处理线程,
	因此Reactor模式也叫Dispatcher模式。
	
Reactor模式特点:
	1)响应快,不必为单个同步时间所阻塞,虽然Reactor本身依然是同步的;
	2)编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;
	3)可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源;
	4)可复用性,Reactor模型本身与具体事件处理逻辑无关,具有很高的复用性。

Reactor模式分类:
	根据 Reactor 的数量和处理资源池线程的数量不同,有3种典型的实现:		
	1)单 Reactor 单线程;
	2)单 Reactor 多线程;
	3)主从 Reactor 多线程。
单Reactor单线程

单Reactor单线程

流程描述:
	1)Reactor对象通过select/poll/epoll监控客户端请求事件,收到事件后通过dispatch 进行分发;
	2)如果是建立连接请求事件,则由Acceptor通过accept处理连接请求,然后创建一个Handler对象处理连接完成后的后续业务处理;
	3)如果不是建立连接事件,则Reactor会分发调用连接对应Handler来响应;
	4)Handler会完成read→业务处理→send 的完整业务流程。

优点:
	模型简单,没有多线程、进程通信、竞争的问题,全部都在一个线程中完成。
	当客户端的数量有限,业务处理非常快速时适合使用,比如 Redis。
缺点:
	只有一个线程,无法完全发挥多核 CPU 的性能。
	在处理某个连接上的业务时,无法接受其他连接,容易导致性能瓶颈。可靠性差。
单Reactor多线程

单Reactor多线程

流程描述:
	1)Reactor对象通过select/poll/epoll监控客户端请求事件,收到事件后通过dispatch进行分发;
	2)如果是建立连接请求事件,则由Acceptor通过accept处理连接请求,然后创建一个Handler对象处理连接完成后续的各种事件;
	3)如果不是建立连接事件,则Reactor会分发调用连接对应的Handler来响应;
	4)Handler只负责响应事件,不做具体业务处理,通过read读取数据后,会分发给后面的Worker线程池进行业务处理;
	5)Worker线程池会分配独立的线程完成真正的业务处理,如何将响应结果发给 Handler进行处理;
	6)Handler收到响应结果后通过send将响应结果返回给Client。

优点:
	可以充分利用多核 CPU 的处理能力。
缺点:
	多线程数据共享和访问比较复杂;Reactor承担所有事件的监听和响应,在单线程中运行,高并发场景下容易成为性能瓶颈。
主从Reactor多线程

主从Reactor多线程

流程描述:
	1)Reactor主线程MainReactor对象通过select/poll/epoll监控建立连接事件,收到事件后通过Acceptor接收,处理建立连接事件;
	2)Acceptor处理建立连接事件后,MainReactor将连接分配Reactor子线程给 SubReactor进行处理;
	3)SubReactor将连接加入连接队列进行监听,并创建一个Handler用于处理各种连接事件;
	4)当有新的事件发生时,SubReactor会调用连接对应的Handler进行响应;
	5)Handler通过read读取数据后,会分发给后面的Worker线程池进行业务处理;
	6)Worker线程池会分配独立的线程完成真正的业务处理,如何将响应结果发给 Handler进行处理;
	7)Handler收到响应结果后通过send将响应结果返回给Client。

优点:
	父线程与子线程的数据交互简单职责明确,父线程只需要接收新连接,子线程完成后续的业务处理。
	父线程与子线程的数据交互简单,Reactor 主线程只需要把新连接传给子线程,子线程无需返回数据。
	这种模型在许多项目中广泛使用,包括Nginx主从Reactor多进程模型,Memcached主从多线程,Netty主从多线程模型的支持。

Proactor模式

Proactor模式

异步Proactor:
	在Reactor模式中,Reactor等待某个事件或者可应用或者操作的状态发生(比如文件描述符可读写,或者是Socket 可读写)。
	然后把这个事件传给事先注册的Handle(事件处理函数或者回调函数),由后者来做实际的读写操作。
	其中的读写操作都需要应用程序同步操作,所以Reactor是非阻塞同步网络模型。
	如果把I/O操作改为异步,即交给操作系统来完成就能进一步提升性能,这就是异步网络模型Proactor。

流程描述:
	1)Proactor Initiator创建Proactor和Handler对象,并将Proactor和Handler 都通过AsyOptProcessor(Asynchronous Operation Processor)注册到内核;
	2)AsyOptProcessor处理注册请求,并处理 I/O 操作;
	3)AsyOptProcessor完成I/O操作后通知 Proactor;
	4)Proactor根据不同的事件类型回调不同的Handler进行业务处理;
	5)Handler完成业务处理。

Proactor和Reactor的区别:
	1)Reactor是在事件发生时就通知事先注册的事件(读写在应用程序线程中处理完成);
	2)Proactor是在事件发生时基于异步I/O完成读写操作(由内核完成),待I/O操作完成后才回调应用程序的处理器来进行业务处理。
	理论上Proactor比Reactor效率更高,异步I/O更加充分发挥DMA(Direct Memory Access,直接内存存取)的优势。

Proactor缺点如下:
	1)编程复杂性,由于异步操作流程的事件的初始化和事件完成在时间和空间上都是相互分离的,因此开发异步应用程序更加复杂。
	应用程序还可能因为反向的流控而变得更加难以Debug;
	2)内存使用,缓冲区在读或写操作的时间段内必须保持住,可能造成持续的不确定性,
	并且每个并发操作都要求有独立的缓存,相比Reactor模式,在socket已经准备好读或写前,是不要求开辟缓存的;
	3)操作系统支持,Windows下通过IOCP实现了真正的异步I/O,而在 Linux 系统下,Linux 2.6才引入,异步I/O还不完善。

高并发服务器设计

服务器的设计目标与性能

服务器设计目标
	1)高性能:对于大量请求,及时快速的响应
	2)高可用:服务器24h都可用,故障可转移备机
	3)伸缩性:使用跨机器的通信,分布式存储,方便拓展
影响性能的因素
	1)数据拷贝:利用缓存来解决
	2)理性创建线程:
		单核服务器,采用状态机编程,效果最好,因为大量的任务,提交到服务器,会增加线程间的切换开销;
		多核服务器,多线程能够充分发挥多核服务器的性能,也要尽可能减少线程之间的上下文切换。
	3)内存分配:
		增加内存池,减少对OS申请内存
	4)锁竞争:
		用逻辑避免锁的使用,减少锁的使用
性能瓶颈与优化
数据库瓶颈与优化
	1)队列+连接池:
		采用DAL(Data Access Layer)队列服务+连接池的设计,
		DAL与DB的连接放到连接池里面,下次访问直接从连接池中取出一个连接,节省新连接创建的开销
	2)程序设计合理:
		主要的业务处理应该放在应用服务器(即操作系统上面),而数据库只做辅助的业务处理,来降低数据库压力
	3)使用缓存可以减少对数据库的访问:
		缓存更新:
			设置缓存过期时间,当缓存失效,就重新去数据库查询,再更新缓存,实时性较差,实现简单;
			一旦数据库中的数据更新,立即通知前端的缓存更新,实时性比较高,实现复杂
		缓存换页:
			若内存不够,就将不活跃的数据换出内存:FIFO,LRU(least recently used最近最少使用),LFU(Least frequently used)最不频繁使用
	4)数据库读写分离:
		数据库的写操作,会把数据库锁住,那么其它的业务请求过来就会阻塞住,等待写操作完成
		对大部分的应用来说,数据库的读操作比写操作频繁,可以使用replication机制对数据库进行负载均衡
		master负责写操作,slave负责读操作。master发生数据改变,需要将数据同步到slave数据库(方法:通过日志文件进行同步),
		这也叫做replication机制
	5)数据分区(分库、分表):
		分库:垂直分区
			若数据库有:用户表,业务表,基础表,可将其分为三个库。
		分表:水平分区
		若数据库有:若用户表是10条记录,就将其分到10个数据库,每个数据库只有1条记录。

应用服务器瓶颈
	添加任务服务器对应用服务器的任务分配进行负载均衡。
	任务服务器可以监控app应用服务器的状态(通过暴露接口的方式给任务服务器),
	app服务器相当于http服务端,任务服务器相当于http客户端。负载均衡又分为主动和被动两种方案:
	1)应用服务器被动接受方案:
		任务服务器来可以监视应用服务器的负载,CPU,IO,并发,内存换页,查询到这些信息之后,选取负载最低的服务器来分配任务;
	2)应用服务器主动到任务服务器接受任务进行处理:
		应用服务器处理完自己的任务后主动向任务服务器申请求任务。
	第一种方式可能会造成不公平,但是实现简单;
	第二种方式的缺点是如果应用服务器处理不同的业务,那么可能任务服务器的编程逻辑会很复杂。
	其中任务服务器可以设置多台,彼此之间通过心跳联系,以满足高可用性。
	
	如此一来(数据库,缓存,应用服务器,任务服务器)任何位置出现瓶颈就只需要增加服务器。

服务器的架构演化

单机架构

在这里插入图片描述

	服务器和数据库部署在同一台服务器上,随着用户数的增长,服务器和数据库之间竞争资源,单机性能不足以支撑业务
服务器与数据库分离

在这里插入图片描述

	服务器和数据库分别独占服务器资源,显著提高两者各自性能。
	随着用户数的增长,并发读写数据库成为瓶颈
本地缓存和分布式缓存

在这里插入图片描述

	在同服务器上增加本地缓存,并在外部增加分布式缓存,缓存热点数据。大大降低数据库压力。
	使用memcached作为本地缓存,使用Redis作为分布式缓存。
	关键词:缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效。
	随着并发数的增长,单机服务器响应逐渐跟不上
反向代理与负载均衡

在这里插入图片描述

	在多台服务器上分别部署服务器,使用反向代理软件(Nginx)把请求均匀分发到每个服务器中。
	关键词:Nginx、HAProxy、http协议、session共享、文件上传下载。
	并发量的增长意味着更多请求到数据库,单机数据库又成为瓶颈
数据库读写分离

在这里插入图片描述

	把数据库划分为读库和写库,读库可以有多个,通过同步机制把写库的数据同步到读库,
	对于需要查询最新写入数据场景,可通过在缓存中多写一份,通过缓存获得最新数据。
	关键词:Mycat(它是数据库中间件,可通过它来组织数据库的分离读写和分库分表,客户端通过它来访问下层数据库),
			数据同步,数据一致性。	
	业务逐渐变多,不同业务之间的访问量差距较大,不同业务直接竞争数据库,相互影响性能
数据库分库

在这里插入图片描述

	把不同业务的数据保存到不同的数据库中,使业务之间的资源竞争降低,
	对于访问量大的业务,可以部署更多的服务器来支撑。
	这样同时导致跨业务的表无法直接做关联分析,需要通过其他途径来解决。
	随着并发量进一步的增长,单机的写库会逐渐会达到性能瓶颈
数据库分表

在这里插入图片描述

	针对评论数据,可按照商品ID进行hash,路由到对应的表中存储;
	针对支付记录,可按照小时创建表,每个小时表继续拆分为小表,使用用户ID或记录编号来路由数据。
	只要实时操作的表数据量足够小,请求能够足够均匀的分发到多台服务器上的小表,
	那数据库就能通过水平扩展的方式来提高性能。Mycat也支持在大表拆分为小表情况下的访问控制。
	数据库和服务器都能够水平扩展,可支撑的并发大幅提高,随着用户数的增长,最终单机的Nginx会成为瓶颈。
使用LVS或F5来使多个Nginx负载均衡

在这里插入图片描述

	由于瓶颈在Nginx,因此无法通过两层的Nginx来实现多个Nginx的负载均衡。LVS和F5是工作在网络第四层的负载均衡解决方案,
	其中LVS是软件,运行在操作系统内核态,可对TCP请求或更高层级的网络协议进行转发,因此支持的协议更丰富,并且性能也远高于Nginx;
	F5是一种负载均衡硬件,与LVS提供的能力类似,性能比LVS更高,但价格昂贵。
	由于LVS是单机版的软件,若LVS所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点。
	可使用keepalived软件模拟出虚拟IP,然后把虚拟IP绑定到多台LVS服务器上。
	浏览器访问虚拟IP时,会被路由器重定向到真实的LVS服务器,
	当主LVS服务器宕机时,keepalived软件会自动更新路由器中的路由表,把虚拟IP重定向到另外一台正常的LVS服务器,从而达到LVS服务器高可用的效果。
	全部Nginx不一定都转发请求到全部的Tomcat,可能是几个Nginx下面接一部分的Tomcat,
	这些Nginx之间通过keepalived实现高可用,其他的Nginx接另外的Tomcat,这样可接入的Tomcat数量就能成倍的增加。
	由于LVS也是单机的,随着并发数增长到几十万时,LVS服务器最终会达到瓶颈,此时用户数达到千万甚至上亿级别,
	用户分布在不同的地区,与服务器机房距离不同,导致了访问的延迟会明显不同
DNS轮询实现机房间的负载均衡

在这里插入图片描述

	在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP。
	当用户访问同一个域名时,DNS服务器会使用轮询策略或其他策略,来选择某个IP供用户访问。此方式能实现机房间的负载均衡。
	至此,系统可做到机房级别的水平扩展,千万级到亿级的并发量都可通过增加机房来解决,系统入口处的请求并发量不再是问题。
	随着数据的丰富程度和业务的发展,检索、分析等需求越来越丰富,单单依靠数据库无法解决如此丰富的需求。
引入NoSQL数据库和搜索引擎等技术

在这里插入图片描述

  当数据库中的数据多到一定规模时,数据库就不适用于复杂的查询了,往往只能满足普通查询的场景。对于统计报表场景,在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢,对于全文检索、可变数据结构等场景,数据库天生不适用。
  因此需要针对特定的场景,引入合适的解决方案。如对于海量文件存储,可通过分布式文件系统HDFS解决,对于key value类型的数据,可通过HBase和Redis等方案解决,对于全文检索场景,可通过搜索引擎如ElasticSearch解决,对于多维分析场景,可通过Kylin或Druid等方案解决。
  当然,引入更多组件同时会提高系统的复杂度,不同的组件保存的数据需要同步,需要考虑一致性的问题,需要有更多的运维手段来管理这些组件等。
  引入更多组件解决了丰富的需求,业务维度能够极大扩充,随之而来的是一个应用中包含了太多的业务代码,业务的升级迭代变得困难。

大应用拆分为小应用

在这里插入图片描述

  按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。这时候应用之间可能会涉及到一些公共配置,可以通过分布式配置中心Zookeeper来解决。
  不同应用之间存在共用的模块,由应用单独管理会导致相同代码存在多份,导致公共功能升级时全部应用代码都要跟着升级

复用的功能抽离成微服务

在这里插入图片描述

  如用户管理、订单、支付、鉴权等功能在多个应用中都存在,那么可以把这些功能的代码单独抽取出来形成一个单独的服务来管理,这样的服务就是所谓的微服务。
  应用和服务之间通过HTTP、TCP或RPC请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理。此外,可以通过Dubbo、SpringCloud等框架实现服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性。
  不同服务的接口访问方式不同,应用代码需要适配多种访问方式才能使用服务,此外,应用访问服务,服务之间也可能相互访问,调用链将会变得非常复杂,逻辑变得混乱

引入企业服务总线ESB屏蔽服务接口的访问差异

在这里插入图片描述

  通过ESB统一进行访问协议转换,应用统一通过ESB来访问后端服务,服务与服务之间也通过ESB来相互调用,以此降低系统的耦合程度。
  这种单个应用拆分为多个应用,公共服务单独抽取出来来管理,并使用企业消息总线来解除服务之间耦合问题的架构,就是所谓的SOA(面向服务)架构。
  微服务架构更多是指把系统里的公共服务抽取出来单独运维管理的思想,而SOA架构则是指一种拆分服务并使服务接口访问变得统一的架构思想,SOA架构中包含了微服务的思想。
  业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂,同一台服务器上部署多个服务还要解决运行环境冲突的问题。
  此外,对于需要动态扩缩容的场景,需要水平扩展服务的性能,就需要在新增的服务上准备运行环境,部署服务等,运维将变得十分困难。

引入容器化技术实现运行环境隔离与动态服务管理

在这里插入图片描述

  目前最流行的容器化技术是Docker,最流行的容器管理服务是Kubernetes(K8S),应用/服务可以打包为Docker镜像,通过K8S来动态分发和部署镜像。
  Docker镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用/服务的运行代码,运行环境根据实际的需要设置好。
  把整个“操作系统”打包为一个镜像后,就可以分发到需要部署相关服务的机器上,直接启动Docker镜像就可以把服务起起来,使服务的部署和运维变得简单。
  在大促的之前,可以在现有的机器集群上划分出服务器来启动Docker镜像,增强服务的性能,大促过后就可以关闭镜像,对机器上的其他服务不造成影响。
  使用容器化技术后服务动态扩缩容问题得以解决,但是机器还是需要公司自身来管理,在非大促的时候,还是需要闲置着大量的机器资源来应对大促,机器自身成本和运维成本都极高,资源利用率低。

以云平台承载系统

在这里插入图片描述

  系统可部署到公有云上,利用公有云的海量机器资源,解决动态硬件资源的问题,在大促的时间段里,在云平台中临时申请更多的资源,结合Docker和K8S来快速部署服务,在大促结束后释放资源,真正做到按需付费,资源利用率大大提高,同时大大降低了运维成本。
  所谓的云平台,就是把海量机器资源,通过统一的资源管理,抽象为一个资源整体,在之上可按需动态申请硬件资源(如CPU、内存、网络等),并且之上提供通用的操作系统,提供常用的技术组件(如Hadoop技术栈,MPP数据库等)供用户使用,甚至提供开发好的应用,用户不需要关系应用内部使用了什么技术,就能够解决需求(如音视频转码服务、邮件服务、个人博客等)。在云平台中会涉及如下几个概念:

  • IaaS:基础设施即服务。对应于上面所说的机器资源统一为资源整体,可动态申请硬件资源的层面;
  • PaaS:平台即服务。对应于上面所说的提供常用的技术组件方便系统的开发和维护;
  • SaaS:软件即服务。对应于上面所说的提供开发好的应用或服务,按功能或性能要求付费。

架构设计原则

	1)N+1设计。系统中的每个组件都应做到没有单点故障;
	2)回滚设计。确保系统可以向前兼容,在系统升级时应能有办法回滚版本;
	3)禁用设计。应该提供控制具体功能是否可用的配置,在系统出现故障时能够快速下线功能;
	4)监控设计。在设计阶段就要考虑监控的手段;
	5)多活数据中心设计。若系统需要极高的高可用,应考虑在多地实施数据中心进行多活,至少在一个机房断电的情况下系统依然可用;
	6)采用成熟的技术。刚开发的或开源的技术往往存在很多隐藏的bug,出了问题没有商业支持可能会是一个灾难;
	7)资源隔离设计。应避免单一业务占用全部资源;
	8)架构应能水平扩展。系统只有做到能水平扩展,才能有效避免瓶颈问题;
	9)非核心则购买。非核心功能若需要占用大量的研发资源才能解决,则考虑购买成熟的产品;
	10)使用商用硬件。商用硬件能有效降低硬件故障的机率;
	11)快速迭代。系统应该快速开发小功能模块,尽快上线进行验证,早日发现问题大大降低系统交付的风险;
	12)无状态设计。服务接口应该做成无状态的,当前接口的访问不依赖于接口上次访问的状态。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值