这里写目录标题
单体架构
什么是单体架构
在软件设计中,经常提及和使用经典的 3 层模型,即表示层、业务逻辑层和数据访问层,但是对业务场景没有划分。
将所有的业务场景的表示层、业务逻辑层和数据访问层放在一个工程中,最终经过编译、打包,部署在一台服务器上便是我们典型常见的单体架构。
如下图所示:
表示层(controller层)
用于直接和用户交互,也称为交互层。
此层接收到前端用户的请求,校验相关的参数之后,直接调用service的方法。
业务逻辑层(service层)
即业务逻辑处理层,例如用户输入的信息要经过业务逻辑层的处理后,才能展现给用户。
数据访问层(dao层)
用于操作数据库,用户在表示层会产生大量的数据,通过数据访问层对数据库进行读写操作。
单体架构的好处
-
部署简单:由于是完整的结构体,可以直接部署在一台服务器上即可。
-
技术单一:项目不需要复杂的技术栈,往往一套熟悉的技术栈就可以完成开发。
-
用人成本低:单个程序员可以完成业务接口到数据库的整个流程。
-
服务器成本低:只需要一台服务器即可,不用购买多余的服务器。
单体架构的坏处
-
系统启动慢, 一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重启时间周期过长;
-
系统错误隔离性差、可用性差,任何一个模块的错误均可能造成整个系统的宕机;
-
可伸缩性差:系统的扩容只能只对这个应用进行扩容,不能做到对某个功能点进行扩容;
-
线上问题修复周期长:任何一个线上问题修复需要对整个应用系统进行全面升级。
单体架构常用技术栈
基于单体架构的开发,目前比较常用的就是spring mvc + hibernate
,或者 spring mvc + mybatis
,
当然,也有公司使用“`spring boot + mybatis做单体开发。
微服务
使用微服务的原因
基于单体架构带来的困扰,为了解耦合,为了避免单点故障,且能快速开发,将各个服务拆分,部署在不同的服务器或Tomcat上,各个服务之间相互调用,如图所示:
spring boot
我们如果用spring mvc
框架,他虽然开发成本低,但配置成本高,因而,有没有一个框架代替spring MVC
。因而,spring boot
便应运而生,其拆箱可用。
Spring boot
通过stater
集成各种插件,大量的自动化配置,比如spring-boot-starter-web
引入了spring MVC
,spring-boot-starter-data-redis
引入Redis
,简化了spring MVC
中的很多配置。
同时,服务可拆分,方便部署在多个Tomcat
或多个服务器,但各个服务之间的如何通信?这就需要网络传输。
服务间的通信
网络传输有四层协议,应用层,传输层,网络层,链路层
。
使用应用层协议为主的HTTP通信,但HTTP协议包含太多无用的信息,包括请求头和请求空行。而真正需要的用户数据只在请求体或者路由之后,在高可用的现代化软件开发体系中,显然太多的无用的字段会影响网络传输的。因而,能不能直接以传输层协议为主,进行服务间的通信?
因而,我们就想到了传输层的TCP协议
,通过序列化将对象写出jvm
,反序列化将对象写入jvm
,这样重新引入新的服务协议,即rpc协议【remote procedure caller 远程服务调用】
。这样,就规避了http协议
带来的无效协议信息。
支持rpc框架的有netty,dubbo
等。
Netty底层使用的是nio,dubbo底层使用的netty,性能还是比较高的。
分布式架构
各个服务相对独立,又相互联系,便组成了微服务,也能避免单点故障。支持微服务的架构设计,便是所谓的分布式架构。
分布式架构比单体架构更复杂的,但更好的实现高内聚和低耦合。
session共享
由于服务之间相对独立,那么怎么样可以共享sesstion?
复制算法比较耗时,如果存储到非关系型数据库中,但数据存储到磁盘上的,随着数据量的增加,从数据库中读取数据耗性能,能不能直接在内存中操作,因为就出现了非关系型数据库:Redis。
Redis
Redis纯内存操作,且是单线程框架,避免了多线程的上下文切换;它同时采用NIO的多路复用技术,可以避免bio那种连接阻塞和读写阻塞,这就让Redis有很高的性能。
Redis可以用做缓存,限流,分布式事务,计数器,投票,点赞,共同好友,相似好友,存储session会话等等。
Redis集群
如果访问量很大,单台Redis的并发毕竟有限,同时单台redis也会存在单点故障,这就需要多台redis集群,master redis 和 slave redis。
master redis 需要时刻将数据写入到slave redis中,以免当前master redis 挂了,必须在保证数据安全的情况下,快速从slave redis选举出master redis。
Redis集群监听
谁来监听master redis的生命状态,如果master redis挂了,谁能监听到并重新快速选举出新的master redis。
因而,需要Sentinel集群选举Leader,兵谏亭redis的生命状态。但是,谁来监听Sentinel集群,这就需要分布式协调组件zookeeper。
如果没有做redis集群,但redis挂了,怎么办?这就需要redis数据备份,可以使用rdb或aof实现将redis写入到磁盘,并在redis启动后,将数据恢复到redis中。
负载均衡
Session共享解决了,但是如何实现各个服务的负载,比如动态将用户的请求转发到哪台服务器上?这可以使用Nginx。
Nginx使用的进程级别的通信,性能有一两拨千金的作用。它由三种算法进行负载,轮询、加权,hash算法,可以受用select、poll、epoll进行NIO多路复用。
如果访问量很大,单台Nginx的并发毕竟有限,因而,需要多台Nginx集群。如何监听Nginx集群的心跳,以及主从Nginx的选举等,这里可以使用keepalive集群,如何监听keepAlive集群,这就需要分布式协调组件zookeeper。
为什么需要zookeeper
zookeeper采用事件监听、有序节点临时节点的特性,来选举出master和slave的集群,节点大的监听节点小的,如图所示:
为什么需要hystrix
当我们的服务在相互调用期间,突然某个服务挂掉了,那怎么办呢?这就需要将服务降级,怎么将服务降级,那便使用到了hystrix。
hystrix熔断主要是指在一定的时间窗口内,当请求的次数达到一定的失败比率后,hystrix就会主动拒绝服务,采取将请求直接降级等方式,从而有效的缓解了服务雪崩的问题,通过快速错误的方式,有效的控制服务之间链路调用的响应时间,保证整个微服务的健康。
为什么需要docker
假设现在有十台服务器,每台服务器上均部署web应用,因而,每台服务器上都需要部署Tomcat和jdk,假如使用手动的方式去部署Tomcat和jdk,需要经过以下步骤:
- jdk
- 下载jdk
- 安装jdk
- 配置环境变量和系统变量
- 。。。
- Tomcat
- 下载Tomcat
- 配置Tomcat
- 修改Tomcat的日志编码格式
- 设置post请求的数据编码格式
- 。。。
这些配置加起来非常繁琐,配置Tomcat和下载jdk要受到操作系统的影响,操作起来非常的不方便,况且要配置十台这样的服务器,但凡有一台疏忽大意,都有可能配置错误。这只是Tomcat和jdk的配置,nginx,mysql,keepalive等还没有配置,加起来会更麻烦和容易出错。
此外,开发还分为测试环境和正式环境,往往在测试环境是正常的,但在测试环境是不正常,这就造成了环境的不一致。
因而,就在考虑在多台服务器中的配置,能不能以一个镜像的形式,打包安装到每个服务器上,因而,这就出现了如今很火的docker技术,如图所示:
涉及到的各个技术的细节,并没有涉及太深,只是展示微服务和分布式的由来。
总结
如果你的业务量不是很大,或者你只是初创企业,可以先使用单体服务,毕竟单体服务简单,易应用,易维护等。
如果单体服务支撑不了你的业务,那么可以使用微服务。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99247.html