前端上传图片到服务器-前端图片上传七牛
背景
近两年,业界最热门的技术架构话题已经从前后端分离,变成了分布式、微服务、DDD。 微服务架构适合所有公司吗? 业务场景发展到什么程度才需要考虑微服务? 毕竟在选择技术架构之前,还是要考虑业务是否匹配。 否则,分布式、微服务等繁重的架构设计将成为一些公司的屠龙技,成为一线开发团队的累赘。
在我短暂的职业生涯中,经历过小的创业公司,经历过国企这样的大型项目前端上传图片到服务器,也经历过在ThoughtWorks看到的各种项目。 架构就像杂货店,而微服务只是一个工具箱。 不能拿着锤子满世界找钉子。
我想尝试让建筑的概念更流行。 文中有很多不恰当的比喻,请见谅。 为了描述常见互联网公司技术架构的演进过程,这里设置一个虚拟背景:
Neo 是一名软件工程师。 毕业后,他留在了这座城市,加入了一家互联网创业公司。 该公司的业务是为餐厅提供送餐服务。 用户可以通过APP或微信提前订餐,公司将在次日早上送达。 哒。 采用了Java+MySQL的技术栈。 目前只使用一台服务器,数据库和应用仍然部署在同一台服务器上。
由于用户的增多和业务的逐渐复杂化,Neo团队遇到的第一个问题就是需要对系统进行扩展,提高系统响应速度。 对于互联网公司来说,扩容一般就是“加机器”,那么第一步是如何加机器呢?
单库多应用服务架构
在添加机器方案时,我首先想到的是软件园餐厅的工作模式。
软件系统的用户就像是来饭店吃饭的顾客,服务员就像是服务员。 本来服务员是可以收费和卖菜的,就像有时候我们把应用代码和数据库同时部署在同一台服务器上一样。 如果在服务员既负责结账又负责餐卖的模式中增加人手,效率不会高,决算也可能不一致。 因此,餐厅一般会有多名服务员售卖餐点,然后由专人负责结账。
回到我们的架构问题,如果我们需要多台服务器来响应更多的用户,我们也必须保证数据的一致性。 根据数据库的范式理论,数据的冗余度越低,数据的一致性就越高。 所以我们第一步可以分为多台应用服务器处理用户请求,一台数据库服务器集中处理数据的读写,分担服务器的压力,保证数据的正确性。
但是在应用服务器的入口处,我们需要增加一个负载均衡服务器,将不同的用户请求分发到具体的应用服务器上。 这有点类似于餐厅里的排队机,分流用户。 负载均衡服务器可以是配置在普通PC服务器上的Nginx等软件,也可以是F5等专用的硬件负载均衡设备。
Neo 的团队花了半个月的时间重新部署了这些服务器,通过剥离数据库和添加应用服务器来提高系统性能。
读写分离的数据库架构
半年时间很快就过去了,尼奥的公司增加了很多新的业务,系统也增加了更多的功能。 订购蔬菜的商家还可以通过手机查看历史订单和各种统计信息。 这时,Neo 发现无论增加多少应用服务器,用户都需要等待很长时间,最终数据库也出现了瓶颈。
数据库是分布式架构中最难解决的问题,因为它不像应用服务器,它不保存数据。 如果要增加数据库服务器的数量,首先需要解决数据的重复和一致性问题。 现实中对应的解决方案有很多,比如读写分离、数据库物理分区、逻辑表分区、逻辑数据库分区,但本质上只是对数据库操作的一种不同的拆分方式,我们处理的是最常见的数据库性能和性价比最高的方法是读写分离。
这里我忍不住用一个美食城的例子来说明数据库读写分离的思想。
上面我们提到了数据的集中处理,刚开始的时候还挺有效的,但是随着用户量的增加,负责处理数据的服务器还是忙不过来。 同样的例子,在现实生活中,美食广场等很多人流量较高的场景还有另一种运营模式。 美食广场一般由管理公司和各类商户组成。 消费者需要先到管理公司设立的充值点充值,然后到各商户刷卡消费。 收银员只需要写入充值数据,然后各个商户就可以读取数据了。
因为在不修改数据的情况下,读取数据会消耗大量的计算资源,所以我们可以考虑将数据库读取和写入这两个操作分开。
我们可以利用数据库的主从架构来增加读服务器的数量。 主库保证数据一致性,使用从服务共享查询请求。 主服务器会将数据同步到从服务器,实现数据的最终一致性。 当然,这种架构可能还是会遇到性能瓶颈,但是暂时可以长期使用。
当然,如果加上缓存,静态文件分离,性能会进一步提升。 一般的项目达到这一步,足以满足大部分需求。
但在随后的日子里,产品经理提出在点餐页面提供视频介绍,于是系统中出现了大量耗费计算资源或耗时的视频转码操作。
使用消息队列的架构
电影《让子弹飞》中有一句经典台词,“让子弹飞一会儿”。 程序世界总是和现实生活相似。 如果我们要去邮局寄件邮件,或者去快递公司寄包裹,我们不必等到邮件或包裹到达收件人之后才离开。 这将需要几天时间。
相应的,系统中也经常会出现这样类似的场景。 当我们将视频上传到视频网站时,视频网站往往会进行转码,使其适合网络播放。 这个操作需要大量的服务器资源,不可能在用户点击提交后处理完成,否则用户要等待很长时间,甚至连接超时。
对于这种应用场景,我们可以让系统不必实时处理这样的任务。 当用户提交请求时,系统会将任务添加到消息队列中,完成后改变数据的状态。 用户在刷新或收到通知后,就会知道任务已经处理完毕。
在上面提到的系统架构中,多个应用服务器被克隆,然后分别部署。 每个应用服务器上的代码完全相同。 就像原始生物体真菌一样,细胞没有分化。 所有细胞都具有相同的功能。 从这一节开始,不同应用服务器的职责开始发生变化,就像植物的出现让细胞开始分化一样。
随着业务的发展,Neo的公司开始拓展新的领域,开发了代理平台和物流平台来拓展更多的商户,甚至需要对接第三方平台,需要保证这些平台中的一些通用数据和逻辑是正确的。持续的。
面向服务的架构 (SOA)
如果你看过《工作细胞》这部动漫,一定会对可爱的血小板姐姐印象深刻。 《工作细胞》通过拟人化的动画方式,讲述了人体不同细胞的职责和工作方式。 每种细胞都有其独特的功能,血小板负责止血和修复伤口,而T细胞则负责吞噬异物和发现入侵者。
随着软件系统越来越复杂,涉及的开发人员越来越多,应用系统的分离和分化就变得非常有意义。 面向前端的API应用服务器不再真正处理业务逻辑,而是调用专门的服务器来完成。
单点登录(SSO)是一种典型的面向服务的架构,广泛应用于互联网公司。 国内互联网巨头往往拥有多个系统。 比如腾讯的QQ音乐和空间都可以用同一个QQ号登录。 因此,用户服务和鉴权服务分离,通过各个系统之间统一登录和管理用户信息,大大提高了用户体验。 这是一个面向服务架构的例子。
这些大厂商不仅在自己的系统中完成统一的认证和用户管理,还向第三方系统开放了登录和授权服务。 例如,很多网站都支持微信登录,这样用户就可以使用一组用户名和密码登录大量的访问系统。 而业界有一个通用的规范,方便各个系统接入,就是OAuth标准。
调用服务的方式有很多种,根据不同的网络协议使用RPC框架或者直接HTTP请求。
Neo的公司改造了面向服务的架构,系统中的用户服务、物流服务、订单服务等差异化服务,通过OAuth提供收银系统认证对接。 一些收银机厂商也接入了这个系统,商家可以通过支持的收银机设备订购食材。
微服务架构
随着Neo所在公司的快速发展,越来越多的业务需求加入到系统中,系统变得异常庞大。 不同的应用和数据相互依赖,逻辑错综复杂,项目的部署进入了混乱状态。 具有复杂依赖关系的大型系统需要更强大的架构。 为了解决系统复杂性和服务解耦的问题,微服务和领域驱动建模(DDD)是时候出现了。
大家都知道,微服务来源于Martin Fowler阐述的概念,然后流行起来。 上面提到的各种架构仍然彼此密切相关。 即使分开,也被当作系统组件,很难独立运行。
微服务旨在解耦大型软件系统。 独立部署不同职责的服务,实现服务内高内聚,服务间低耦合,开发更加灵活。 当然,“分开是为了更好的聚在一起”。 为了重新组合并稳定运行这些服务,人们发明了服务发现、断路器机制、服务部署监控等一揽子工具。
我曾经和同事开玩笑说,最好的微服务就是一个国家的政府。 政务中心相信大家都去过。 当您需要办理账务或其他市政业务时,政务大厅就像一个软件系统一样运作。
大堂的签到区就像一个API网关。 给你排号的时候需要你的身份证(认证)。 如果发现您不符合该区域的处理条件(授权或范围),将直接拒绝您。 当多人被编号时,他们将被分配到不同的窗口。 这时候你感觉面对的不是前台小姐姐而是一个采用轮询策略的负载均衡服务器。 对于某些业务,受理业务的窗口并不实际办理,而是提交给专门部门办理。 该窗口对您来说是 BFF(前端后端)。 实际受理业务的部门将数据处理后提交给档案室,就像读写数据库一样。 如果系统中的某个部门因某种原因停工,则会发布通知(熔断)。 当然,这样的例子太多了,这里不再赘述。
微服务甚至不是一种架构,而是一种生态,应用之间相互独立,又相互依赖。 通过DDD模型设计一个地图,把合适的代码放在合适的地方。 实现微服务涉及的工具太多了,为了让架构看起来更清晰前端上传图片到服务器,我省略了其中一些。
建筑神话
支付宝前架构师周爱民先生曾说过,“真正的架构师是没有头衔的”。 然而,更进一步,其实IT系统的架构是没有标题的。 每个公司的架构都是独特的、混合的、适合业务需求的。 很难说我们现在的架构是一个标准的“微服务”,一个“标准的微服务”对于一线开发的小伙伴来说可能有时候会比较吃力。
从一开始就完美地设计架构也很困难。 架构不是设计出来的,甚至不能设计出来。 它只能随着需求的变化而不断发展。 建筑师的工作不像建筑师那样去构建一个大蓝图,而更像是一个治病开药的药剂师。 正如 The Cathedral and the Bazaar 所说,“软件主要是服务行业,尽管长期以来人们毫无根据地将其误认为是制造业。”
正如生命在自然环境中不断适应而进化; 我们的架构需要根据敏捷的要求不断改进。
文/ThoughtWorks 林宁