zl程序教程

您现在的位置是:首页 >  工具

当前栏目

详解单体架构 微服务 微服务架构 分布式结构 集群 负载均衡 服务监听 服务降级 服务通信 session共享 docker技术

2023-09-27 14:26:20 时间

单体架构

什么是单体架构

在软件设计中,经常提及和使用经典的 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 MVCspring-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的集群,节点大的监听节点小的,如图所示:
zookeeper的目录结构

为什么需要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技术,如图所示:

docker技术

涉及到的各个技术的细节,并没有涉及太深,只是展示微服务和分布式的由来。

总结

如果你的业务量不是很大,或者你只是初创企业,可以先使用单体服务,毕竟单体服务简单,易应用,易维护等。

如果单体服务支撑不了你的业务,那么可以使用微服务。