笔者公司近年来基于SRE理念的运维模式决定一线运维们得有自己的运维场景提炼沉淀的运维支撑平台。笔者公司基本在全国各地均有自己的运维团队,这种情况下如果运维平台使用单体架构,会导致在单体架构下跨地域,跨开发小组协调困难。因为业务团队(运维团队)分布全国各地并基于本地的实际需要,在一些通用场景的基础上提出大量本地自己的运维场景实现需求,因为是全国性的SRE团队,内部对应配备多个场景开发小组,基于单体架构会给各开发小组之间的协调和沟通带来昂贵成本。所以,基于实际情况及业务场景需要,我们在相关产品选型初期就确定微服务架构,笔者今天就来讲讲微服务的相关入门知识。
●什么是微服务●
微服务一个相对较小且独立的功能单元,是用户可以感知的最小功能集,如一个网站有订单管理、用户管理、商品管理等模块,我们就可以把其中的订单管理、用户管理做成微服务。
●微服务架构●
微服务架构风格是一种使用一套小服务来开发单个应用的方式突进,每个服务运行在自己的进程中,并且使用轻量级通信如HTTPAPI,这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署,这些服务可以使用不同的编程语言,以及不同的数据储存技术等。
●为什么使用微服务●
项目开始阶段,运维场景功能并不是很齐全、体量小,单体架构可以满足业务需要。但伴随着业务能力拓展、自动化服务越来越集中,尤其是笔者公司希望给地场景能像货币一样流通,单体架构会带来一些问题:
复杂性逐渐变高
单体架构系统本身过于庞大和复杂,以至于任何一个开发者都很难以理解它的全部。这种极度的复杂度会形成恶性循环,由于代码难以理解,因此开发人员更改更容易出错,每一次更改系统更复杂、更难懂。
技术债务逐渐上升
随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且越积越多。“不坏不修”,这在软件开发中非常常见,在单体应用中,这种思想更严重。已使用的系统设计或代码难以被修改,因为应用程序中的其他模块可能会以意料之外的方式使用它。
部署速度逐渐变慢
随着代码的增多,构建和部署的时间也会增加。而在单体应用中,每次功能的变更或缺陷的修复都会导致重新部署整个应用,而且全量部署的方式耗时长、影响范围大、风险高。
阻碍技术创新
单体应用往往使用统一的技术平台或方案解决所有的问题,团队中的每个成员必须使用相同的开发语言和框架,要想引入新框架或新技术平台会非常困难。例如,一个使用Struts2构建的、有百万行代码的单体应用,如果想要换用SpringMVC,毫无疑问切换的成本是非常高的。
无法按需伸缩
单体应用只能作为一个整体进行扩展,无法根据业务模块的需要进行伸缩。例如,应用中有的模块是计算密集型的,它需要强劲的CPU;有的模块则是IO密集型的,需要更大的内存。由于这些模块部署在一起,不得不在硬件的选择上做出妥协。
综上,随着业务需求的发展,功能的不断增加,单体架构很难满足互联网时代快速变化的需要。
●使用微服务的优点与缺点●
优点如下:
易于开发和维护
微服务易于被一个开发人员理解,修改和维护,实现了模块化的解决方案。
独立部署启动快
微服务架构模式是每个微服务独立的部署,开发者不再需要协调其它服务部署对本服务的影响,这种改变可以加快部署速度。
技术栈不受限
这种架构使得每个微服务都可以有专门开发团队来开发,开发者可以自由选择开发技术,提供API服务。这种自由意味着开发者不需要被迫使用某项目开始时采用的过时技术,他们可以选择现在的技术。甚至于,因为微服务都是相对简单,即使用现在技术重写以前代码也不是很困难的事情。
按需伸缩
微服务架构模式使得每个微服务独立扩展,你可以根据每个微服务的规模来部署满足需求的规模。甚至于,你可以使用更适合于微服务资源需求的硬件。比如,你可以把依赖CPU计算能力的指标管理微服务部署在高配置的多核CPU实例上,把视频管理模块部署在高内存、I/O读写能力强的实例上。
缺点如下:
运维要求高
对于单体架构来讲,我们只需要维护好这一个项目就可以了,但是对于微服务架构来讲,由于项目是由多个微服务构成的,每个模块出现问题都会造成整个项目运行出现异常,想要知道是哪个模块造成的问题往往是不容易的,因为我们无法一步一步通过debug的方式来跟踪,这就对运维人员提出了很高的要求。
分布式的复杂性
对于单体架构来讲,我们可以不使用分布式,但是对于微服务架构来说,分布式几乎是必会用的技术,由于分布式本身的复杂性,导致微服务架构也变得复杂起来。
接口调整成本高
比如,用户微服务是要被订单微服务和电影微服务所调用的,一旦用户微服务的接口发生大的变动,那么所有依赖它的微服务都要做相应的调整,由于微服务可能非常多,那么调整接口所造成的成本将会明显提高。
重复造轮子
对于单体架构来讲,如果某段业务被多个模块所共同使用,我们便可以抽象成一个工具类,被所有模块直接调用,但是微服务却无法这样做,因为这个微服务的工具类是不能被其它微服务所直接调用的,从而我们便不得不在每个微服务上都建这么一个工具类,从而导致代码的重复。
●微服务架构SpringCloud●
服务发现Eureka介绍
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能,类似于Dubbo的注册中心Zookeeper。实现原理如下:
EureKa采用C-S的设计架构,即包括了EurekaServer(服务端),EureKaclient(客户端)。
EureKaServer提供服务注册,各个节点启动后,在EureKaserver中进行注册
EureKaClient是一个Java客户端,用于和服务端进行交互,同时客户端也是一个内置的默认使用轮询负载均衡算法的负载均衡器。在应用启动后,会向EurekaServer发送心跳(默认30秒)。如果EurekaServer在多个心跳周期内没有接受到某个节点的心跳,EureKaServer将会从服务注册表中将这个服务移出(默认90秒)。
在项目中业务量不大情况下,例如微服务消费者A可以通过url地址调用微服务生产者B的接口服务,这种直接指定url调用有如下隐患:1、微服务B的IP和端口变了,那微服务A通过之前的url调用微服务B就会报错;2、因业务量大增,微服务B需要扩容做成集群,如果微服务A还是通过指定url调用微服务B就无法做到集群的负载均衡以及高可用。
综上所述,我们用Eureka来解决这一难题,各微服务启动时都注册服务名在Eureka中,例如微服务消费者A在Eureka中注册服务名为’consumer,微服务生产者B在Eureka中注册服务名为’producer’,那微服务消费者A就可以通过指定要调用的服务名’producer’通过Eureka的负载均衡返回实际微服务生产者B的url地址,这样就解决了以上问题。
微服务之间通信Feign
微服务之间调用接口通过Feign,它是声明式的Rest客户端,基于接口的注解方式,它跟Eureka配套使用,Eureka中自带了Ribbon实现了负载均衡。例如代码中微服务消费者A通过Feign要调用微服务生产者B的接口服务,只需在微服务A的Feign注解中指定微服务者生产B在Eureka中的注册服务名即可,如下:
断路器Hystrix
在微服务架构中,根据业务来拆分成一个个的微服务,微服务与微服务之间可以相互调用,为了保证其高可用,单个微服务通常会集群部署。由于网络原因或者自身的原因,微服务并不能保证100%可用,如果单个微服务出现问题,调用这个微服务就会出现线程阻塞,此时若有大量的请求涌入该微服务实例,会导致该实例的线程资源会被消耗完毕,导致服务瘫痪。因微服务与微服务之间的依赖性,所以故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是微服务故障的“雪崩”效应。
综上情况,我们使用到了断路器Hystrix,当对特定的微服务的调用的不可用达到一个阀值(Hystric默认是5秒20次)断路器将会被打开,下次请求过来微服务会直接通过fallback返回一个固定值快速失败响应,不会走内部逻辑占用资源。
断路器还能自动回复,在熔断机制的异常情况逻辑中,当熔断器打开的时候,会自动的启动自动恢复休眠窗(一个计时器,默认10秒),在这个休眠期内,所有请求都会快速失败。
但是当休眠期到期的时候,此时熔断器会进入半开状态,让下一次请求继续调用内部资源,而不是快速失败。如果这时候调用成功,熔断开关置为关闭状态。
反之,熔断开关继续打开状态,再次进入快速失败的状态,并继续进行休眠,等待下一次尝试恢复。断路器提供了看板监控如下:
服务网关zuul
所有从设备或网站来的请求都会经过Zuul到达后端微服务应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。Zuul底层利用各种filter实现如下功能:
1、认证和安全:识别每个需要认证的资源,拒绝不符合要求的请求。
2、性能监测:在服务边界追踪并统计数据,提供精确的生产视图。
3、动态路由:根据需要将请求动态路由到后端集群。
4、压力测试:逐渐增加对集群的流量以了解其性能。
5、负载均衡:预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。
6、静态资源处理:直接在边界返回某些响应。
在项目中,一般用到zuul最多的是动态路由、负载均衡,它搭配Eureka使用,当用户请求过来时,先实现动态路由映射,隐藏真实微服务的IP,在从Eureka拿到实际调用微服务的地址。没用zuul是以下场景调用微服务,需要直接配置微服务url接口地址:
配置了服务网关zuul后,不管微服务url接口地址是否改变,不影响外部调用:
配置中心SpringCloud Config
我们知道,每个独立的微服务都有配置文件,一个项目至少有几个、甚至十几个微服务以上,如果要修改微服务的配置文件参数,需要登陆到每个微服务项目的resources目录下进行修改,不方便维护。尤其是更新微服务项目配置后需要重启,而重启项目的代价还是很高的。而配置中心SpringCloudConfig提供了公有云远程Git仓库、本地Git仓库,可以把每个微服务的配置文件统一集中管理,当配置文件内容修改时,可以同步到每个微服务的内存中,不需要重启,实现了高可用,非常方便。
我们可以指定一个微服务为Configserver,实时同步远程Git仓库、本地Git仓库的所有微服务配置文件,当配置文件参数有改动时程序会自动同步到上图中的微服务A、B中,微服务A、B启动时也会主动从微服务Configserver同步一次配置文件参数。
以上就是笔者对Spring Cloud在项目中使用原因说明及架构讲解,本次入门介绍分享结束,我们下次再见。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/130216.html
摘要:可简单地认为它是的扩展,负载均衡自然成为不可或缺的特性。是基于开发的服务代理组件,在使用场景中,它与和整合,打造具备服务动态更新和负载均衡能力的服务网关。类似的特性在项目也有体现,它是另一种高性能代理的方案,提供服务发现健康和负载均衡。 摘要: Cloud Native 应用架构随着云技术的发展受到业界特别重视和关注,尤其是 CNCF(Cloud Native Computing Fo...
摘要:作为面试官,我是如何甄别应聘者的包装程度语言和等其他语言的对比分析和主从复制的原理详解和持久化的原理是什么面试中经常被问到的持久化与恢复实现故障恢复自动化详解哨兵技术查漏补缺最易错过的技术要点大扫盲意外宕机不难解决,但你真的懂数据恢复吗每秒 作为面试官,我是如何甄别应聘者的包装程度Go语言和Java、python等其他语言的对比分析 Redis和MySQL Redis:主从复制的原理详...
摘要:作为面试官,我是如何甄别应聘者的包装程度语言和等其他语言的对比分析和主从复制的原理详解和持久化的原理是什么面试中经常被问到的持久化与恢复实现故障恢复自动化详解哨兵技术查漏补缺最易错过的技术要点大扫盲意外宕机不难解决,但你真的懂数据恢复吗每秒 作为面试官,我是如何甄别应聘者的包装程度Go语言和Java、python等其他语言的对比分析 Redis和MySQL Redis:主从复制的原理详...
摘要:目前首个测试版是针对环境的,社区宣称在未来几个月内会为虚拟机和等其他环境增加支持。查看下在上的更新时间,截止年月日所有项目均更新于小时内。核心项目最近更新于一个月乃至数月前。所有项目均更新于分钟内。目前对比来看,则显得稍逊下来。 showImg(https://segmentfault.com/img/remote/1460000010953149); 在 Kubernetes 容器云...
摘要:可简单地认为它是的扩展,负载均衡自然成为不可或缺的特性。类似的特性在项目也有体现,它是另一种高性能代理的方案,提供服务发现健康和负载均衡。 Dubbo Cloud Native 实践与思考 分享简介 Cloud Native 应用架构随着云技术的发展受到业界特别重视和关注,尤其是 CNCF(Cloud Native Computing Foundation)项目蓬勃发展之际。Dubbo...
阅读 1247·2023-01-11 13:20
阅读 1555·2023-01-11 13:20
阅读 1008·2023-01-11 13:20
阅读 1676·2023-01-11 13:20
阅读 3968·2023-01-11 13:20
阅读 2510·2023-01-11 13:20
阅读 1305·2023-01-11 13:20
阅读 3474·2023-01-11 13:20