最近要开新项目,使用微服务架构,正好就在之前的spring boot基础之上。所以觉得还是要把最近的思考写一下。让我们小到大一点点说。本文只代表我个人观点理解。
spring几乎可以说是现在java开发者都知道的一个开源框架,使用javabean致力于解决企业级应用开发的复杂性。
总结有以下优点:
1,高内聚低耦合
2,简化开发
3,IOC一个大工厂管理javaBean
4,对难于应用的API做了二次封装
5,便于测试junit
6,支持切面编程AOP
7,方便集成其他框架
spring boot 是在spring的基础上开发的,几乎干掉了所有的繁琐的XML配置,可以让我们通过极少量的代码快速搭建一个产品级spring的应用。并且内建了tomcat(spring boot2的webflux换成了netty)可以在IDE中快速启动应用程序。spring boot 更像是一个脚手架,各种模块化的内容可以通过maven依赖引入实现功能。让我们更方便快捷的使用。它更像是一个框架的框架。或者说集合? spring boot的简单配置可以让我们更专注于业务模块开发而无需关心这些繁琐配置。
spring cloud 其实就是微服务架构, 由一个个的spring boot微服务串起来的一套微服务架构体系。
spring cloud的技术栈很庞大,spring cloud 技术栈
spring cloud利用spring boot的快速构建的特性,在此基础上将各种功能模块整合。比如注册发现中心,配置中心,服务网关,熔断器,负载均衡等。从而快速构建分布式系统的基础架构。
开发过程中,我们可以通过spring boot的方式在IDE中快速启动多个微服务进行功能开发测试,上线时,每个微服务都是一个独立的模块,独立项目,可以分开打包部署。
从前的项目项目文件中有很多功能包,代码全都集中在一个项目里。这个项目的功能责任不单一。并且代码间的耦合也会随着人员的入职离职变得越来越高。维护成本越来越高。并且拓展性也不强,如果遇到极高的并发,我们只能通过物理上增加机器来进行拓展。
现在我们使用微服务架构,就可以将每个功能模块提取成一个独立的项目进行开发,让这个项目只做跟这个功能有关的事。这样将他们进行隔离开发,不仅避免了不同功能之间的代码耦合,还容易管理维护,举个我们之前项目的一个查询模块需求的例子,要更改一个查询模块内的代码,但却连带着后面的支付,订单等模块都需要更改。代码耦合极强,但如果将查询,支付,订单拆分成3个独立的项目,那么这个问题就不存在了。
并且当项目周期很长,技术过时的时候,原来的单一项目如果想进行技术升级,几乎是不可能的。升级JDK,spring 版本等,都有可能造成一些不兼容的问题,但是微服务就不同了,他每个项目都是单独的,只对外暴露接口,这样即使项目周期很长,后续的需求也可以单独使用一个项目,进行技术升级试点。再慢慢扩散的其他的原来项目中。甚至对原来很老的项目进行重构,成本也不会比单一项目高。
首先我们需要一个注册发现中心,spring cloud使用的事eureka(eureka2.0好像是闭源了),用于微服务的注册与发现,还有心跳机制,当默认90s没有收到心跳,则认为微服务出现异常,及时将其剔除。还有诸如自我保护机制等。也还有像dubbo,也是用于服务发现与注册的。关于dubbo+zk的简单示例
其次由于微服务的配置会由于业务的增加,增加相当多的配置。所以我们需要一个配置中心,spring cloud config 提供的就是一个配置中心。他可以对我们所有微服务的配置进行统一管理。把所有配置文件集中于一个项目中,统一放在git管理,当配置文件发生改变时,配合spring cloud bus + MQ实现配置refresh的推送。可以使配置文件直接生效,算是一种热插拔的形式。只不过spring cloud config 并没有提供一个可视化的界面。还是以yml或者properties的形式进行管理。同样的配置中心还有很多,比如携程的开源框架apollo,并且apollo拥有自己的可视化界面。减少了运维的难度。
没有服务敢保证100%不宕机,我们生产过程中,承若的也只是9999可用性。所以是服务就有出错的风险,在微服务中很容易出现雪崩效应,即一个服务的不可用,导致这个服务的消费者变得不可用,从来这个消费者的消费者也会跟着不可用,这样就会因为一个点的问题造成大面积的服务瘫痪,所以进行熔断是非常有必要的。所以我们也要使用hystrix熔断器。
在微服务架构中,为了保证高可用性,一般服务都不只一个实例,高负载的应用可能更多,比如查询,支付等。都会以多节点的形式存在。多节点服务调用,我们需要使用负载均衡Ribbon。Ribbon会读取我们注册在eureka server中的每个微服务名及其名下的实例,然后按顺序调用。从而达到负载均衡的效果。
我们的每个微服务都有自己的IP,自己的端口号,都暴露给外部访问安全性得不到保障,并且难度较大。所以这里我们需要一个服务网关,在我们的底层的各个微服务和外部调用之间,设置一个转发,让外部统一访问这个服务网关,网关进行校验后,在调用内部的真实服务。这样不仅解决了外部访问安全性的问题,还统一了外部调用的方式。并且网关也会进行负载均衡。
但我们把模块进行拆分时,肯定是有高负载与低负载之分的。比如查询肯定比预定的多。各个微服务的性能是否够用,是否需要将高负载继续拆分成更小的微服务这都是需要通过服务上线后监控来进行的。并且日志报错量大与小,这些也都是需要监控。所以我们还需要监控, 比如ELK。
当我们使用微服务时,如果我们拆分成10个项目,每个项目3个节点,一次上5个项目的话那么上线,一次就需要部署15个包。这对于运维实施来说压力有点大。更别说之前网上看有人说他们项目拆分100个多项目,没有自动化部署是不实际的。所以使用微服务的话,jenkins自动化部署就非常必要了。他们帮我们自动打包,自动上传,自动重启。
其实微服务每一个都是一个项目,我们开发时,其实还是要从需求入手。如果只是一个小项目,量根本达不到这么多,那根本没必要使用微服务,单一服务其实也足够支撑了。但如果随着业务的增长,单一服务无法满足,那么就有必要进行微服务架构升级了。
目前想到的就这么多,spring cloud 的技术栈如此之多,很难将其所有内容都用起来并融会贯通,技术选型还是要和团队一起沟通,确保大家都能正常使用并开发。