这么去设计一个web架构和技术选型就对了

1,466 阅读8分钟

目前业界的架构演进

应用架构演进

graph TD
单服务 --> SOA --> 微服务 --> serveless
微服务 --> service_mesh

     在互联网生态不甚发达的时候,大多数web服务,或者以java来说,基于java的服务从java se 发展到java web,从单服务到集群,再到异构系统的出现,再到微服务,无服务、服务网格等,都是先有了需求,才有了后面技术的出现,而新出现的技术往往是对老技术的完善和增强。

     service mesh 即服务网格,它的落地实现有 istio,是由Google、IBM 和 Lyft 开源。

     Serverless通常与Faas 即函数即服务相关,它是一种架构思想,落地即是各大云厂商推出,它的实现有基于k8s再做一层封装去实现。

运维部署架构演进

graph TD
1 --> 单体 --> 集群 --> HA

2 --> 手动部署 --> CI/CD --> Devops

3 --> 物理机部署服务 --> 虚拟机部署服务 --> 容器化技术部署服务 --> k8s与云原生 

   1和2和3 三条路径 并不是说是完全分离的,它们之间是结合的,只不过是从三个不同的角度来看运维部署方式的演进,都是有了需求才有了后面的演进,单体到集群是为了支持大量的请求,集群到HA高可用是为了解决单点故障问题,也并不是说是一步一步按时间顺序出现的,这里的流向指代的是按解决问题的顺序。

应用架构设计

模块和聚合

    我们可以通过maven创建一个聚合项目,在项目中按照业务进行分模块构造,对于每个模块,又可以将接口和实现抽离开来,分成两个部分,对于公共部分可以抽成一个common模块,对于基础底层可以构建成一个单独的模块。在每个模块内部进行代码的开发可以根据不同的业务场景,考虑选择不同的方案(设计模式)来实现,以实现它的模块内部高内聚低耦合 ,可拓展性。这样我们的聚合项目就从项目分模块,到模块内部都是按照高内聚低耦合的方式去实现的。

    在设计聚合模块时我们先考虑对于业务的划分,我们应该考虑的是基于价值,怎样去快速的落地这个项目,而不是去考虑一下设计出怎样牛逼的架构,需要先产生价值才能推进价值的增值,推进架构的进一步演进和发展,需要明白的是业务就是 money,有时候我们需要快速落地而抢占先机,所以先去在一个基础的底层架子上去填充业务模块,在这个单服务聚合项目中,我们需要划分好业务模块和底层模块再去进行技术选型,需要考虑公司已有的技术栈是否有要求去使用,也要考虑这个项目的应用场景,是自用还是作为to B 商业价值,如果自用,那可以考虑的技术选型就比较广,如果针对to B 商业售卖应用,那需要考虑目标客户群体是否有特殊要求,针对这些特殊要求进行技术选型范围确定,亦要考虑项目的快速落地化和实施的简易性。

    一般来说,最新的技术相对于同类的老技术是更优的,所以,若无特殊要求,我们选择同类最新的技术即可,当然在这个过程中,并不是说选同类技术的最新版本,尽量选择它的stable版本,即稳定版本即可。

微服务拆分

     我们的目标:要能快速落地,要尽可能在短的时间内看到演示效果,所以千万别想着一下完美主义,完美主义是需要时间成本的,所带来的可能就是价值的流失。

     微服务的拆分肯定会带来一定的资源开销,并且衍生出来一堆其他问题,所以我们需要合理的进行业务规划,将哪些业务归到一个服务里面是需要去仔细考虑的。如果是基于maven单一聚合项目拆分微服务,那就要考虑是否完全按照模块进行拆分,还是对部分模块进行归并,如果资源确实有限,那就要考虑进行归并了。虽然技术可以推进业务的发展,但是我们目前大多数的场景其实是技术为业务服务,所以要适合、要均衡业务与技术的权重。

微服务的各个组件技术是为了解决什么问题

首先我们来看看微服务的各个组成:

test1-2.png

     我们可以看到整个微服务架构中除了业务服务外,还有注册服务,配置服务,链路追踪,网关,降级熔断服务,日志服务,监控服务等。

  • 注册服务是为了解决服务注册;

  • 配置服务是为了将所有配置集中起来,可以动态更新,不需要再改配置后部署;

  • 降级熔断可以分开来看,降级是为了在发生服务调用出问题的时释放资源,a调用b,a出问题,a释放b的资源,这时候可以理解为降级,熔断是多次发生降级,这时候直接将a服务熔断,让它不要再去做调用;

  • 链路追踪是在a调用b,b调用c,c调用d这一整个链路中,根据时间串成一个链路,在哪个节点发生长时间的等待或者阻塞,这时候就可以通过链路追踪发现和排查问题;

  • 网关刚开始是为了提供统一入口,不能直接去调注册中心,也不能直接去调某个服务,这时候就需要一个网关来做统一入口,类似网络中的网关路由器,后面随着发展慢慢丰富起来,像是鉴权认证,限流等都集成进了网关;

  • 日志服务是为了解决多个服务我们查询日志排查问题的需求,像是比较普遍的ELK日志解决方案,即一般通过一些工具从各个服务去采集日志文件,然后通过logstash进行filter和处理后推进elasticsearch,集成kibana进行搜索查看(不止这些);

  • 监控服务即是对各个服务器进行监控,服务是否运行良好,服务器cpu和io是否在正常阈值等,如果出问题就会进行报警发短信等提示。

     CI/CD 即是持续集成和持续部署,持续集成简单来说就是向master分支合代码,持续部署就是通过工具将master代码拉取打包并进行部署运行(这两个过程可能只需要客户触发一下,后面都是自动的)。

     可以看到docker和非容器部署两种不同模式的CI/CD,其实本质上都是一个原理,当然除了图上的CI/CD实现,还有其他的实现。

微服务技术选型经验思考

并不是说落地一个微服务就要用最新的技术,可以参考以下原则:

  1. 有技术要求,这时候在技术要求范围内进行选择。

  2. 是一个新的项目,无技术要求,这时候可以考虑用新技术即可(普遍新的技术一般都是优于老的)。

  3. 考虑这个项目落地的紧急性和现有资源的充足性,及相关人员的技术栈,进行技术方案选择。

  4. 有一些特殊要求,可能会出现一些特殊的业务场景,这时候根据相关技术特性进行选择。

将业务功能填充进各个服务

     在完成架构设计和技术选型后,就要进行基本框架搭建,搭建完成后开始填充业务功能进对应服务,在填充业务功能之前,梳理部分公共组件模块,填充公共工具等,来供业务服务功能使用,剩下的就是细节处理编码了,对一些业务功能使用设计模式进行设计,使之高内聚低耦合、可拓展演进等。

面向价值导向设计和落地架构

     在设计架构时一定要明白这样做能带来什么价值,应该采取最优原则,并不是这个架构设计的多完美就多好,一定要考虑落地的快速性和产生价值的急切性,权衡去设计,但也不能偏差太大,要有可用性。当然对于互联网三高(高并发、高可用、高性能)架构就要去慎重考虑了。

拥抱云原生设计架构

     云原生,简单来说就是这个项目的落地从开始就是为了运行在云上而开发,而它也是运行在云上。我们可以考虑使用service mesh 的落地 istio去实现一个项目,来拥抱云原生。