1、单体架构:
这是我们最初的一个系统架构:无论我们是什么样的一个客户端,UI呈现是一个什么样的,后端都只有一个,相对比较简单;
以前项目就一个进程,各种模块项目都放在一起,随着业务的发展,数据量,流量的不断增长,单体不够用了,【eg:一个石头太大,搬不动】那我们怎么做呢?
- 要么换大力士【升级硬件】:but:升级硬件也是有上限的;
- 要么多个人来搬,常见的2种方式有:
- 垂直拆分
- 水平
那什么是垂直呢?什么是水平呢?
A:垂直:也就是系统拆分,按系统业务、逻辑拆分成多个合作完成。
一个人搞不完的事,按系统业务拆分,一个人干一部分,把事情干完;
但是:垂直也有一定的局限性,拆分多了,就比较碎片化,不仅不利用管理,单一节点压力还是会很大;
B:水平:也就是我们平时说的集群负载均衡
以前这个逻辑一个实例处理的,现在换成多个实例,干相同的事,换成多个实例,请求来了该找谁呢?这时候我们就用到了负载均衡,搭载Nginx做转发处理
一个人搞不定,那我们都多来几个干相同的事,请求来了,分发一下,把所有的事干了
扩展:Nginx-->高性能的Http和反向代理web服务器;工作原理:作为反向代理,请求之后,配置策略,根据策略把请求转发出去;
事实上,它们做的事都是一样的,都是都是想办法用有限的服务器,计算资源来处理原始的请求,以应对满足高并发,大数据的一些诉求;
现在有3个服务实例,它们都要写log,那么我们不可能每个都写,这样就会重复构建,共同的东西,就可以把它抽出来,服务共享,也就是代码复用
假如一个项目有100个功能点,按照2:8原则来分配,只有20%的业务是常用的,它们会承担80%的流量,而80%是一个进程,那个点的资源是所有程序共享的,就会划不来,那我们把20%的高频服务拆分出来,服务共享,独立的部分增加计算资源,多分一些资源,其它少一点,这样才能资源最大化利用;
2、分布式
如果在项目架构之间,多个项目,把一些操作,逻辑,业务或者服务独立出来,当作服务来共享调用,一次请求就变为:我调用A,A调用logserver,那么这样下来我们就来了一个新的名词,叫:分布式
分布式:多进程协助完成业务;
A:分布式的代价:
那么分布式有那么好么?eg:有一个词叫“欲戴皇冠,必成其重”,eg:分布式锁,分布式事务,以及它的复杂性..........;
分布式锁:一个东西,最多一个人处理,2个人同时操作就会出问题,那么我们就要做一些进程上的互斥;
分布式事务:你操作成功了,我操作失败了,所以我们就要来做些操作。来保证数据的一致性;
为什么那么麻烦,我们还要使用它?好处:独立运维,独立扩展,独立部署【享受自己单独的硬件资源】,更好的利用资源;
3.微服务架构(Microsercice Architecture)
随着时间的推移,业务倒逼技术不断的发展,分布式的问题都解决了,那么分布式就变成了常规手段,推演下午就变成了微服务;
A.定义:
微服务架构就是一个用分布式服务拆分业务逻辑,完成解耦的架构模式(架构风格)。
B:究竟怎么拆分微服务?
eg:三层架构里面有一层,DLL业务逻辑层----UI负责调用
微服务---业务逻辑都放在服务里面---UI客户端负责调用,该集群集群,该部署部署,该运维运维,该注册发现,该网关网关,各种东西佩奇,就变成了微服务
那么真如我们描述的这么简单么?
以前我们调用BLL,在一个进程里,成功或者失败,结果一目了然,清清楚楚,那么我们变为了微服务,调用服务慢,或者失败,原因可能是代码,网络丢包,抖动,服务器,数据库挂了,超时等一系列可能性问题
从单进程变为分布式,一切都不一样了
3.微服务架构全组件解析
把方法都拆成独立服务了,怎么样保证项目是可用的呢?
1.保证服务的高可用;
2.服务的可伸缩性;
A.核心基础:高可用
问题:风险太大--串行结构,任意节点出问题,全流程奔溃,这是项目的高压线,如果一个服务的可用性是99%,那2个,3个...7个,8个呢?简直不敢想象后果,充分体现了可用性的重要性
那我们怎么去保证可用性:答案是集群【可以理解为找备胎?】
Nginx+KeepAlived做IP漂移,我们用nginx作反向代理负载均衡,通过nginx将客户端请求用轮询方式发送给服务器,我们部署了的一个nginx挂了怎么办 ?那我们就部署两个,使用keepalived监控nginx的健康状态,当nginx出现宕机时自动主备切换,实现IP漂移,来实现高可用
B.伸缩性:
总有服务是应对多个客户端的,我们的系统也会在不同的时段,出现压力不均的情况,甚至突然间压力变大10,100倍就会导致我们系统的奔溃,那问题来了,怎么办呢?我们总不可能在事先准备100份冗余资源吧。
我们的预期目标是希望它能自动伸缩,随着压力情况,自动开启新节点或者关闭节点。(Docker+swarm,或者K8S)
游离在外面,请求过不去,怎么纳入集群里面管理起来使用?
Nginx其自身的属性:可以自动减少,减少时会自动重启Nginx,如果新增节点则不能实现自动扩张,修改配置重启Nginx服务那现在怎么办?
1.注册发现
那如果新增一个呢?
节点删除
如果满足了这个特性,就做到了自动伸缩,ConSul就完成了,我们的架构也就演变为:
GRPC:局域网内部传输具有更高的性能,外部我们还是使用.core webapi
问题:
1.服务暴露:这么多服务实例可见,这么多端口暴露在外面还是会很危险;
2.负载均衡;
3.调用服务的麻烦;
新增一个网关,通过包一层的方式去解决上面的问题,由网关GeteWay去处理,做的事跟Nginx差不多;
它们的区别:Nginx是一个单独的服务器,要扩展需要写Lua脚本,但网关还要很多额外功能;
2.网关Gateway
网关用Ocelot,Kong,推荐用Ocelot,[c#写的方便扩展,微软出品]
从图中可以看出网关是一切网络的出入口,这样显得它在整个架构中尤为重要,那我们就要考虑到它的可用性,一个挂了,整个流程都结束了,那我们就集群呗;
集群完,这么多网关怎么访问,难道我记4个地址吗?去调用哪一个呢?
问题:网关调用服务实例,还是要担心服务挂了,服务超时的问题,所以这个地方网关除了去做服务注册,转发,还要去做路由映射,,,,,
没有网关的请求:
加了网关的请求:
有了网关,就可以把关系整理清晰
请求超时:
雪崩:在串行化链路里面,任意节点的故障都会导致整个链路的崩溃。那怎么处理这个问题呢?:
限时解决:定义1S的请求,>1s,不管你是否成功,我都不会再管这个结果,认为Fail,虽然这中间有一个失败了,但是保证了整个链路的健康状态
限流:
熔断,降级等等
最后除了以上这些,还有鉴权,授权
加了鉴权授权,请求的时候,带上Token,有权限就请求,没权限只能出门左转回家
到这,核心模型就搭建完成了
问题思考:那么我们如何拆分才能保证系统高内聚,低耦合?