系统架构与高可用

系统架构与高可用

前言

简单聊聊博主的背景吧,博主是Java开发,刚毕业就来到这个刚创立的公司(当然是有一点背景的),公司开发人数从80来人到现在的430人,期间系统进行多次调整。

而我除了写代码业务实现外,刚好有机会接触了一些类似架构、运维、以及新系统初期设计讨论的工作,这大大满足了我的好奇心,这是幸运的。

我大部分的知识是从工作中学习到的,开始知识点是零散,喜欢做笔记,一旦遇到我们没有听过的技术名词或者业务名词我就会记录下来,然后自己找资料去了解,哪怕是同事讨论我听到的,平时闲逛博客文章也会看到一些,慢慢的一些知识点可以串连起来,逐渐的对公司使用的技术体系有了较为明确的了解。(这是一种我认为不错的学习方法,有一定的技术体系脉络后,可以尝试各个知识点针对性加深理解,这是一种从点到线到面,再到深入的一种方式)。

事实上架构师的工作可以细分为业务架构和技术架构,相应的职位可细分为业务架构师、技术架构师。当然细分并非必须的。

而我们公司的架构师职位,是偏向业务架构的定位,技术架构基本是各个研发团队规划。当然整个公司有基础架构规范,使得各个系统使用的技术偏差不会太大,尽量保持统一。

博主所在公司的技术架构是微服务架构,新型中大型互联网公司一般采用这种架构吧。至于什么是微服务架构,我们后面细说。

关于业务架构

为了让大家更好的理解业务架构,我找到一遍非常不错的文章:怎么做好业务架构师

我摘抄了其中不错描述:
(1)开发的思维和业务架构师的思维有很大差异。前者侧重于对具体的问题,思考能否实现、如何实现、实现的好不好、效率高不高。后者侧重于对明确或者模糊的问题, 思考真正需求是什么、为什么是这样、如何分析成册、如何描述给下游同事。
(2)作为一个承前启后的岗位,业务架构师像是一个路由器,对各种业务需求加以分析处理后路由到下游产品和研发团队。 因此和业务人员沟通时,需要能换位思考“他们为什么提出这个需求、痛点在哪里”;和产品、研发沟通时,能思考他们的技术限制、架构局限和项目进度压力。 基于换位思考的沟通能力,能让你和业务、产品/研发更有效的沟通,关系也更融洽。

整体而言,业务架构师需要更多的思考、更多的沟通与表达(文档能力),需要对业务有足够的理解。
我们公司研发中心也有架构团队,有架构师职位。但是整体而言,我们公司的架构师,并没有发挥出应有的贡献。因为他们对业务的理解非常局限,而只是作为参与讨论的角色,讨论完了,基本不总结,因此形同虚设。我觉得是因为研发中心对他们的职责定位没有足够的明确,或者没事实施好的缘故吧。

关于技术架构

技术架构师是选型、抽象、提炼、封装公共组件,如缓存、消息中间件、服务框架、工作流等。让项目团队只关注业务代码的实现。

2017年12月份,公司邀请了一位京东高级架构师给我们分享了《微服务架构设计与实践》的课程。收获非常大,最主要是让我对知识体系结构的理解更为深入,这一点让我在后面的学习中可以更加快速的理解。下面说说系统架构自己的一些收获吧。

(1)系统架构其实分为:标准的基础系统架构规范和结合具体业务的系统架构。有些系统如秒杀系统、营销活动系统等,需要对业务有足够的理解,才能设计出更为合理的系统架构。

(2)系统架构有:1、单体式架构(两层的C/S架构、三层的MVC架构),2、多体式架构(简单分布式系统RPC调用、面向服务架构SOA、微服务架构)。

关于单体式架构,系统应用、数据库都部署到一台机器上,比如一个小超市的结算系统。在以前网络没有现在那么便利时,他确实有其较强的使用场景的。

关于微服务架构,采用一组服务的方式来构建一个应用,服务独立部署在不同的进程中,不同的服务通过一些轻量级交互机制通信,例如RPC、HTTP等,服务可独立扩展伸缩,每个服务定义了明确的边界,不同的服务甚至可以采用不同的编程语言来实现(但是建议尽量统一,方便维护),由独立的团队来维护。

微服务的思路是将一个巨大的单体式应用分解为许多小的、相互连接的微服务,可以更加快速的迭代及扩展伸缩。
一个微服务一般完成某个特定的功能,比如下单管理、客户管理等等。
运行时微服务的每个实例可能是一个云VM或者是Docker容器。
微服务架构每个服务都有自己的数据库。

微服务架构的好处:
(1)通过分解巨大的单体式应用为多个服务方法解决了复杂性问题。
(2)这种架构使得每个服务都可以有专门的开发团队来开发。开发者可以自由选择开发技术,提供API服务。(不过我们公司目前都是采用统一的技术,方便维护,除非特例才使用不一样的技术)
(3)微服务架构模式是每个微服务独立部署。开发者不再需要协调其他服务部署对本服务的影响。
(4)微服务架构模式使得敏捷开发、持续化部署成为可能。
(5)微服务架构模式使得每个服务独立扩展。你可以根据每个服务的规模来部署满足要求的规模。你可以使用更合适于服务资源需求的硬件。

微服务架构带来的问题:
(1)微服务的边界、大小很难界定(什么时候该拆分,什么时候该合并,因此就我们公司而言机会每年需要整合一次,当然不会大变化,只是局部调整使得更加合理)
(2)微服务应用是分布式系统,由此会带来固有的复杂性。开发者需要在RPC或消息传递志健选择并完成进程间通讯机制。
(3)在微服务架构应用中,需要更新不同服务所使用的不同数据库或缓存。使用最终一致性、分布式事务等等。
(4)微服务架构模式应用的改变将会波及多个服务。需要了解所有服务使用者。
(5)测试一个基于微服务架构的应用也是很复杂的任务。

而我们公司微服务架构的具体实现:

这里写图片描述

每个微服务单元,可以根据业务量进行,横向扩展,部署多个实例负载相应请求。
微服务单元之间通过远程调用通信(博主公司采用的是Zookeeper + Dubbo),微服务暴露一些接口给其他模块消费,其他模块可以是另外一个微服务,也可以是中台api。
中台api+前端主要职责是业务包装,可以包装各种各样的业务形态,如不同的订单流程及交互。
微服务之中也可以作基础微服务和业务微服务区分,如客户系统、额度系统、审批系统、贷款系统开发成熟后,变更相对较小,而订单系统、营销系统、商户系统等则变动比较大。划分维度可以结合自己业务场景多研究。

关于高可用架构设计

【由于时间有限,没有画图,纯文字略显粗糙,不过希望猿友可以耐心看完】

正常情况下,我们一般一个微服务单元部署两个实例,分别放到两台服务器上,可以达到一个容灾效果。普通的请求量是没有问题的。

某些请求耗时特别高或者系统崩溃,一般是索引没有设计好查询太慢导致数据库连接数不够、或者一次性从数据库中查询百万级别数据加载到内存导致内存溢出(严禁查全表,尽量采用分页查询)、或者存在死锁导致数据库连接数不够、或者某段代码存在死循环(递归尽量判断,设置个递归次数,如100,避免死循环)。
以上问题,我们一般安排代码检视,让大家按照规范,那么比较少出现了。

排除上面的一般问题,小部分接口访问量较大,性能瓶颈大部分就是数据库了,结合我们的业务场景,可以适当使用缓存,缓存我们尽量使用分布式缓存吧,除非是一些对相应速度要求非常高且数据量很小的可以使用本地缓存。
使用了缓存后,数据从内存里面读取性能会得到大大的提升。

如果综合访问量比较大,这时候的瓶颈集中在服务器的cpu和io了,那么就扩展中台api和微服务的实例,拓展到一个相对稳定的数量级。

如果访问量及数据量都达到一定的级别,那么很可能瓶颈又落到数据库了,但是我们会发现,数据库操作超过80%往往是读操作,而写操作不超过20%,那么我们可以考虑读写分离,我们愿意牺牲一定的写操作时间来换取读的性能。再者就是,学会做数据冗余,以前数据库服务非常昂贵,我们坚持数据库的第三范式,避免冗余,而现在我们应该考虑的是如何做好数据冗余,以提高系统的可用性。不仅仅是表字段冗余,甚至可以整张表冗余。以商城为例,可以商家端看到的订单信息跟用户看到的订单信息并不在同一个数据库的,商家是可以接受短时间的数据不一致的,只要最终一致就好了。(最终一致性,这个词有不少应用场景的,可以细细了解并应用)。

对于类似秒杀系统,突然峰值,这种一方面我们肯定需要热备份多台机器以方便快速拓展微服务实例、另一方面还需要做请求拦截和队列,请求拦截和队列应该尽可能前置,减少对系统带来的冲击。一些逻辑可尽量采用异步处理,结果消息通知的方式。

当系统越来越复杂,数据库表很多,比如超过150张表,我们可以考虑进行服务拆分,重新规划。还可以达到容灾隔离的效果。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/2260.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 自动关机程序[通俗易懂]

    自动关机程序[通俗易懂]Shutdown命令作用语法参数示例执行作用让我们能够一次关闭或重新启动一台本地或远程计算机。语法shutdown[-a|-s|-f|-i|-l|-r|-h][-m//ComputerName][-tXXX][-d[p:]XX:YY/c”Comment”]参数shutdown-a 取消关机shutdown-s关机shutdown-f 强行关闭应用程序shutdown-i 显示“远程关机”图形用户界面,但必须是Shutdown的第一个

    2022年7月22日
    18
  • 按位取反怎么运算_按位取反在线计算器

    按位取反怎么运算_按位取反在线计算器一、首先二进制在计算机的内存中是以补码的形式存储二、正数的补码=原码=反码,负数的反码=原码的取反(二进制数的符号位除外,一般来说在二进制的左边的最高位)补码=反码+1三、按位取反怎么算按位取反:二进制的每一位都取反(符号位+数据位)公式法:~x=-(x+1)举两个例子:~11=-(11+1)=-12~(-11)=10公式法的内部是如何计算的呢:以~11为例:~11的计算步骤:计算11的补码转二进制:01011计算补码:01011按位取反:10100(按位取反

    2022年8月14日
    19
  • navate15激活码【最新永久激活】

    (navate15激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~AE…

    2022年3月28日
    79
  • pycharm默认编码_编码需要注意什么

    pycharm默认编码_编码需要注意什么这两天爬取东西的时候经常出现编码的问题,错误如下:UnicodeEncodeError:’gbk’codeccan’tencodecharacter’\xa9’inposition75:illegalmultibytesequ找了很多资料也没发现有用的,问了一些朋友也不知道,然后自己试着改了下pycharm的一些东西,就好了具体步骤:File–>Se…

    2022年8月27日
    0
  • c 获取UUID_c获取程序运行路径

    c 获取UUID_c获取程序运行路径计算机获取UUIDUUID是通用唯一识别码(UniversallyUniqueIdentifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名…

    2022年8月9日
    16
  • goland 2021.5激活码【注册码】[通俗易懂]

    goland 2021.5激活码【注册码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月20日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号